DEADSOFTWARE

Holmes: UI cosmetix
[d2df-sdl.git] / src / game / g_holmes.pas
index cf6a2bdbca084623e91ff9c2a06968f4746a6604..0cac2c7aa30aa5f0b5834b11d49d0a24b37d8001 100644 (file)
@@ -24,14 +24,14 @@ uses
   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, g_gfx,
   xprofiler,
-  sdlcarcass, glgfx, gh_ui;
+  sdlcarcass, glgfx, gh_ui_common, gh_ui;
 
 
 procedure g_Holmes_Draw ();
 procedure g_Holmes_DrawUI ();
 
-function g_Holmes_MouseEvent (var ev: THMouseEvent): Boolean; // returns `true` if event was eaten
-function g_Holmes_KeyEvent (var ev: THKeyEvent): Boolean; // returns `true` if event was eaten
+procedure g_Holmes_MouseEvent (var ev: THMouseEvent);
+procedure g_Holmes_KeyEvent (var ev: THKeyEvent);
 
 // hooks for player
 procedure g_Holmes_plrViewPos (viewPortX, viewPortY: Integer);
@@ -108,8 +108,9 @@ procedure createLayersWindow (); forward;
 procedure createOutlinesWindow (); forward;
 
 
-procedure toggleLayersWindowCB (me: TUIControl; checked: Integer);
+procedure toggleLayersWindowCB (me: TUIControl);
 begin
+  showLayersWindow := not showLayersWindow;
   if showLayersWindow then
   begin
     if (winLayers = nil) then createLayersWindow();
@@ -121,9 +122,9 @@ begin
   end;
 end;
 
-
-procedure toggleOutlineWindowCB (me: TUIControl; checked: Integer);
+procedure toggleOutlineWindowCB (me: TUIControl);
 begin
+  showOutlineWindow := not showOutlineWindow;
   if showOutlineWindow then
   begin
     if (winOutlines = nil) then createOutlinesWindow();
@@ -137,17 +138,102 @@ end;
 
 
 procedure createHelpWindow ();
+  procedure addHelpEmptyLine ();
+  var
+    stx: TUIStaticText;
+  begin
+    stx := TUIStaticText.Create();
+    stx.flExpand := true;
+    stx.halign := 0; // center
+    stx.text := '';
+    stx.header := false;
+    stx.line := false;
+    winHelp.appendChild(stx);
+  end;
+
+  procedure addHelpCaptionLine (const txt: AnsiString);
+  var
+    stx: TUIStaticText;
+  begin
+    stx := TUIStaticText.Create();
+    stx.flExpand := true;
+    stx.halign := 0; // center
+    stx.text := txt;
+    stx.header := true;
+    stx.line := true;
+    winHelp.appendChild(stx);
+  end;
+
+  procedure addHelpCaption (const txt: AnsiString);
+  var
+    stx: TUIStaticText;
+  begin
+    stx := TUIStaticText.Create();
+    stx.flExpand := true;
+    stx.halign := 0; // center
+    stx.text := txt;
+    stx.header := true;
+    stx.line := false;
+    winHelp.appendChild(stx);
+  end;
+
+  procedure addHelpKeyMouse (const key, txt, grp: AnsiString);
+  var
+    box: TUIHBox;
+    span: TUISpan;
+    stx: TUIStaticText;
+  begin
+    box := TUIHBox.Create();
+    box.flExpand := true;
+      // key
+      stx := TUIStaticText.Create();
+      stx.flExpand := true;
+      stx.halign := 1; // right
+      stx.valign := 0; // center
+      stx.text := key;
+      stx.header := true;
+      stx.line := false;
+      stx.flHGroup := grp;
+      box.appendChild(stx);
+      // span
+      span := TUISpan.Create();
+      span.flDefaultSize := TLaySize.Create(4, 1);
+      span.flExpand := true;
+      box.appendChild(span);
+      // text
+      stx := TUIStaticText.Create();
+      stx.flExpand := true;
+      stx.halign := -1; // left
+      stx.valign := 0; // center
+      stx.text := txt;
+      stx.header := false;
+      stx.line := false;
+      box.appendChild(stx);
+    winHelp.appendChild(box);
+  end;
+
+  procedure addHelpKey (const key, txt: AnsiString); begin addHelpKeyMouse(key, txt, 'help-keys'); end;
+  procedure addHelpMouse (const key, txt: AnsiString); begin addHelpKeyMouse(key, txt, 'help-mouse'); end;
+
 var
