DEADSOFTWARE

Holmes UI: events now can be compared with strings
authorKetmar Dark <ketmar@ketmar.no-ip.org>
Mon, 28 Aug 2017 10:25:54 +0000 (13:25 +0300)
committerKetmar Dark <ketmar@ketmar.no-ip.org>
Mon, 28 Aug 2017 10:26:18 +0000 (13:26 +0300)
src/game/g_holmes.pas
src/game/g_holmes_ui.inc
src/game/g_window.pas

index 9b0055c839ff42b9f9229fbcdebc0913b0cd1efe..1222cd6c73da25c92ce45a6b16c643137e5bdea8 100644 (file)
@@ -19,7 +19,7 @@ unit g_holmes;
 interface
 
 uses
-  e_log,
+  e_log, e_input,
   g_textures, g_basic, e_graphics, g_phys, g_grid, g_player, g_monsters,
   g_window, g_map, g_triggers, g_items, g_game, g_panel, g_console,
   xprofiler;
@@ -68,8 +68,9 @@ type
     sym: Word; // SDLK_XXX
     bstate: Word; // button state
     kstate: Word; // keyboard state
-  end;
 
+  public
+  end;
 
 procedure g_Holmes_VidModeChanged ();
 procedure g_Holmes_WindowFocused ();
@@ -86,6 +87,13 @@ procedure g_Holmes_plrView (viewPortX, viewPortY, viewPortW, viewPortH: Integer)
 procedure g_Holmes_plrLaser (ax0, ay0, ax1, ay1: Integer);
 
 
+operator = (constref ev: THKeyEvent; const s: AnsiString): Boolean;
+operator = (const s: AnsiString; constref ev: THKeyEvent): Boolean;
+
+operator = (constref ev: THMouseEvent; const s: AnsiString): Boolean;
+operator = (const s: AnsiString; constref ev: THMouseEvent): Boolean;
+
+
 var
   g_holmes_enabled: Boolean = {$IF DEFINED(D2F_DEBUG)}true{$ELSE}false{$ENDIF};
 
@@ -116,6 +124,108 @@ var
 {$INCLUDE g_holmes_ui.inc}
 
 
