OpenClonk
C4GuiMenu.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
5  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
6  *
7  * Distributed under the terms of the ISC license; see accompanying file
8  * "COPYING" for details.
9  *
10  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11  * See accompanying file "TRADEMARK" for details.
12  *
13  * To redistribute this file separately, substitute the full license texts
14  * for the above references.
15  */
16 // generic user interface
17 // context menu
18 
19 #include "C4Include.h"
20 #include "gui/C4Gui.h"
21 
22 #include "graphics/C4Draw.h"
23 #include "graphics/C4FacetEx.h"
25 #include "gui/C4MouseControl.h"
26 
27 namespace C4GUI
28 {
29 
30  int32_t ContextMenu::iGlobalMenuIndex = 0;
31 
32 
33 // ----------------------------------------------------
34 // ContextMenu::Entry
35 
37  {
38  // icon
39  if (icoIcon > Ico_None)
40  {
41  // get icon counts
42  int32_t iXMax, iYMax;
44  if (!iXMax)
45  iXMax = 6;
46  // load icon
47  const C4Facet &rfctIcon = ::GraphicsResource.fctIcons.GetPhase(icoIcon % iXMax, icoIcon / iXMax);
48  rfctIcon.DrawX(cgo.Surface, rcBounds.x + cgo.TargetX, rcBounds.y + cgo.TargetY, rcBounds.Hgt, rcBounds.Hgt);
49  }
50  // print out label
51  if (!!sText)
53  // submenu arrow
54  if (pSubmenuHandler)
55  {
57  rSubFct.Draw(cgo.Surface, cgo.TargetX+rcBounds.x+rcBounds.Wdt - rSubFct.Wdt, cgo.TargetY+rcBounds.y+(rcBounds.Hgt - rSubFct.Hgt)/2);
58  }
59  }
60 
61  ContextMenu::Entry::Entry(const char *szText, Icons icoIcon, MenuHandler *pMenuHandler, ContextHandler *pSubmenuHandler)
62  : Element(), cHotkey(0), icoIcon(icoIcon), pMenuHandler(pMenuHandler), pSubmenuHandler(pSubmenuHandler)
63  {
64  // set text with hotkey
65  if (szText)
66  {
67  sText.Copy(szText);
69  // adjust size
71  }
72  else
73  {
74  rcBounds.Wdt = 40;
76  }
77  // regard icon
78  rcBounds.Wdt += GetIconIndent();
79  // submenu arrow
81  }
82 
83 // ----------------------------------------------------
84 // ContextMenu
85 
87  {
88  iMenuIndex = ++iGlobalMenuIndex;
89  // set min size
90  rcBounds.Wdt=40; rcBounds.Hgt=7;
91  // key bindings
93  Keys.emplace_back(K_UP);
95  {
96  ControllerKeys::Up(Keys);
97  }
98  pKeySelUp = new C4KeyBinding(Keys, "GUIContextSelUp", KEYSCOPE_Gui,
99  new C4KeyCB<ContextMenu>(*this, &ContextMenu::KeySelUp), C4CustomKey::PRIO_Context);
100 
101  Keys.clear();
102  Keys.emplace_back(K_DOWN);
104  {
105  ControllerKeys::Down(Keys);
106  }
107  pKeySelDown = new C4KeyBinding(Keys, "GUIContextSelDown", KEYSCOPE_Gui,
108  new C4KeyCB<ContextMenu>(*this, &ContextMenu::KeySelDown), C4CustomKey::PRIO_Context);
109 
110  Keys.clear();
111  Keys.emplace_back(K_RIGHT);
113  {
114  ControllerKeys::Right(Keys);
115  }
116  pKeySubmenu = new C4KeyBinding(Keys, "GUIContextSubmenu", KEYSCOPE_Gui,
117  new C4KeyCB<ContextMenu>(*this, &ContextMenu::KeySubmenu), C4CustomKey::PRIO_Context);
118 
119  Keys.clear();
120  Keys.emplace_back(K_LEFT);
122  {
123  ControllerKeys::Left(Keys);
124  }
125  pKeyBack = new C4KeyBinding(Keys, "GUIContextBack", KEYSCOPE_Gui,
126  new C4KeyCB<ContextMenu>(*this, &ContextMenu::KeyBack), C4CustomKey::PRIO_Context);
127 
128  Keys.clear();
129  Keys.emplace_back(K_ESCAPE);
131  {
133  }
134  pKeyAbort = new C4KeyBinding(Keys, "GUIContextAbort", KEYSCOPE_Gui,
135  new C4KeyCB<ContextMenu>(*this, &ContextMenu::KeyAbort), C4CustomKey::PRIO_Context);
136 
137  Keys.clear();
138  Keys.emplace_back(K_RETURN);
140  {
141  ControllerKeys::Ok(Keys);
142  }
143  pKeyConfirm = new C4KeyBinding(Keys, "GUIContextConfirm", KEYSCOPE_Gui,
144  new C4KeyCB<ContextMenu>(*this, &ContextMenu::KeyConfirm), C4CustomKey::PRIO_Context);
145 
146  pKeyHotkey = new C4KeyBinding(C4KeyCodeEx(KEY_Any), "GUIContextHotkey", KEYSCOPE_Gui,
147  new C4KeyCBPassKey<ContextMenu>(*this, &ContextMenu::KeyHotkey), C4CustomKey::PRIO_Context);
148  }
149 
151  {
152  // del any submenu
153  if (pSubmenu) { delete pSubmenu; pSubmenu=nullptr; }
154  // forward RemoveElement to screen
155  Screen *pScreen = GetScreen();
156  if (pScreen) pScreen->RemoveElement(this);
157  // clear key bindings
158  delete pKeySelUp;
159  delete pKeySelDown;
160  delete pKeySubmenu;
161  delete pKeyBack;
162  delete pKeyAbort;
163  delete pKeyConfirm;
164  delete pKeyHotkey;
165  // clear children to get appropriate callbacks
166  Clear();
167  }
168 
169  void ContextMenu::Abort(bool fByUser)
170  {
171  // effect
172  if (fByUser) GUISound("UI::Close");
173  // simply del menu: dtor will remove itself
174  delete this;
175  }
176 
178  {
179  // draw context menu bg
183  // context bg: mark selected item
184  if (pSelectedItem)
185  {
186  // get marked item bounds
187  C4Rect rcSelArea = pSelectedItem->GetBounds();
188  // do indent
189  rcSelArea.x += GetClientRect().x;
190  rcSelArea.y += GetClientRect().y;
191  // draw
192  pDraw->DrawBoxDw(cgo.Surface, rcSelArea.x+cgo.TargetX, rcSelArea.y+cgo.TargetY,
193  rcSelArea.x+rcSelArea.Wdt+cgo.TargetX-1, rcSelArea.y+rcSelArea.Hgt+cgo.TargetY-1,
195  }
196  // draw frame
197  Draw3DFrame(cgo);
198  }
199 
200  void ContextMenu::MouseInput(CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam)
201  {
202  // inherited
203  Window::MouseInput(rMouse, iButton, iX, iY, dwKeyParam);
204  // mouse is in client area?
205  if (GetClientRect().Contains(iX+rcBounds.x, iY+rcBounds.y))
206  {
207  // reset selection
208  Element *pPrevSelectedItem = pSelectedItem;
209  pSelectedItem = nullptr;
210  // get client component the mouse is over
211  iX -= GetMarginLeft(); iY -= GetMarginTop();
212  for (Element *pCurr = GetFirst(); pCurr; pCurr = pCurr->GetNext())
213  if (pCurr->GetBounds().Contains(iX, iY))
214  pSelectedItem = pCurr;
215  // selection change sound
216  if (pSelectedItem != pPrevSelectedItem)
217  {
218  SelectionChanged(true);
219  // selection by mouse: Check whether submenu can be opened
221  }
222  // check mouse click
223  if (iButton == C4MC_Button_LeftDown)
224  { DoOK(); return; }
225  }
226  }
227 
228  void ContextMenu::MouseLeaveEntry(CMouse &rMouse, Entry *pOldEntry)
229  {
230  // no submenu open? then deselect any selected item
231  if (pOldEntry==pSelectedItem && !pSubmenu)
232  {
233  pSelectedItem = nullptr;
234  SelectionChanged(true);
235  }
236  }
237 
238  bool ContextMenu::KeySelUp()
239  {
240  // not if focus is in submenu
241  if (pSubmenu) return false;
242  Element *pPrevSelectedItem = pSelectedItem;
243  // select prev
245  // nothing selected or beginning reached: cycle
247  // selection might have changed
248  if (pSelectedItem != pPrevSelectedItem) SelectionChanged(true);
249  return true;
250  }
251 
252  bool ContextMenu::KeySelDown()
253  {
254  // not if focus is in submenu
255  if (pSubmenu) return false;
256  Element *pPrevSelectedItem = pSelectedItem;
257  // select next
259  // nothing selected or end reached: cycle
261  // selection might have changed
262  if (pSelectedItem != pPrevSelectedItem) SelectionChanged(true);
263  return true;
264  }
265 
266  bool ContextMenu::KeySubmenu()
267  {
268  // not if focus is in submenu
269  if (pSubmenu) return false;
271  return true;
272  }
273 
274  bool ContextMenu::KeyBack()
275  {
276  // not if focus is in submenu
277  if (pSubmenu) return false;
278  // close submenu on keyboard input
279  if (IsSubmenu()) { Abort(true); return true; }
280  return false;
281  }
282 
283  bool ContextMenu::KeyAbort()
284  {
285  // not if focus is in submenu
286  if (pSubmenu) return false;
287  Abort(true);
288  return true;
289  }
290 
291  bool ContextMenu::KeyConfirm()
292  {
293  // not if focus is in submenu
294  if (pSubmenu) return false;
296  DoOK();
297  return true;
298  }
299 
300  bool ContextMenu::KeyHotkey(const C4KeyCodeEx &key)
301  {
302  // not if focus is in submenu
303  if (pSubmenu) return false;
304  Element *pPrevSelectedItem = pSelectedItem;
305  StdStrBuf sKey = C4KeyCodeEx::KeyCode2String(key.Key, true, true);
306  // do hotkey procs for standard alphanumerics only
307  if (sKey.getLength() != 1) return false;
308  WORD wKey = WORD(*sKey.getData());
309  if (Inside<C4KeyCode, C4KeyCode, C4KeyCode>(wKey, 'A', 'Z') || Inside<C4KeyCode, C4KeyCode, C4KeyCode>(wKey, '0', '9'))
310  {
311  // process hotkeys
312  uint32_t ch = wKey;
313  for (Element *pCurr = GetFirst(); pCurr; pCurr = pCurr->GetNext())
314  if (pCurr->OnHotkey(ch))
315  {
316  pSelectedItem = pCurr;
317  if (pSelectedItem != pPrevSelectedItem) SelectionChanged(true);
319  DoOK();
320  return true;
321  }
322  return false;
323  }
324  // unrecognized hotkey
325  return false;
326  }
327 
328  void ContextMenu::UpdateElementPositions()
329  {
330  // first item at zero offset
331  Element *pCurr = GetFirst();
332  if (!pCurr) return;
333  pCurr->GetBounds().y = 0;
334  int32_t iMinWdt = std::max<int32_t>(20, pCurr->GetBounds().Wdt);;
335  int32_t iOverallHgt = pCurr->GetBounds().Hgt;
336  // others stacked under it
337  while ((pCurr = pCurr->GetNext()))
338  {
339  iMinWdt = std::max(iMinWdt, pCurr->GetBounds().Wdt);
340  int32_t iYSpace = pCurr->GetListItemTopSpacing();
341  int32_t iNewY = iOverallHgt + iYSpace;
342  iOverallHgt += pCurr->GetBounds().Hgt + iYSpace;
343  if (iNewY != pCurr->GetBounds().y)
344  {
345  pCurr->GetBounds().y = iNewY;
346  pCurr->UpdateOwnPos();
347  }
348  }
349  // don't make smaller
350  iMinWdt = std::max(iMinWdt, rcBounds.Wdt - GetMarginLeft() - GetMarginRight());
351  // all entries same size
352  for (pCurr = GetFirst(); pCurr; pCurr = pCurr->GetNext())
353  if (pCurr->GetBounds().Wdt != iMinWdt)
354  {
355  pCurr->GetBounds().Wdt = iMinWdt;
356  pCurr->UpdateOwnPos();
357  }
358  // update own size
359  rcBounds.Wdt = iMinWdt + GetMarginLeft() + GetMarginRight();
360  rcBounds.Hgt = std::max<int32_t>(iOverallHgt, 8) + GetMarginTop() + GetMarginBottom();
361  UpdateSize();
362  }
363 
365  {
366  // inherited
367  Window::RemoveElement(pChild);
368  // target lost?
369  if (pChild == pTarget) { Abort(false); return; }
370  // submenu?
371  if (pChild == pSubmenu) pSubmenu = nullptr;
372  // clear selection var
373  if (pChild == pSelectedItem)
374  {
375  pSelectedItem = nullptr;
376  SelectionChanged(false);
377  }
378  // forward to any submenu
379  if (pSubmenu) pSubmenu->RemoveElement(pChild);
380  // forward to mouse
381  if (GetScreen())
382  GetScreen()->Mouse.RemoveElement(pChild);
383  // update positions
384  UpdateElementPositions();
385  }
386 
387  bool ContextMenu::AddElement(Element *pChild)
388  {
389  // add it
390  Window::AddElement(pChild);
391  // update own size and positions
392  UpdateElementPositions();
393  // success
394  return true;
395  }
396 
397  bool ContextMenu::InsertElement(Element *pChild, Element *pInsertBefore)
398  {
399  // insert it
400  Window::InsertElement(pChild, pInsertBefore);
401  // update own size and positions
402  UpdateElementPositions();
403  // success
404  return true;
405  }
406 
408  {
409  // inherited
410  Window::ElementSizeChanged(pOfElement);
411  // update positions of all list items
412  UpdateElementPositions();
413  }
414 
416  {
417  // inherited
418  Window::ElementSizeChanged(pOfElement);
419  // update positions of all list items
420  UpdateElementPositions();
421  }
422 
423  void ContextMenu::SelectionChanged(bool fByUser)
424  {
425  // any selection?
426  if (pSelectedItem)
427  {
428  // effect
429  if (fByUser) GUISound("UI::Select");
430  }
431  // close any submenu from prev selection
432  if (pSubmenu) pSubmenu->Abort(true);
433  }
434 
436  {
437  // context menus don't have a parent; get screen by static var
438  return Screen::GetScreenS();
439  }
440 
441  bool ContextMenu::CtxMouseInput(CMouse &rMouse, int32_t iButton, int32_t iScreenX, int32_t iScreenY, DWORD dwKeyParam)
442  {
443  // check submenu
444  if (pSubmenu)
445  if (pSubmenu->CtxMouseInput(rMouse, iButton, iScreenX, iScreenY, dwKeyParam)) return true;
446  // check bounds
447  if (!rcBounds.Contains(iScreenX, iScreenY)) return false;
448  // inside menu: do input in local coordinates
449  MouseInput(rMouse, iButton, iScreenX - rcBounds.x, iScreenY - rcBounds.y, dwKeyParam);
450  return true;
451  }
452 
453  bool ContextMenu::CharIn(const char * c)
454  {
455  // forward to submenu
456  if (pSubmenu) return pSubmenu->CharIn(c);
457  return false;
458  }
459 
461  {
462  // In editor mode, the surface is not assigned
463  // The menu is drawn directly by the dialogue, so just exit here.
464  if (!cgo.Surface) return;
465  // draw self
466  Window::Draw(cgo);
467  // draw submenus on top
468  if (pSubmenu) pSubmenu->Draw(cgo);
469  }
470 
471  void ContextMenu::Open(Element *pTarget, int32_t iScreenX, int32_t iScreenY)
472  {
473  // set pos
474  rcBounds.x = iScreenX; rcBounds.y = iScreenY;
475  UpdatePos();
476  // set target
477  this->pTarget = pTarget;
478  // effect :)
479  GUISound("UI::Open");
480  // done
481  }
482 
484  {
485  // safety
486  if (!GetScreen()) return;
487  // anything selected?
488  if (!pSelectedItem) return;
489  // get as entry
490  Entry *pSelEntry = (Entry *) pSelectedItem;
491  // has submenu handler?
492  ContextHandler *pSubmenuHandler = pSelEntry->pSubmenuHandler;
493  if (!pSubmenuHandler) return;
494  // create submenu then
495  if (pSubmenu) pSubmenu->Abort(false);
496  pSubmenu = pSubmenuHandler->OnSubcontext(pTarget);
497  // get open pos
498  int32_t iX = GetClientRect().x + pSelEntry->GetBounds().x + pSelEntry->GetBounds().Wdt;
499  int32_t iY = GetClientRect().y + pSelEntry->GetBounds().y + pSelEntry->GetBounds().Hgt/2;
500  int32_t iScreenWdt = GetScreen()->GetBounds().Wdt, iScreenHgt = GetScreen()->GetBounds().Hgt;
501  if (iY + pSubmenu->GetBounds().Hgt >= iScreenHgt)
502  {
503  // bottom too narrow: open to top, if height is sufficient
504  // otherwise, open to top from bottom screen pos
505  if (iY < pSubmenu->GetBounds().Hgt) iY = iScreenHgt;
506  iY -= pSubmenu->GetBounds().Hgt;
507  }
508  if (iX + pSubmenu->GetBounds().Wdt >= iScreenWdt)
509  {
510  // right too narrow: try opening left of this menu
511  // otherwise, open to left from right screen border
512  if (GetClientRect().x < pSubmenu->GetBounds().Wdt)
513  iX = iScreenWdt;
514  else
515  iX = GetClientRect().x;
516  iX -= pSubmenu->GetBounds().Wdt;
517  }
518  // open it
519  pSubmenu->Open(pTarget, iX, iY);
520  }
521 
523  {
524  return GetScreen() && GetScreen()->pContext!=this;
525  }
526 
528  {
529  // safety
530  if (!GetScreen()) return;
531  // anything selected?
532  if (!pSelectedItem) return;
533  // get as entry
534  Entry *pSelEntry = (Entry *) pSelectedItem;
535  // get CB; take over pointer
536  MenuHandler *pCallback = pSelEntry->GetAndZeroCallback();
537  Element *pTarget = this->pTarget;
538  if (!pCallback) return;
539  // close all menus (deletes this class!) w/o sound
540  GetScreen()->AbortContext(false);
541  // sound
542  GUISound("UI::Click");
543  // do CB
544  pCallback->OnOK(pTarget);
545  // free CB class
546  delete pCallback;
547  }
548 
549  void ContextMenu::SelectItem(int32_t iIndex)
550  {
551  // get item to be selected (may be nullptr on purpose!)
552  Element *pNewSelElement = GetElementByIndex(iIndex);
553  if (pNewSelElement != pSelectedItem) return;
554  // set new
555  pSelectedItem = pNewSelElement;
556  SelectionChanged(false);
557  }
558 
559 
560 // ----------------------------------------------------
561 // ContextButton
562 
563  ContextButton::ContextButton(C4Rect &rtBounds) : Control(rtBounds), iOpenMenu(0), fMouseOver(false)
564  {
565  RegisterContextKey();
566  }
567 
568  ContextButton::ContextButton(Element *pForEl, bool fAdd, int32_t iHIndent, int32_t iVIndent)
569  : Control(C4Rect(0,0,0,0)), iOpenMenu(0), fMouseOver(false)
570  {
571  SetBounds(pForEl->GetToprightCornerRect(16, 16, iHIndent, iVIndent));
572  // copy context handler
574  // add if desired
575  Container *pCont;
576  if (fAdd) if ((pCont = pForEl->GetContainer()))
577  pCont->AddElement(this);
578  RegisterContextKey();
579  }
580 
582  {
583  delete pKeyContext;
584  }
585 
586  void ContextButton::RegisterContextKey()
587  {
588  // reg keys for pressing the context button
589  C4CustomKey::CodeList ContextKeys;
590  ContextKeys.emplace_back(K_RIGHT);
591  ContextKeys.emplace_back(K_DOWN);
592  ContextKeys.emplace_back(K_SPACE);
593  ContextKeys.emplace_back(K_RIGHT, KEYS_Alt);
594  ContextKeys.emplace_back(K_DOWN, KEYS_Alt);
595  ContextKeys.emplace_back(K_SPACE, KEYS_Alt);
596  pKeyContext = new C4KeyBinding(ContextKeys, "GUIContextButtonPress", KEYSCOPE_Gui,
597  new ControlKeyCB<ContextButton>(*this, &ContextButton::KeyContext), C4CustomKey::PRIO_Ctrl);
598  }
599 
600  bool ContextButton::DoContext(int32_t iX, int32_t iY)
601  {
602  // get context pos
603  if (iX<0)
604  {
605  iX = rcBounds.Wdt/2;
606  iY = rcBounds.Hgt/2;
607  }
608  // do context
609  ContextHandler *pCtx = GetContextHandler();
610  if (!pCtx) return false;
611  if (!pCtx->OnContext(this, iX, iY)) return false;
612  // store menu
613  Screen *pScr = GetScreen();
614  if (!pScr) return false;
615  iOpenMenu = pScr->GetContextMenuIndex();
616  // return whether all was successful
617  return !!iOpenMenu;
618  }
619 
621  {
622  // recheck open menu
623  Screen *pScr = GetScreen();
624  if (!pScr || (iOpenMenu != pScr->GetContextMenuIndex())) iOpenMenu = 0;
625  // calc drawing bounds
626  int32_t x0 = cgo.TargetX + rcBounds.x, y0 = cgo.TargetY + rcBounds.y;
627  // draw button; down (phase 1) if a menu is open
628  ::GraphicsResource.fctContext.Draw(cgo.Surface, x0, y0, iOpenMenu ? 1 : 0);
629  // draw selection highlight
630  if (HasDrawFocus() || (fMouseOver && IsInActiveDlg(false)) || iOpenMenu)
631  {
634  pDraw->ResetBlitMode();
635  }
636  }
637 
638  void ContextButton::MouseInput(CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam)
639  {
640  // left-click activates menu
641  if ((iButton == C4MC_Button_LeftDown) || (iButton == C4MC_Button_RightDown))
642  if (DoContext()) return;
643  // inherited
644  Control::MouseInput(rMouse, iButton, iX, iY, dwKeyParam);
645  }
646 
648  {
649  Control::MouseEnter(rMouse);
650  // remember mouse state for button highlight
651  fMouseOver = true;
652  }
653 
655  {
656  Control::MouseLeave(rMouse);
657  // mouse left
658  fMouseOver = false;
659  }
660 
661 
662 
663 } // end of namespace
664 
C4Config Config
Definition: C4Config.cpp:930
C4Draw * pDraw
Definition: C4Draw.cpp:42
C4GraphicsResource GraphicsResource
#define C4GUI_ContextBGColor
Definition: C4Gui.h:65
#define C4GUI_ContextFontClr
Definition: C4Gui.h:55
#define C4GUI_ContextSelColor
Definition: C4Gui.h:64
const C4KeyCode KEY_Any
@ KEYSCOPE_Gui
@ KEYS_Alt
const int32_t C4MC_Button_RightDown
const int32_t C4MC_Button_LeftDown
const int ALeft
Definition: C4Surface.h:41
#define C4GFXBLIT_ADDITIVE
Definition: C4Surface.h:26
uint16_t WORD
uint32_t DWORD
int32_t GamepadGuiControl
Definition: C4Config.h:233
C4ConfigControls Controls
Definition: C4Config.h:263
std::vector< C4KeyCodeEx > CodeList
void SetBlitMode(DWORD dwBlitMode)
Definition: C4Draw.h:191
void DrawBoxDw(C4Surface *sfcDest, int iX1, int iY1, int iX2, int iY2, DWORD dwClr)
Definition: C4Draw.cpp:840
void ResetBlitMode()
Definition: C4Draw.h:192
bool TextOut(const char *szText, CStdFont &rFont, float fZoom, C4Surface *sfcDest, float iTx, float iTy, DWORD dwFCol=0xffffffff, BYTE byForm=ALeft, bool fDoMarkup=true)
Definition: C4Draw.cpp:561
C4Surface * Surface
Definition: C4Facet.h:117
C4Facet GetPhase(int iPhaseX=0, int iPhaseY=0)
Definition: C4Facet.cpp:59
float Hgt
Definition: C4Facet.h:118
float Wdt
Definition: C4Facet.h:118
void Draw(C4Facet &cgo, bool fAspect=true, int32_t iPhaseX=0, int32_t iPhaseY=0, bool fTransparent=true)
Definition: C4Facet.cpp:154
bool GetPhaseNum(int32_t &rX, int32_t &rY)
Definition: C4Facet.cpp:472
void DrawX(C4Surface *sfcTarget, float iX, float iY, float iWdt, float iHgt, int32_t iPhaseX=0, int32_t iPhaseY=0) const
Definition: C4Facet.cpp:358
void RemoveElement(Element *pChild)
Definition: C4Gui.cpp:534
friend class Element
Definition: C4Gui.h:844
virtual Element * GetLastContained()
Definition: C4Gui.h:774
void AddElement(Element *pChild)
void RemoveElement(Element *pChild) override
virtual void ElementSizeChanged(Element *pOfElement)
Definition: C4Gui.h:753
Element * GetElementByIndex(int32_t i)
Element * GetFirst()
Definition: C4Gui.h:829
void InsertElement(Element *pChild, Element *pInsertBefore)
Element * GetFirstContained() override
Definition: C4Gui.h:773
void DrawElement(C4TargetFacet &cgo) override
Definition: C4GuiMenu.cpp:620
void MouseEnter(CMouse &rMouse) override
Definition: C4GuiMenu.cpp:647
void MouseInput(CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam) override
Definition: C4GuiMenu.cpp:638
void MouseLeave(CMouse &rMouse) override
Definition: C4GuiMenu.cpp:654
~ContextButton() override
Definition: C4GuiMenu.cpp:581
ContextButton(C4Rect &rtBounds)
Definition: C4GuiMenu.cpp:563
virtual ContextMenu * OnSubcontext(Element *pOnElement)=0
Definition: C4Gui.h:1792
uint32_t cHotkey
Definition: C4Gui.h:1798
MenuHandler * GetAndZeroCallback()
Definition: C4Gui.h:1806
ContextHandler * pSubmenuHandler
Definition: C4Gui.h:1801
void DrawElement(C4TargetFacet &cgo) override
Definition: C4GuiMenu.cpp:36
Icons icoIcon
Definition: C4Gui.h:1799
Entry(const char *szText, Icons icoIcon=Ico_None, MenuHandler *pMenuHandler=nullptr, ContextHandler *pSubmenuHandler=nullptr)
Definition: C4GuiMenu.cpp:61
StdStrBuf sText
Definition: C4Gui.h:1797
~ContextMenu() override
Definition: C4GuiMenu.cpp:150
Element * pTarget
Definition: C4Gui.h:1830
void Draw(C4TargetFacet &cgo) override
Definition: C4GuiMenu.cpp:460
int32_t GetMarginTop() override
Definition: C4Gui.h:1851
void ElementPosChanged(Element *pOfElement) override
Definition: C4GuiMenu.cpp:415
void DrawElement(C4TargetFacet &cgo) override
Definition: C4GuiMenu.cpp:177
Screen * GetScreen() override
Definition: C4GuiMenu.cpp:435
Element * pSelectedItem
Definition: C4Gui.h:1831
ContextMenu * pSubmenu
Definition: C4Gui.h:1833
void RemoveElement(Element *pChild) override
Definition: C4GuiMenu.cpp:364
int32_t GetMarginBottom() override
Definition: C4Gui.h:1854
virtual bool CharIn(const char *c)
Definition: C4GuiMenu.cpp:453
void MouseLeaveEntry(CMouse &rMouse, Entry *pOldEntry)
Definition: C4GuiMenu.cpp:228
void Open(Element *pTarget, int32_t iScreenX, int32_t iScreenY)
Definition: C4GuiMenu.cpp:471
void ElementSizeChanged(Element *pOfElement) override
Definition: C4GuiMenu.cpp:407
int32_t GetMarginRight() override
Definition: C4Gui.h:1853
bool CtxMouseInput(CMouse &rMouse, int32_t iButton, int32_t iScreenX, int32_t iScreenY, DWORD dwKeyParam)
Definition: C4GuiMenu.cpp:441
void SelectionChanged(bool fByUser)
Definition: C4GuiMenu.cpp:423
int32_t GetMarginLeft() override
Definition: C4Gui.h:1852
void Abort(bool fByUser)
Definition: C4GuiMenu.cpp:169
void MouseInput(CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam) override
Definition: C4GuiMenu.cpp:200
void SelectItem(int32_t iIndex)
Definition: C4GuiMenu.cpp:549
void MouseInput(CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam) override
bool DoContext()
Definition: C4Gui.cpp:417
Element * GetPrev() const
Definition: C4Gui.h:450
C4Rect rcBounds
Definition: C4Gui.h:385
virtual Container * GetContainer()
Definition: C4Gui.h:410
C4Rect GetToprightCornerRect(int32_t iWidth=16, int32_t iHeight=16, int32_t iHIndent=4, int32_t iVIndent=4, int32_t iIndexX=0)
Definition: C4Gui.cpp:399
virtual Screen * GetScreen()
Definition: C4Gui.cpp:289
Element * GetNext() const
Definition: C4Gui.h:449
bool IsInActiveDlg(bool fForKeyboard)
Definition: C4Gui.cpp:435
virtual void UpdateSize()
Definition: C4Gui.cpp:185
void SetBounds(const C4Rect &rcNewBound)
Definition: C4Gui.h:446
virtual ContextHandler * GetContextHandler()
Definition: C4Gui.cpp:429
virtual void UpdatePos()
Definition: C4Gui.cpp:193
virtual void MouseEnter(CMouse &rMouse)
Definition: C4Gui.h:413
void SetContextHandler(ContextHandler *pNewHd)
Definition: C4Gui.h:465
C4Rect & GetBounds()
Definition: C4Gui.h:445
virtual void MouseLeave(CMouse &rMouse)
Definition: C4Gui.h:414
void Draw3DFrame(C4TargetFacet &cgo, bool fUp=false, int32_t iIndent=1, BYTE byAlpha=C4GUI_BorderAlpha, bool fDrawTop=true, int32_t iTopOff=0, bool fDrawLeft=true, int32_t iLeftOff=0)
Definition: C4Gui.cpp:291
virtual void OnOK(Element *pTarget)=0
static Screen * GetScreenS()
Definition: C4Gui.h:2629
int32_t GetContextMenuIndex()
Definition: C4Gui.h:2658
CMouse Mouse
Definition: C4Gui.h:2590
ContextMenu * pContext
Definition: C4Gui.h:2594
void AbortContext(bool fByUser)
Definition: C4Gui.h:2657
void RemoveElement(Element *pChild) override
Definition: C4Gui.cpp:556
void MouseInput(CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam) override
void Draw(C4TargetFacet &cgo) override
C4Rect & GetClientRect() override
Definition: C4Gui.h:864
Definition: C4Rect.h:28
int32_t y
Definition: C4Rect.h:30
int32_t Hgt
Definition: C4Rect.h:30
int32_t Wdt
Definition: C4Rect.h:30
int32_t x
Definition: C4Rect.h:30
bool Contains(int32_t iX, int32_t iY) const
Definition: C4Rect.h:40
float TargetY
Definition: C4Facet.h:165
float TargetX
Definition: C4Facet.h:165
int GetLineHeight() const
Definition: C4FontLoader.h:125
bool GetTextExtent(const char *szText, int32_t &rsx, int32_t &rsy, bool fCheckMarkup=true)
const char * getData() const
Definition: StdBuf.h:442
void Copy()
Definition: StdBuf.h:467
size_t getLength() const
Definition: StdBuf.h:445
Icons
Definition: C4Gui.h:638
@ Ico_None
Definition: C4Gui.h:640
bool ExpandHotkeyMarkup(StdStrBuf &sText, uint32_t &rcHotkey, bool for_tooltip)
Definition: C4Gui.cpp:38
void GUISound(const char *szSound)
Definition: C4Gui.cpp:1175
void Ok(T &keys)
void Left(T &keys)
void Down(T &keys)
void Up(T &keys)
void Cancel(T &keys)
void Right(T &keys)
static StdStrBuf KeyCode2String(C4KeyCode wCode, bool fHumanReadable, bool fShort)
C4KeyCode Key