-  llb: TUISimpleText;
   slist: array of AnsiString = nil;
   cmd: PHolmesCommand;
   bind: THolmesBinding;
-  f, maxkeylen: Integer;
+  f: Integer;
+  {
+  llb: TUISimpleText;
+  maxkeylen: Integer;
   s: AnsiString;
+  }
 begin
+  winHelp := TUITopWindow.Create('Holmes Help');
+  winHelp.escClose := true;
+  winHelp.flHoriz := false;
+
+  // keyboard
   for cmd in cmdlist do cmd.helpmark := false;
 
-  maxkeylen := 0;
+  //maxkeylen := 0;
   for bind in keybinds do
   begin
     if (Length(bind.key) = 0) then continue;
@@ -156,7 +242,7 @@ begin
       if (Length(cmd.help) > 0) then
       begin
         cmd.helpmark := true;
-        if (maxkeylen < Length(bind.key)) then maxkeylen := Length(bind.key);
+        //if (maxkeylen < Length(bind.key)) then maxkeylen := Length(bind.key);
       end;
     end;
   end;
@@ -164,7 +250,7 @@ begin
   for cmd in cmdlist do
   begin
     if not cmd.helpmark then continue;
-    if (Length(cmd.help) = 0) then continue;
+    if (Length(cmd.help) = 0) then begin cmd.helpmark := false; continue; end;
     f := 0;
     while (f < Length(slist)) and (CompareText(slist[f], cmd.section) <> 0) do Inc(f);
     if (f = Length(slist)) then
@@ -174,11 +260,14 @@ begin
     end;
   end;
 
-  llb := TUISimpleText.Create(0, 0);
+  addHelpCaptionLine('KEYBOARD');
+  //llb := TUISimpleText.Create(0, 0);
   for f := 0 to High(slist) do
   begin
-    if (f > 0) then llb.appendItem('');
-    llb.appendItem(slist[f], true, true);
+    //if (f > 0) then llb.appendItem('');
+    if (f > 0) then addHelpEmptyLine();
+    //llb.appendItem(slist[f], true, true);
+    addHelpCaption(slist[f]);
     for cmd in cmdlist do
     begin
       if not cmd.helpmark then continue;
@@ -188,16 +277,20 @@ begin
         if (Length(bind.key) = 0) then continue;
         if (cmd.name = bind.cmdName) then
         begin
-          s := bind.key;
-          while (Length(s) < maxkeylen) do s += ' ';
-          s := '  '+s+' -- '+cmd.help;
-          llb.appendItem(s);
+          //s := bind.key;
+          //while (Length(s) < maxkeylen) do s += ' ';
+          //s := '  '+s+' -- '+cmd.help;
+          //llb.appendItem(s);
+          addHelpMouse(bind.key, cmd.help);
         end;
       end;
     end;
   end;
 
-  maxkeylen := 0;
+  // mouse
+  for cmd in cmdlist do cmd.helpmark := false;
+
+  //maxkeylen := 0;
   for bind in msbinds do
   begin
     if (Length(bind.key) = 0) then continue;
@@ -206,13 +299,15 @@ begin
       if (Length(cmd.help) > 0) then
       begin
         cmd.helpmark := true;
-        if (maxkeylen < Length(bind.key)) then maxkeylen := Length(bind.key);
+        //if (maxkeylen < Length(bind.key)) then maxkeylen := Length(bind.key);
       end;
     end;
   end;
 
-  llb.appendItem('');
-  llb.appendItem('mouse', true, true);
+  //llb.appendItem('');
+  //llb.appendItem('mouse', true, true);
+  if (f > 0) then addHelpEmptyLine();
+  addHelpCaptionLine('MOUSE');
   for bind in msbinds do
   begin
     if (Length(bind.key) = 0) then continue;
@@ -220,84 +315,147 @@ begin
     begin
       if (Length(cmd.help) > 0) then
       begin
-        s := bind.key;
-        while (Length(s) < maxkeylen) do s += ' ';
-        s := '  '+s+' -- '+cmd.help;
-        llb.appendItem(s);
+        //s := bind.key;
+        //while (Length(s) < maxkeylen) do s += ' ';
+        //s := '  '+s+' -- '+cmd.help;
+        //llb.appendItem(s);
+        addHelpKey(bind.key, cmd.help);
       end;
     end;
   end;
 