+// ////////////////////////////////////////////////////////////////////////// //
+// any mods = 255: nothing was defined
+function parseModKeys (const s: AnsiString; out kmods: Byte; out mbuts: Byte): AnsiString;
+var
+  pos, epos: Integer;
+begin
+  kmods := 255;
+  mbuts := 255;
+  pos := 1;
+  while (pos <= Length(s)) and (s[pos] <= ' ') do Inc(pos);
+  while (pos < Length(s)) do
+  begin
+    if (Length(s)-pos >= 2) and (s[pos+1] = '-') then
+    begin
+      case s[pos] of
+        'C', 'c': begin if (kmods = 255) then kmods := 0; kmods := kmods or THKeyEvent.ModCtrl; Inc(pos, 2); continue; end;
+        'M', 'm': begin if (kmods = 255) then kmods := 0; kmods := kmods or THKeyEvent.ModAlt; Inc(pos, 2); continue; end;
+        'S', 's': begin if (kmods = 255) then kmods := 0; kmods := kmods or THKeyEvent.ModShift; Inc(pos, 2); continue; end;
+      end;
+      break;
+    end;
+    if (Length(s)-pos >= 4) and ((s[pos+1] = 'M') or (s[pos+1] = 'm')) and ((s[pos+2] = 'B') or (s[pos+1] = 'b')) and (s[pos+3] = '-') then
+    begin
+      case s[pos] of
+        'L', 'l': begin if (mbuts = 255) then mbuts := 0; mbuts := mbuts or THMouseEvent.Left; Inc(pos, 4); continue; end;
+        'R', 'r': begin if (mbuts = 255) then mbuts := 0; mbuts := mbuts or THMouseEvent.Right; Inc(pos, 4); continue; end;
+        'M', 'm': begin if (mbuts = 255) then mbuts := 0; mbuts := mbuts or THMouseEvent.Middle; Inc(pos, 4); continue; end;
+      end;
+      break;
+    end;
+    break;
+  end;
+  epos := Length(s)+1;
+  while (epos > pos) and (s[epos-1] <= ' ') do Dec(epos);
+  if (epos > pos) then result := Copy(s, pos, epos-pos) else result := '';
+end;
+
+
+operator = (constref ev: THKeyEvent; const s: AnsiString): Boolean;
+var
+  f: Integer;
+  kmods: Byte = 255;
+  mbuts: Byte = 255;
+  kname: AnsiString;
+begin
+  result := false;
+  kname := parseModKeys(s, kmods, mbuts);
+  if (kmods = 255) then kmods := 0;
+  if (ev.kstate <> kmods) then exit;
+  if (mbuts <> 255) and (ev.bstate <> mbuts) then exit;
+  for f := 1 to High(e_KeyNames) do
+  begin
+    if (CompareText(kname, e_KeyNames[f]) = 0) then
+    begin
+      result := (ev.scan = f);
+      exit;
+    end;
+  end;
+end;
+
+
+operator = (const s: AnsiString; constref ev: THKeyEvent): Boolean;
+begin
+  result := (ev = s);
+end;
+
+
+operator = (constref ev: THMouseEvent; const s: AnsiString): Boolean;
+var
+  kmods: Byte = 255;
+  mbuts: Byte = 255;
+  kname: AnsiString;
+  but: Integer = -1;
+begin
+  result := false;
+  kname := parseModKeys(s, kmods, mbuts);
+       if (CompareText(kname, 'LMB') = 0) then but := THMouseEvent.Left
+  else if (CompareText(kname, 'RMB') = 0) then but := THMouseEvent.Right
+  else if (CompareText(kname, 'MMB') = 0) then but := THMouseEvent.Middle
+  else if (CompareText(kname, 'None') = 0) then but := 0
+  else exit;
+
+  //conwritefln('s=[%s]; kname=[%s]; kmods=%s; mbuts=%s; but=%s', [s, kname, kmods, mbuts, but]);
+
+  if (mbuts = 255) then mbuts := 0;
+  if (kmods <> 255) and (ev.kstate <> kmods) then exit;
+
+       if (ev.kind = ev.Press) then mbuts := mbuts or but
+  else if (ev.kind = ev.Release) then mbuts := mbuts and (not but);
+
+  //conwritefln('  ev.bstate=%s; ev.but=%s; mbuts=%s', [ev.bstate, ev.but, mbuts]);
+
+  result := (ev.bstate = mbuts) and (ev.but = but);
+end;
+
+
+operator = (const s: AnsiString; constref ev: THMouseEvent): Boolean;
+begin
+  result := (ev = s);
+end;
+
+
 // ////////////////////////////////////////////////////////////////////////// //
 var
   g_ol_nice: Boolean = false;
@@ -818,7 +928,7 @@ begin
   if (ev.kind = THKeyEvent.Press) then
   begin
     // M-M: one monster think step
-    if (ev.scan = SDL_SCANCODE_M) and ((ev.kstate and THKeyEvent.ModAlt) <> 0) then
+    if (ev = 'M-M') then
     begin
       result := true;
       gmon_debug_think := false;
@@ -826,28 +936,28 @@ begin
       exit;
     end;
     // M-I: toggle monster info
-    if (ev.scan = SDL_SCANCODE_I) and ((ev.kstate and THKeyEvent.ModAlt) <> 0) then
+    if (ev = 'M-I') then
     begin
       result := true;
       showMonsInfo := not showMonsInfo;
       exit;
     end;
     // M-L: toggle monster LOS to player
-    if (ev.scan = SDL_SCANCODE_L) and ((ev.kstate and THKeyEvent.ModAlt) <> 0) then
+    if (ev = 'M-L') then
     begin
       result := true;
       showMonsLOS2Plr := not showMonsLOS2Plr;
       exit;
     end;
     // M-G: toggle "show all cells occupied by monsters"
-    if (ev.scan = SDL_SCANCODE_G) and ((ev.kstate and THKeyEvent.ModAlt) <> 0) then
+    if (ev = 'M-G') then
     begin
       result := true;
       showAllMonsCells := not showAllMonsCells;
       exit;
     end;
     // M-A: wake up monster
-    if (ev.scan = SDL_SCANCODE_A) and ((ev.kstate and THKeyEvent.ModAlt) <> 0) then
+    if (ev = 'M-A') then
     begin
       result := true;
       if (monMarkedUID <> -1) then
@@ -858,7 +968,7 @@ begin
       exit;
     end;
     // C-T: teleport player
-    if (ev.scan = SDL_SCANCODE_T) and ((ev.kstate and THKeyEvent.ModCtrl) <> 0) then
+    if (ev = 'C-T') then
     begin
       result := true;
       //e_WriteLog(Format('TELEPORT: (%d,%d)', [pmsCurMapX, pmsCurMapY]), MSG_NOTIFY);
