Răsfoiți Sursa

* GetKeyName

Michaël Van Canneyt 6 luni în urmă
părinte
comite
c9fe26ef22
1 a modificat fișierele cu 123 adăugiri și 15 ștergeri
  1. 123 15
      src/base/fresnel.keys.pas

+ 123 - 15
src/base/fresnel.keys.pas

@@ -337,7 +337,27 @@ Type
     BrowserStop = 'BrowserStop';
   end;
 
+  TKeyCodeName = record
+    Code : Integer;
+    Name : string;
+  end;
+  TKeyCodeNameArray = Array of TKeyCodeName;
+
+  TEnumKeysCallback = Procedure(aCode : Integer; aName : string) of object;
+
+  TSpecialKeyEnumerator = class(TObject)
+  Protected
+    Procedure EnumKey(aCode : Integer; aName : string); virtual; abstract;
+  end;
+
+  { TKeyCodes }
+
   TKeyCodes = Record
+  Private
+    class var FSortedKeys : TKeyCodeNameArray;
+    class function indexOf(aKeyCode : Integer) : Integer; static;
+    class function GetKeyName(aKeyCode : Integer) : String; static;
+  Public
   Const
     // Specials...
     SpecialKeysOffset          = -1024;
@@ -430,10 +450,11 @@ Type
     Hiranga                    = SpecialKeysOffset - 0085;
     HirangaKatakana            = SpecialKeysOffset - 0086;
     KanaMode                   = SpecialKeysOffset - 0087;
+    KanjiMode                  = SpecialKeysOffset - 0340; // Forgotten
     Katakana                   = SpecialKeysOffset - 0088;
     Romaji                     = SpecialKeysOffset - 0089;
     Zenkaku                    = SpecialKeysOffset - 0090;
-    ZenkakuHanaku              = SpecialKeysOffset - 0091;
+    ZenkakuHankaku             = SpecialKeysOffset - 0091;
     F1                         = SpecialKeysOffset - 0092;
     F2                         = SpecialKeysOffset - 0093;
     F3                         = SpecialKeysOffset - 0094;
@@ -703,18 +724,8 @@ Type
     F22                        = SpecialKeysOffset - 0337;
     F23                        = SpecialKeysOffset - 0338;
     F24                        = SpecialKeysOffset - 0339;
-  end;
-  TKeyCodeName = record
-    Code : Integer;
-    Name : string;
-  end;
-  TKeyCodeNameArray = Array of TKeyCodeName;
-
-  TEnumKeysCallback = Procedure(aCode : Integer; aName : string) of object;
-
-  TSpecialKeyEnumerator = class(TObject)
-  Protected
-    Procedure EnumKey(aCode : Integer; aName : string); virtual; abstract;
+    // 0340 is kanjimode (see above)
+    class Property Names[aKey : Integer] : string read GetKeyName;
   end;
 
   { TCountSpecialKeys }
@@ -749,9 +760,12 @@ Type
 procedure EnumSpecialKeys(aCallback : TEnumKeysCallback);
 function GetSpecialKeyCount : Integer;
 function GetSpecialKeyArray : TKeyCodeNameArray;
+function GetSpecialKeyName(aCode : Integer) : String;
 
 implementation
 
+uses UTF8Utils;
+
 function GetSpecialKeyCount : Integer;
 
 begin
@@ -764,6 +778,12 @@ begin
   Result:=TSpecialKeysArrayCreator.GetArray;
 end;
 
+function GetSpecialKeyName(aCode : Integer) : String;
+
+begin
+  Result:=TKeyCodes.Names[aCode];
+end;
+
 procedure EnumSpecialKeys(aCallback : TEnumKeysCallback);
 
 begin
@@ -858,7 +878,7 @@ begin
   aCallBack(TKeyCodes.Katakana ,TKeyNames.Katakana );
   aCallBack(TKeyCodes.Romaji ,TKeyNames.Romaji );
   aCallBack(TKeyCodes.Zenkaku ,TKeyNames.Zenkaku );
-  aCallBack(TKeyCodes.ZenkakuHanaku ,TKeyNames.ZenkakuHanaku );
+  aCallBack(TKeyCodes.ZenkakuHankaku ,TKeyNames.ZenkakuHanaku );
   aCallBack(TKeyCodes.F1 ,TKeyNames.F1 );
   aCallBack(TKeyCodes.F2 ,TKeyNames.F2 );
   aCallBack(TKeyCodes.F3 ,TKeyNames.F3 );
@@ -1085,6 +1105,94 @@ begin
   aCallBack(TKeyCodes.BrowserStop ,TKeyNames.BrowserStop );
 end;
 
+{ TKeyCodes }
+
+// Once we have sortbase, this can disappear.
+type
+  TIntegerArray = array of Integer;
+
+procedure Swap(var a, b: TKeyCodeName); inline;
+var
+  temp: TKeyCodeName;
+begin
+  temp := a;
+  a := b;
+  b := temp;
+end;
+
+function Partition(var arr: TKeyCodeNameArray; low, high: Integer): Integer;
+var
+  pivot : TKeyCodeName;
+  i, j: Integer;
+begin
+  pivot := arr[high];
+  i := low - 1;
+
+  for j := low to high - 1 do
+  begin
+    if arr[j].Code <= pivot.code then
+    begin
+      Inc(i);
+      Swap(arr[i], arr[j]);
+    end;
+  end;
+
+  Swap(arr[i + 1], arr[high]);
+  Result := i + 1;
+end;
+
+procedure QuickSort(var arr: TKeyCodeNameArray; low, high: Integer);
+var
+  pi: Integer;
+begin
+  if low < high then
+  begin
+    pi := Partition(arr, low, high);
+    QuickSort(arr, low, pi - 1);
+    QuickSort(arr, pi + 1, high);
+  end;
+end;
+
+class function TKeyCodes.indexOf(aKeyCode: Integer): Integer;
+
+var
+  left, right, mid: Integer;
+begin
+  left:=0;
+  right:=Length(FSortedKeys)-1;
+  while (left<=right) do
+    begin
+    mid:=left+(right-left) div 2;
+    if (FSortedKeys[mid].Code=aKeyCode) then
+      System.Exit(mid); // Target found, return index
+    if FSortedKeys[mid].code < aKeyCode then
+      left := mid + 1
+    else
+      right := mid - 1;
+    end;
+    Result := -1; // Target not found
+end;
+
+class function TKeyCodes.GetKeyName(aKeyCode: Integer): String;
+var
+  Idx : integer;
+begin
+  if aKeyCode>0 then
+    Result:=UTF8Utils.UnicodeToUTF8(aKeyCode)
+  else
+    begin
+    Result:='';
+    if FSortedKeys=Nil then
+      begin
+      FSortedKeys:=GetSpecialKeyArray;
+      QuickSort(FSortedKeys,0,Length(FSortedKeys));
+      end;
+    Idx:=IndexOf(aKeyCode);
+    if Idx<>-1 then
+      Result:=FSortedKeys[Idx].Name
+    end;
+end;
+
 { TCountSpecialKeys }
 
 procedure TCountSpecialKeys.EnumKey(aCode: Integer; aName: string);
@@ -1119,8 +1227,8 @@ begin
   if _keyarray=Nil then
     With TSpecialKeysArrayCreator.Create do
       try
-        EnumSpecialKeys(@EnumKey);
         SetLength(FArray,GetSpecialKeyCount);
+        EnumSpecialKeys(@EnumKey);
         _KeyArray:=FArray;
       finally
         Free;