-  winHelp := TUITopWindow.Create('Holmes Help', 10, 10);
-  winHelp.escClose := true;
-  winHelp.appendChild(llb);
+  //winHelp.appendChild(llb);
+
+  winHelp.flMaxSize := TLaySize.Create(trunc(getScrWdt/gh_ui_scale), trunc(getScrHgt/gh_ui_scale));
+  uiLayoutCtl(winHelp);
   winHelp.centerInScreen();
 end;
 
 
-procedure winLayersClosed (me: TUIControl; dummy: Integer); begin showLayersWindow := false; end;
-procedure winOutlinesClosed (me: TUIControl; dummy: Integer); begin showOutlineWindow := false; end;
+procedure winLayersClosed (me: TUIControl); begin showLayersWindow := false; end;
+procedure winOutlinesClosed (me: TUIControl); begin showOutlineWindow := false; end;
+
+procedure addCheckBox (parent: TUIControl; const text: AnsiString; pvar: PBoolean);
+var
+  cb: TUICheckBox;
+begin
+  cb := TUICheckBox.Create();
+  cb.flExpand := true;
+  cb.setVar(pvar);
+  cb.text := text;
+  parent.appendChild(cb);
+end;
+
+procedure addButton (parent: TUIControl; const text: AnsiString; cb: TUIControl.TActionCB);
+var
+  but: TUIButton;
+begin
+  but := TUIButton.Create();
+  //but.flExpand := true;
+  but.actionCB := cb;
+  but.text := text;
+  parent.appendChild(but);
+end;
+
 
 procedure createLayersWindow ();
 var
-  llb: TUICBListBox;
+  box: TUIVBox;
 begin
-  llb := TUICBListBox.Create(0, 0);
-  llb.appendItem('background', @g_rlayer_back);
-  llb.appendItem('steps', @g_rlayer_step);
-  llb.appendItem('walls', @g_rlayer_wall);
-  llb.appendItem('doors', @g_rlayer_door);
-  llb.appendItem('acid1', @g_rlayer_acid1);
-  llb.appendItem('acid2', @g_rlayer_acid2);
-  llb.appendItem('water', @g_rlayer_water);
-  llb.appendItem('foreground', @g_rlayer_fore);
-  winLayers := TUITopWindow.Create('layers', 10, 10);
+  winLayers := TUITopWindow.Create('layers');
+  winLayers.x0 := 10;
+  winLayers.y0 := 10;
+  winLayers.flHoriz := false;
   winLayers.escClose := true;
-  winLayers.appendChild(llb);
   winLayers.closeCB := winLayersClosed;
+
+  box := TUIVBox.Create();
+    addCheckBox(box, '~background', @g_rlayer_back);
+    addCheckBox(box, '~steps', @g_rlayer_step);
+    addCheckBox(box, '~walls', @g_rlayer_wall);
+    addCheckBox(box, '~doors', @g_rlayer_door);
+    addCheckBox(box, 'acid~1', @g_rlayer_acid1);
+    addCheckBox(box, 'acid~2', @g_rlayer_acid2);
+    addCheckBox(box, 'wate~r', @g_rlayer_water);
+    addCheckBox(box, '~foreground', @g_rlayer_fore);
+  winLayers.appendChild(box);
+
+  winLayers.flMaxSize := TLaySize.Create(trunc(getScrWdt/gh_ui_scale), trunc(getScrHgt/gh_ui_scale));
+  uiLayoutCtl(winLayers);
 end;
 
 
 procedure createOutlinesWindow ();
 var
-  llb: TUICBListBox;
+  box: TUIVBox;
 begin
-  llb := TUICBListBox.Create(0, 0);
-  llb.appendItem('background', @g_ol_rlayer_back);
-  llb.appendItem('steps', @g_ol_rlayer_step);
-  llb.appendItem('walls', @g_ol_rlayer_wall);
-  llb.appendItem('doors', @g_ol_rlayer_door);
-  llb.appendItem('acid1', @g_ol_rlayer_acid1);
-  llb.appendItem('acid2', @g_ol_rlayer_acid2);
-  llb.appendItem('water', @g_ol_rlayer_water);
-  llb.appendItem('foreground', @g_ol_rlayer_fore);
-  llb.appendItem('OPTIONS', nil);
-  llb.appendItem('fill walls', @g_ol_fill_walls);
-  llb.appendItem('contours', @g_ol_nice);
-  winOutlines := TUITopWindow.Create('outlines', 100, 10);
+  winOutlines := TUITopWindow.Create('outlines');
+  winOutlines.x0 := 100;
+  winOutlines.y0 := 30;
+  winOutlines.flHoriz := false;
   winOutlines.escClose := true;