@@ -870,21 +980,21 @@ begin
       exit;
     end;
     // C-P: show cursor position on the map
-    if (ev.scan = SDL_SCANCODE_P) and ((ev.kstate and THKeyEvent.ModCtrl) <> 0) then
+    if (ev = 'C-P') then
     begin
       result := true;
       showMapCurPos := not showMapCurPos;
       exit;
     end;
     // C-G: toggle grid
-    if (ev.scan = SDL_SCANCODE_G) and ((ev.kstate and THKeyEvent.ModCtrl) <> 0) then
+    if (ev = 'C-G') then
     begin
       result := true;
       showGrid := not showGrid;
       exit;
     end;
     // C-L: toggle layers window
-    if (ev.scan = SDL_SCANCODE_L) and ((ev.kstate and THKeyEvent.ModCtrl) <> 0) then
+    if (ev = 'C-L') then
     begin
       result := true;
       showLayersWindow := not showLayersWindow;
@@ -892,7 +1002,7 @@ begin
       exit;
     end;
     // C-O: toggle outlines window
-    if (ev.scan = SDL_SCANCODE_O) and ((ev.kstate and THKeyEvent.ModCtrl) <> 0) then
+    if (ev = 'C-O') then
     begin
       result := true;
       showOutlineWindow := not showOutlineWindow;
@@ -900,7 +1010,7 @@ begin
       exit;
     end;
     // F1: toggle options window
-    if (ev.scan = SDL_SCANCODE_F1) and (ev.kstate = 0) then
+    if (ev = 'F1') then
     begin
       result := true;
       if (winHelp = nil) then createHelpWindow();
@@ -908,7 +1018,7 @@ begin
       exit;
     end;
     // M-F1: toggle options window
-    if (ev.scan = SDL_SCANCODE_F1) and (ev.kstate = THKeyEvent.ModAlt) then
+    if (ev = 'M-F1') then
     begin
       result := true;
       if (winOptions = nil) then createOptionsWindow();
index 17cb20f644c3f86abae44cb1fc0b6f0a554b3e2a..f9cbf3c01bde5919959d87e6f94de173251b8be1 100644 (file)
@@ -785,7 +785,7 @@ begin
   if (topLevel.mFocused <> self) and isMyChild(topLevel.mFocused) and topLevel.mFocused.mEnabled then result := topLevel.mFocused.keyEvent(ev);
   if (mParent = nil) then
   begin
-    if (ev.kstate = THKeyEvent.ModShift) and (ev.scan = SDL_SCANCODE_TAB) then
+    if (ev.kind = ev.Press) and (ev = 'S-Tab') then
     begin
       result := true;
       if (ev.kind = ev.Press) then
@@ -799,7 +799,7 @@ begin
       end;
       exit;
     end;
-    if (ev.kstate = 0) and (ev.scan = SDL_SCANCODE_TAB) then
+    if (ev.kind = ev.Press) and (ev = 'Tab') then
     begin
       result := true;
       if (ev.kind = ev.Press) then
@@ -813,7 +813,7 @@ begin
       end;
       exit;
     end;
-    if mEscClose and (ev.kind = ev.Press) and (ev.kstate = 0) and (ev.scan = SDL_SCANCODE_ESCAPE) then
+    if mEscClose and (ev.kind = ev.Press) and (ev = 'Escape') then
     begin
       result := true;
       uiRemoveWindow(self);
@@ -906,7 +906,7 @@ function THTopWindow.keyEvent (var ev: THKeyEvent): Boolean;
 begin
   result := inherited keyEvent(ev);
   if not getFocused then exit;
-  if (ev.kstate = ev.ModAlt) and (ev.kind = ev.Press) and (ev.scan = SDL_SCANCODE_F3) then
+  if (ev.kind = ev.Press) and (ev = 'M-F3') then
   begin
     uiRemoveWindow(self);
     result := true;
@@ -1156,7 +1156,7 @@ begin
   if not result and toLocal(lx, ly) then
   begin
     result := true;
-    if (ev.kind = ev.Press) then
+    if (ev.kind = ev.Press) and (ev = 'lmb') then
     begin
       ly := ly div 8;
       if (ly >= 0) and (ly < Length(mItems)) then
@@ -1182,67 +1182,62 @@ begin
   result := inherited keyEvent(ev);
   if not getFocused then exit;
   //result := true;
-  if (ev.kstate = 0) and (ev.kind = ev.Press) then
+  if (ev.kind = ev.Press) then
   begin
-    case ev.scan of
-      SDL_SCANCODE_HOME,
-      SDL_SCANCODE_PAGEUP:
-        begin
-          result := true;
-          mCurIndex := 0;
-        end;
-      SDL_SCANCODE_END,
-      SDL_SCANCODE_PAGEDOWN:
-        begin
-          result := true;
-          mCurIndex := High(mItems);
-        end;
-      SDL_SCANCODE_UP:
-        begin
-          result := true;
-          if (Length(mItems) > 0) then
-          begin
-            if (mCurIndex < 0) then mCurIndex := Length(mItems);
-            while (mCurIndex > 0) do
-            begin
-              Dec(mCurIndex);
-              if (mItems[mCurIndex].varp <> nil) then break;
-            end;
-          end
-          else
-          begin
-            mCurIndex := -1;
-          end;
-        end;
-      SDL_SCANCODE_DOWN:
+    if (ev = 'Home') or (ev = 'PageUp') then
+    begin
+      result := true;
+      mCurIndex := 0;
+    end;
+    if (ev = 'End') or (ev = 'PageDown') then
+    begin
+      result := true;
+      mCurIndex := High(mItems);
+    end;
+    if (ev = 'Up') then
+    begin
+      result := true;
+      if (Length(mItems) > 0) then
+      begin
+        if (mCurIndex < 0) then mCurIndex := Length(mItems);
+        while (mCurIndex > 0) do
         begin
-          result := true;
-          if (Length(mItems) > 0) then
-          begin
-            if (mCurIndex < 0) then mCurIndex := -1;
-            while (mCurIndex < High(mItems)) do
-            begin
-              Inc(mCurIndex);
-              if (mItems[mCurIndex].varp <> nil) then break;
-            end;
-          end
-          else
-          begin
-            mCurIndex := -1;
-          end;
+          Dec(mCurIndex);
+          if (mItems[mCurIndex].varp <> nil) then break;
         end;
-      SDL_SCANCODE_SPACE,
-      SDL_SCANCODE_RETURN:
+      end
+      else
+      begin
+        mCurIndex := -1;
+      end;
+    end;
+    if (ev = 'Down') then
+    begin
+      result := true;
+      if (Length(mItems) > 0) then
+      begin
+        if (mCurIndex < 0) then mCurIndex := -1;
+        while (mCurIndex < High(mItems)) do
         begin
-          result := true;
-          if (mCurIndex >= 0) and (mCurIndex < Length(mItems)) and (mItems[mCurIndex].varp <> nil) then
-          begin
-            it := @mItems[mCurIndex];
-            it.varp^ := not it.varp^;
-            if assigned(it.actionCB) then it.actionCB(self, Integer(it.varp^));
-            if assigned(actionCB) then actionCB(self, mCurIndex);
-          end;
+          Inc(mCurIndex);
+          if (mItems[mCurIndex].varp <> nil) then break;
         end;
+      end
+      else
+      begin
+        mCurIndex := -1;
+      end;
+    end;
+    if (ev = 'Space') or (ev = 'Return') then
+    begin
+      result := true;
+      if (mCurIndex >= 0) and (mCurIndex < Length(mItems)) and (mItems[mCurIndex].varp <> nil) then
+      begin
+        it := @mItems[mCurIndex];
+        it.varp^ := not it.varp^;
+        if assigned(it.actionCB) then it.actionCB(self, Integer(it.varp^));
+        if assigned(actionCB) then actionCB(self, mCurIndex);
+      end;
     end;
   end;
 end;
index 17aa0479563d2239f9a3db5305b5b44a07fad5f9..226c4550c73fc5c7758048d1c94ab03da677c896 100644 (file)
@@ -475,7 +475,7 @@ begin
         if (msev.but <> 0) then
         begin
           // ev.button.clicks: Byte
-          curMsButState := curMsButState or msev.but;
+          if (ev.type_ = SDL_MOUSEBUTTONDOWN) then curMsButState := curMsButState or msev.but else curMsButState := curMsButState and (not msev.but);
           msev.bstate := curMsButState;
           msev.kstate := curKbState;
           if (g_holmes_enabled) then g_Holmes_mouseEvent(msev);