-  winOutlines.appendChild(llb);
   winOutlines.closeCB := winOutlinesClosed;
+
+  box := TUIVBox.Create();
+  box.hasFrame := true;
+  box.caption := 'layers';
+    addCheckBox(box, '~background', @g_ol_rlayer_back);
+    addCheckBox(box, '~steps', @g_ol_rlayer_step);
+    addCheckBox(box, '~walls', @g_ol_rlayer_wall);
+    addCheckBox(box, '~doors', @g_ol_rlayer_door);
+    addCheckBox(box, 'acid~1', @g_ol_rlayer_acid1);
+    addCheckBox(box, 'acid~2', @g_ol_rlayer_acid2);
+    addCheckBox(box, 'wate~r', @g_ol_rlayer_water);
+    addCheckBox(box, '~foreground', @g_ol_rlayer_fore);
+  winOutlines.appendChild(box);
+
+  box := TUIVBox.Create();
+  box.hasFrame := true;
+  box.caption := 'options';
+    addCheckBox(box, 'fi~ll walls', @g_ol_fill_walls);
+    addCheckBox(box, 'con~tours', @g_ol_nice);
+  winOutlines.appendChild(box);
+
+  winOutlines.flMaxSize := TLaySize.Create(trunc(getScrWdt/gh_ui_scale), trunc(getScrHgt/gh_ui_scale));
+  uiLayoutCtl(winOutlines);
 end;
 
 
 procedure createOptionsWindow ();
 var
-  llb: TUICBListBox;
+  box: TUIBox;
+  span: TUISpan;
 begin
-  llb := TUICBListBox.Create(0, 0);
-  llb.appendItem('map grid', @showGrid);
-  llb.appendItem('cursor position on map', @showMapCurPos);
-  llb.appendItem('monster info', @showMonsInfo);
-  llb.appendItem('monster LOS to player', @showMonsLOS2Plr);
-  llb.appendItem('monster cells (SLOW!)', @showAllMonsCells);
-  llb.appendItem('draw triggers (SLOW!)', @showTriggers);
-  llb.appendItem('WINDOWS', nil);
-  llb.appendItem('layers window', @showLayersWindow, toggleLayersWindowCB);
-  llb.appendItem('outline window', @showOutlineWindow, toggleOutlineWindowCB);
-  winOptions := TUITopWindow.Create('Holmes Options', 100, 100);
+  winOptions := TUITopWindow.Create('Holmes Options');
+  winOptions.flHoriz := false;
   winOptions.escClose := true;
-  winOptions.appendChild(llb);
+
+  box := TUIVBox.Create();
+  box.hasFrame := true;
+  box.caption := 'visual';
+    addCheckBox(box, 'map ~grid', @showGrid);
+    addCheckBox(box, 'cursor ~position on map', @showMapCurPos);
+    addCheckBox(box, '~monster info', @showMonsInfo);
+    addCheckBox(box, 'monster LO~S to player', @showMonsLOS2Plr);
+    addCheckBox(box, 'monster ~cells (SLOW!)', @showAllMonsCells);
+    addCheckBox(box, 'draw ~triggers (SLOW!)', @showTriggers);
+  winOptions.appendChild(box);
+
+  box := TUIHBox.Create();
+  box.hasFrame := true;
+  box.caption := 'windows';
+  box.captionAlign := 0;
+  box.flAlign := 0;
+    addButton(box, '~layers', toggleLayersWindowCB);
+    span := TUISpan.Create();
+      span.flExpand := true;
+      span.flDefaultSize := TLaySize.Create(4, 1);
+      box.appendChild(span);
+    addButton(box, '~outline', toggleOutlineWindowCB);
+  winOptions.appendChild(box);
+
+  winOptions.flMaxSize := TLaySize.Create(trunc(getScrWdt/gh_ui_scale), trunc(getScrHgt/gh_ui_scale));
+  uiLayoutCtl(winOptions);
   winOptions.centerInScreen();
 end;
 
@@ -305,13 +463,15 @@ end;
 procedure toggleLayersWindow (arg: Integer=-1);
 begin
   if (arg < 0) then showLayersWindow := not showLayersWindow else showLayersWindow := (arg > 0);
-  toggleLayersWindowCB(nil, 0);
+  showLayersWindow := not showLayersWindow; // hack for callback
+  toggleLayersWindowCB(nil);
 end;
 
 procedure toggleOutlineWindow (arg: Integer=-1);
 begin
   if (arg < 0) then showOutlineWindow := not showOutlineWindow else showOutlineWindow := (arg > 0);
-  toggleOutlineWindowCB(nil, 0);
+  showOutlineWindow := not showOutlineWindow; // hack for callback
+  toggleOutlineWindowCB(nil);
 end;
 
 procedure toggleHelpWindow (arg: Integer=-1);
@@ -1105,16 +1265,15 @@ end;
 
 
 // ////////////////////////////////////////////////////////////////////////// //
-function g_Holmes_MouseEvent (var ev: THMouseEvent): Boolean;
+procedure g_Holmes_MouseEvent (var ev: THMouseEvent);
 var
   he: THMouseEvent;
 begin
-  if g_Game_IsNet then begin result := false; exit; end;
-  if not g_holmes_enabled then begin result := false; exit; end;
+  if g_Game_IsNet then exit;
+  if not g_holmes_enabled then exit;
 
   holmesInitCommands();
   holmesInitBinds();
-  result := true;
   msX := ev.x;
   msY := ev.y;
   msB := ev.bstate;
@@ -1123,14 +1282,17 @@ begin
   he := ev;
   he.x := he.x;
   he.y := he.y;
-  if not uiMouseEvent(he) then plrDebugMouse(he);
+  uiMouseEvent(he);
+  if (not he.eaten) then plrDebugMouse(he);
+  ev.eat();
 end;
 
 
 // ////////////////////////////////////////////////////////////////////////// //
-function g_Holmes_KeyEvent (var ev: THKeyEvent): Boolean;
-{$IF DEFINED(D2F_DEBUG)}
+procedure g_Holmes_KeyEvent (var ev: THKeyEvent);
 var
+  doeat: Boolean = false;
+{$IF DEFINED(D2F_DEBUG)}
   pan: TPanel;
   ex, ey: Integer;
   dx, dy: Integer;
@@ -1141,22 +1303,24 @@ var
   end;
 
 begin
-  if g_Game_IsNet then begin result := false; exit; end;
-  if not g_holmes_enabled then begin result := false; exit; end;
+  if g_Game_IsNet then exit;
+  if not g_holmes_enabled then exit;
 
   holmesInitCommands();
   holmesInitBinds();
-  result := false;
+
   msB := ev.bstate;
   kbS := ev.kstate;
   case ev.scan of
     SDL_SCANCODE_LCTRL, SDL_SCANCODE_RCTRL,
     SDL_SCANCODE_LALT, SDL_SCANCODE_RALT,
     SDL_SCANCODE_LSHIFT, SDL_SCANCODE_RSHIFT:
-      result := true;
+      doeat := true;
   end;
-  if uiKeyEvent(ev) then begin result := true; exit; end;
-  if keybindExecute(ev) then begin result := true; exit; end;
+
+  uiKeyEvent(ev);
+  if (ev.eaten) then exit;
+  if keybindExecute(ev) then begin ev.eat(); exit; end;
   // press
   if (ev.press) then
   begin
@@ -1165,7 +1329,7 @@ begin
     if ((ev.scan = SDL_SCANCODE_UP) or (ev.scan = SDL_SCANCODE_DOWN) or (ev.scan = SDL_SCANCODE_LEFT) or (ev.scan = SDL_SCANCODE_RIGHT)) and
        ((ev.kstate and THKeyEvent.ModCtrl) <> 0) then
     begin
-      result := true;
+      ev.eat();
       dx := pmsCurMapX;
       dy := pmsCurMapY;
       case ev.scan of
@@ -1188,6 +1352,7 @@ begin
     end;
     {$ENDIF}
   end;
+  if (doeat) then ev.eat();
 end;
 
 
@@ -1495,15 +1660,16 @@ begin
 end;
 
 
-function onMouseEvent (var ev: THMouseEvent): Boolean;
+procedure onMouseEvent (var ev: THMouseEvent);
 begin
-  result := g_Holmes_MouseEvent(ev);
+  if not g_holmes_enabled then exit;
+  g_Holmes_MouseEvent(ev);
 end;
 
-function onKeyEvent (var ev: THKeyEvent): Boolean;
+procedure onKeyEvent (var ev: THKeyEvent);
 begin
-  if not g_holmes_enabled then begin result := false; exit; end;
-  result := g_Holmes_keyEvent(ev);
+  if not g_holmes_enabled then exit;
+  g_Holmes_KeyEvent(ev);
 end;