OpenClonk
C4GuiListBox.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 // container for a dynamic number of vertically stacked controls
18 
19 #include "C4Include.h"
20 #include "gui/C4Gui.h"
21 
22 #include "graphics/C4Draw.h"
23 #include "gui/C4MouseControl.h"
24 
25 namespace C4GUI
26 {
27 
28 
29 // ----------------------------------------------------
30 // ListBox
31 
32  ListBox::ListBox(const C4Rect &rtBounds, int32_t iMultiColItemWidth) : Control(rtBounds), iMultiColItemWidth(iMultiColItemWidth), iColCount(1)
33  , pSelectedItem(nullptr), pSelectionChangeHandler(nullptr), pSelectionDblClickHandler(nullptr), fDrawBackground(true), fDrawBorder(false), fSelectionDisabled(false)
34  {
35  // calc client rect
36  UpdateOwnPos();
37  // create content scroll window
38  pClientWindow = new ScrollWindow(this);
39  // calc column count
41  // create key bindings
42  pKeyContext = new C4KeyBinding(C4KeyCodeEx(K_MENU), "GUIListBoxContext", KEYSCOPE_Gui,
43  new ControlKeyCB<ListBox>(*this, &ListBox::KeyContext), C4CustomKey::PRIO_Ctrl);
45  keys.emplace_back(K_UP);
47  pKeyUp = new C4KeyBinding(keys, "GUIListBoxUp", KEYSCOPE_Gui,
48  new ControlKeyCB<ListBox>(*this, &ListBox::KeyUp), C4CustomKey::PRIO_Ctrl);
49  keys.clear();
50  keys.emplace_back(K_DOWN);
52  pKeyDown = new C4KeyBinding(keys, "GUIListBoxDown", KEYSCOPE_Gui,
53  new ControlKeyCB<ListBox>(*this, &ListBox::KeyDown), C4CustomKey::PRIO_Ctrl);
54  keys.clear();
55  keys.emplace_back(K_LEFT);
57  pKeyLeft = new C4KeyBinding(keys, "GUIListBoxLeft", KEYSCOPE_Gui,
58  new ControlKeyCB<ListBox>(*this, &ListBox::KeyLeft), C4CustomKey::PRIO_Ctrl);
59  keys.clear();
60  keys.emplace_back(K_RIGHT);
62  pKeyRight = new C4KeyBinding(keys, "GUIListBoxRight", KEYSCOPE_Gui,
63  new ControlKeyCB<ListBox>(*this, &ListBox::KeyRight), C4CustomKey::PRIO_Ctrl);
64  pKeyPageUp = new C4KeyBinding(C4KeyCodeEx(K_PAGEUP), "GUIListBoxPageUp", KEYSCOPE_Gui,
65  new ControlKeyCB<ListBox>(*this, &ListBox::KeyPageUp), C4CustomKey::PRIO_Ctrl);
66  pKeyPageDown = new C4KeyBinding(C4KeyCodeEx(K_PAGEDOWN), "GUIListBoxPageDown", KEYSCOPE_Gui,
67  new ControlKeyCB<ListBox>(*this, &ListBox::KeyPageDown), C4CustomKey::PRIO_Ctrl);
68  pKeyHome = new C4KeyBinding(C4KeyCodeEx(K_HOME), "GUIListBoxHome", KEYSCOPE_Gui,
69  new ControlKeyCB<ListBox>(*this, &ListBox::KeyHome), C4CustomKey::PRIO_Ctrl);
70  pKeyEnd = new C4KeyBinding(C4KeyCodeEx(K_END), "GUIListBoxEnd", KEYSCOPE_Gui,
71  new ControlKeyCB<ListBox>(*this, &ListBox::KeyEnd), C4CustomKey::PRIO_Ctrl);
72  // "activate" current item
73  keys.clear();
74  keys.emplace_back(K_RETURN);
75  keys.emplace_back(K_RETURN, KEYS_Alt);
77  {
78  ControllerKeys::Ok(keys);
79  }
80  pKeyActivate = new C4KeyBinding(keys, "GUIListActivate", KEYSCOPE_Gui,
81  new ControlKeyCB<ListBox>(*this, &ListBox::KeyActivate), C4CustomKey::PRIO_Ctrl);
82  }
83 
85  {
86  delete pKeyActivate;
87  delete pKeyEnd;
88  delete pKeyHome;
89  delete pKeyPageDown;
90  delete pKeyPageUp;
91  delete pKeyRight;
92  delete pKeyLeft;
93  delete pKeyDown;
94  delete pKeyUp;
95  delete pKeyContext;
98  }
99 
101  {
102  if (fDrawBackground)
104  if (fDrawBorder) Draw3DFrame(cgo);
105  // listbox bg: mark selected item
106  if (!pClientWindow) return;
107  if (pSelectedItem)
108  {
109  C4Rect rcSelArea = pSelectedItem->GetBounds();
110  rcSelArea.x += GetClientRect().x;
111  rcSelArea.y += GetClientRect().y + pClientWindow->GetClientRect().y;
112  // clip
113  if (rcSelArea.y < GetClientRect().y)
114  {
115  rcSelArea.Hgt -= GetClientRect().y - rcSelArea.y;
116  rcSelArea.y = GetClientRect().y;
117  }
118  rcSelArea.Hgt = std::min(rcSelArea.Hgt, GetClientRect().y + GetClientRect().Hgt - rcSelArea.y);
119  // draw
120  if (rcSelArea.Hgt>=0)
121  pDraw->DrawBoxDw(cgo.Surface, rcSelArea.x+cgo.TargetX, rcSelArea.y+cgo.TargetY,
122  rcSelArea.x+rcSelArea.Wdt+cgo.TargetX-1, rcSelArea.y+rcSelArea.Hgt+cgo.TargetY-1,
124  }
125  // draw delimeter bars
126  Element *pCurr = pClientWindow->GetFirst();
127  if (!pCurr) return;
128  while ((pCurr = pCurr->GetNext()))
129  if (pCurr->GetListItemTopSpacingBar())
130  {
131  int32_t iYSpace = pCurr->GetListItemTopSpacing();
132  int32_t iY = pCurr->GetBounds().y + GetClientRect().y + pClientWindow->GetClientRect().y - iYSpace/2;
133  int32_t iX0 = pCurr->GetBounds().x + GetClientRect().x + C4GUI_ListBoxBarIndent;
134  int32_t iX1 = iX0 + pClientWindow->GetClientRect().Wdt - 2*C4GUI_ListBoxBarIndent;
135  // clip
136  if (iY < GetClientRect().y || iY >= GetClientRect().y+GetClientRect().Hgt) continue;
137  // draw
138  pDraw->DrawLineDw(cgo.Surface, (float)(iX0+cgo.TargetX), (float)(iY+cgo.TargetY), (float)(iX1+cgo.TargetX), (float)(iY+cgo.TargetY), C4GUI_ListBoxBarColor);
139  }
140  }
141 
142  void ListBox::MouseInput(CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam)
143  {
144  // inherited
145  Control::MouseInput(rMouse, iButton, iX, iY, dwKeyParam);
146  // safety
147  if (pClientWindow)
148  {
149  // check list area bounds
150  if (pClientWindow->GetBounds().Contains(iX, iY))
151  // left btn down: select item (regardless of key states)
152  if (iButton == C4MC_Button_LeftDown || iButton == C4MC_Button_LeftDouble)
153  {
154  // reset selection
155  Element *pPrevSelectedItem = pSelectedItem;
156  pSelectedItem = nullptr;
157  // get client component the mouse is over
158  iX -= GetMarginLeft(); iY -= GetMarginTop();
159  iY += pClientWindow->GetScrollY();
160  for (Element *pCurr = pClientWindow->GetFirst(); pCurr; pCurr = pCurr->GetNext())
161  if (pCurr->GetBounds().Contains(iX, iY))
162  pSelectedItem = pCurr;
163  // selection change sound
164  if (pSelectedItem != pPrevSelectedItem) SelectionChanged(true);
165  // item double-clicked? Callback
166  if (iButton == C4MC_Button_LeftDouble && pSelectedItem)
168  }
169  }
170  }
171 
173  {
175  {
176  // multicoloumn-listbox
177  iColCount = std::max<int32_t>(pClientWindow->GetClientRect().Wdt / iMultiColItemWidth, 1);
178  }
179  else
180  {
181  // regular 1-col-listbox
182  iColCount = 1;
183  }
184  }
185 
187  {
188  if (!pClientWindow) return 0;
189  // calc superfluous bottom space
190  int32_t iExtraSpace = pClientWindow->GetBounds().Hgt - pClientWindow->GetClientRect().Hgt;
191  if (iExtraSpace <= 0) return 0;
192  // contract by it
193  C4Rect rcNewBounds = GetBounds();
194  rcNewBounds.Hgt -= iExtraSpace;
195  SetBounds(rcNewBounds);
196  return iExtraSpace;
197  }
198 
199  void ListBox::OnGetFocus(bool fByMouse)
200  {
201  // inherited (tooltip)
202  Control::OnGetFocus(fByMouse);
203  // select list item if none is selected (only for keyboard; mouse will select with left-click anyway)
204  if (!pSelectedItem && pClientWindow && !fByMouse)
205  {
207  SelectionChanged(false);
208  }
209  }
210 
211  bool ListBox::KeyContext()
212  {
213  // key: context menu
214  if (pSelectedItem && pSelectedItem->DoContext()) return true;
215  return false;
216  }
217 
218  bool ListBox::KeyUp()
219  {
220  // key: selection up
221  Element *pPrevSelectedItem = pSelectedItem;
222  if (!pSelectedItem)
223  // select last
225  else
226  {
227  // select prev row
228  int32_t cnt = iColCount;
229  while (pSelectedItem && cnt--) pSelectedItem = pSelectedItem->GetPrev();
230  if (!pSelectedItem) pSelectedItem = pPrevSelectedItem; // was in start row
231  }
232  // selection might have changed
233  if (pSelectedItem != pPrevSelectedItem) SelectionChanged(true);
234  return true;
235  }
236 
237  bool ListBox::KeyDown()
238  {
239  // key: selection down
240  Element *pPrevSelectedItem = pSelectedItem;
241  if (!pSelectedItem)
242  // select first
244  else
245  {
246  // select next row
247  int32_t cnt = iColCount;
248  while (pSelectedItem && cnt--) pSelectedItem = pSelectedItem->GetNext();
249  if (!pSelectedItem) pSelectedItem = pPrevSelectedItem; // was in end row
250  }
251  // selection might have changed
252  if (pSelectedItem != pPrevSelectedItem) SelectionChanged(true);
253  return true;
254  }
255 
256  bool ListBox::KeyLeft()
257  {
258  // key: Selection left
259  // only in multi-col-listboxes
260  if (!IsMultiColumn()) return false;
261  Element *pPrevSelectedItem = pSelectedItem;
262  if (!pSelectedItem)
263  // select last
265  else
266  {
267  // select prev
269  }
270  // selection might have changed
271  if (pSelectedItem != pPrevSelectedItem) SelectionChanged(true);
272  return true;
273  }
274 
275  bool ListBox::KeyRight()
276  {
277  // key: Selection right
278  // only in multi-col-listboxes
279  if (!IsMultiColumn()) return false;
280  Element *pPrevSelectedItem = pSelectedItem;
281  if (!pSelectedItem)
282  // select first
284  else
285  {
286  // select next
288  }
289  // selection might have changed
290  if (pSelectedItem != pPrevSelectedItem) SelectionChanged(true);
291  return true;
292  }
293 
294  bool ListBox::KeyPageDown()
295  {
296  // key: selection one page down
297  // start from first item or selected
299  if (!pNextSelectedItem) return false;
300  if ((pNext = pNextSelectedItem->GetNext()))
301  {
302  pNextSelectedItem = pNext;
303  // if this is not the last, visible item in the list: go down until item is no longer fully in view
304  if (pClientWindow->IsRangeInView(pNextSelectedItem->GetBounds().y, pNextSelectedItem->GetBounds().Hgt))
305  {
306  while ((pNext = pNextSelectedItem->GetNext()))
308  pNextSelectedItem = pNext;
309  else
310  break;
311  }
312  else
313  {
314  // selected item was last visible: Just scroll one page down and select last visible
316  pNextSelectedItem = pClientWindow->GetLastContained();
317  while (!pClientWindow->IsRangeInView(pNextSelectedItem->GetBounds().y, pNextSelectedItem->GetBounds().Hgt))
318  if ((pNext = pNextSelectedItem->GetPrev())) pNextSelectedItem = pNext; else break;
319  }
320  }
321  // selection might have changed
322  if (pSelectedItem != pNextSelectedItem)
323  {
324  pSelectedItem = pNextSelectedItem;
325  SelectionChanged(true);
326  }
327  return true;
328  }
329 
330  bool ListBox::KeyPageUp()
331  {
332  // key: selection one page up
333  // start from last item or selected
335  if (!pNextSelectedItem) return false;
336  if ((pNext = pNextSelectedItem->GetPrev()))
337  {
338  pNextSelectedItem = pNext;
339  // if this is not the first, visible item in the list: go up until item is no longer fully in view
340  if (pClientWindow->IsRangeInView(pNextSelectedItem->GetBounds().y, pNextSelectedItem->GetBounds().Hgt))
341  {
342  while ((pNext = pNextSelectedItem->GetPrev()))
344  pNextSelectedItem = pNext;
345  else
346  break;
347  }
348  else
349  {
350  // selected item was last visible: Just scroll one page up and select first visible
352  pNextSelectedItem = pClientWindow->GetFirstContained();
353  while (!pClientWindow->IsRangeInView(pNextSelectedItem->GetBounds().y, pNextSelectedItem->GetBounds().Hgt))
354  if ((pNext = pNextSelectedItem->GetNext())) pNextSelectedItem = pNext; else break;
355  }
356  }
357  // selection might have changed
358  if (pSelectedItem != pNextSelectedItem)
359  {
360  pSelectedItem = pNextSelectedItem;
361  SelectionChanged(true);
362  }
363  return true;
364  }
365 
366  bool ListBox::KeyHome()
367  {
368  // key: selection to first item
369  Element *pPrevSelectedItem = pSelectedItem;
371  // selection might have changed
372  if (pSelectedItem != pPrevSelectedItem) SelectionChanged(true);
373  return true;
374  }
375 
376  bool ListBox::KeyEnd()
377  {
378  // key: selection to last item
379  Element *pPrevSelectedItem = pSelectedItem;
381  // selection might have changed
382  if (pSelectedItem != pPrevSelectedItem) SelectionChanged(true);
383  return true;
384  }
385 
386  bool ListBox::KeyActivate()
387  {
388  // process as doubleclick
390  {
392  return true;
393  }
394  return false;
395  }
396 
398  {
399  // safety
400  if (!pItem) return;
401  // scroll covered range into view
403  }
404 
406  {
407  // safety
408  if (!pClientWindow) return;
409  // first item at zero offset
410  Element *pCurr = pClientWindow->GetFirst();
411  int iOverallHgt;
412  if (pCurr)
413  {
414  if (!iMultiColItemWidth)
415  {
416  // Single column box: All stacked vertically
417  if (pCurr->GetBounds().y)
418  {
419  pCurr->GetBounds().y = 0;
420  pCurr->UpdateOwnPos();
421  }
422  if(pCurr->fVisible) iOverallHgt = pCurr->GetBounds().Hgt;
423  else iOverallHgt = 0;
424  // others stacked under it
425  while ((pCurr = pCurr->GetNext()))
426  {
427  if(!pCurr->fVisible) continue; //Do not reserve space for hidden elements
428  int32_t iYSpace = pCurr->GetListItemTopSpacing();
429  int32_t iNewY = iOverallHgt + iYSpace;
430  iOverallHgt += pCurr->GetBounds().Hgt + iYSpace;
431  if (iNewY != pCurr->GetBounds().y)
432  {
433  pCurr->GetBounds().y = iNewY;
434  pCurr->UpdateOwnPos();
435  }
436  }
437  }
438  else
439  {
440  // Multi column box: Keep element size; reposition horizontally+vertically
441  int32_t y=0, iLineHgt=0, col=0;
442  for (; pCurr; pCurr=pCurr->GetNext())
443  {
444  const C4Rect &rcCurrBounds = pCurr->GetBounds();
445  iLineHgt = std::max<int32_t>(rcCurrBounds.Hgt, iLineHgt);
446  int32_t x = col * iMultiColItemWidth;
447  if (rcCurrBounds.x != x || rcCurrBounds.y != y || rcCurrBounds.Wdt != iMultiColItemWidth)
448  pCurr->SetBounds(C4Rect(x,y,iMultiColItemWidth,rcCurrBounds.Hgt));
449  if (++col >= iColCount)
450  {
451  col = 0;
452  y += iLineHgt;
453  }
454  }
455  iOverallHgt = y + iLineHgt;
456  }
457  }
458  else
459  iOverallHgt = 0;
460  // update scrolling
461  pClientWindow->SetClientHeight(iOverallHgt);
462  }
463 
464  void ListBox::UpdateElementPosition(Element *pOfElement, int32_t iIndent)
465  {
466  // resize it
467  C4Rect &rcChildBounds = pOfElement->GetBounds();
468  rcChildBounds.x = iIndent;
469  rcChildBounds.Wdt = GetItemWidth() - iIndent ;
470  pOfElement->UpdateOwnPos();
471  // re-stack elements
473  }
474 
476  {
477  // inherited
478  Control::RemoveElement(pChild);
479  // clear selection var
480  if (pChild == pSelectedItem)
481  {
482  pSelectedItem = nullptr;
483  SelectionChanged(false);
484  }
485  // position update in AfterElementRemoval
486  }
487 
488  bool ListBox::AddElement(Element *pChild, int32_t iIndent)
489  {
490  // fail if no client window is present
491  if (!pClientWindow) return false;
492  // add to scroll window
493  pClientWindow->AddElement(pChild);
494  // resize to horizontal list extents
495  C4Rect &rcChildBounds = pChild->GetBounds();
496  rcChildBounds.x = iIndent;
497  rcChildBounds.Wdt = GetItemWidth() - iIndent ;
498  // reposition to end of list
499  if (pChild->GetPrev())
500  {
501  if (iMultiColItemWidth)
502  {
503  rcChildBounds.y = pChild->GetPrev()->GetBounds().y;
504  int32_t col = pChild->GetPrev()->GetBounds().x / iMultiColItemWidth + 1;
505  if (col >= iColCount)
506  {
507  col = 0;
508  int32_t cnt = iColCount;
509  int32_t iPrevLineHgt = 0;
510  Element *pPrevChild = pChild->GetPrev();
511  while (cnt-- && pPrevChild)
512  {
513  iPrevLineHgt = std::max<int32_t>(iPrevLineHgt, pPrevChild->GetBounds().Hgt);
514  pPrevChild = pPrevChild->GetPrev();
515  }
516  rcChildBounds.y += iPrevLineHgt;
517  }
518  rcChildBounds.x = col * iMultiColItemWidth;
519  }
520  else
521  {
522  rcChildBounds.y = pChild->GetPrev()->GetBounds().y + pChild->GetPrev()->GetBounds().Hgt + pChild->GetListItemTopSpacing();
523  }
524  }
525  else
526  rcChildBounds.y = 0;
527  pChild->UpdateOwnPos();
528  // update scrolling
529  pClientWindow->SetClientHeight(rcChildBounds.y+rcChildBounds.Hgt);
530  // success
531  return true;
532  }
533 
534  bool ListBox::InsertElement(Element *pChild, Element *pInsertBefore, int32_t iIndent)
535  {
536  // fail if no client window is present
537  if (!pClientWindow) return false;
538  // add to scroll window
539  pClientWindow->InsertElement(pChild, pInsertBefore);
540  // resize to horizontal list extents
541  C4Rect &rcChildBounds = pChild->GetBounds();
542  rcChildBounds.x = iIndent;
543  rcChildBounds.Wdt = GetItemWidth() - iIndent ;
544  pChild->UpdateOwnPos();
545  // update all element positions (and scrolling)
547  // done, success
548  return true;
549  }
550 
552  {
553  // inherited
554  if (pOfElement->GetParent() == this)
555  {
556  Control::ElementSizeChanged(pOfElement);
557  // update col count if list element container was resized
559  }
560  // update positions of all list items
562  }
563 
565  {
566  // inherited
567  if (pOfElement->GetParent() == this)
568  Control::ElementSizeChanged(pOfElement);
569  // update positions of all list items
571  }
572 
573  void ListBox::SelectionChanged(bool fByUser)
574  {
575  // selections disabled?
576  if (fSelectionDisabled) { pSelectedItem = nullptr; return; }
577  // any selection?
578  if (pSelectedItem)
579  {
580  // effect
581  if (fByUser) GUISound("UI::Select");
582  }
583  // callback (caution: May do periluous things...)
585  // let's hope it wasn't perilous enough to delete this,
586  // because scrolling the item into view must be done AFTER the callback, as the callback might resize
588  }
589 
590  void ListBox::SelectEntry(Element *pNewSel, bool fByUser)
591  {
592  assert(!pNewSel || pNewSel->GetParent() == pClientWindow);
593  if (pSelectedItem == pNewSel) return;
594  pSelectedItem = pNewSel;
595  SelectionChanged(fByUser);
596  }
597 
598  bool ListBox::CharIn(const char * c)
599  {
600  // Jump to first/next entry beginning with typed letter
601  Element *pSel = GetSelectedItem();
602  Element *pStartCheck = pSel;
603  if (pSel) pSel = pSel->GetNext();
604  if (!pSel)
605  {
606  pSel = GetFirst();
607  if (!pSel) return false;
608  }
609  while (pSel != pStartCheck && !pSel->CheckNameHotkey(c))
610  if (!(pSel = pSel->GetNext()))
611  if (pStartCheck)
612  // list end reached while another entry had been selected before: Re-check start of list
613  pSel = GetFirst();
614  // ok, change selection - might do nothing if list was cycled, which is OK
615  if (pSel)
616  {
617  SelectEntry(pSel, true);
618  return true;
619  }
620  return Control::CharIn(c);
621  }
622 
624  {
625  void *par;
626  ListBox::SortFunction SortFunc;
627 
628  public:
629  SortCompareElements(ListBox::SortFunction SortFunc, void *par) : par(par), SortFunc(SortFunc) {}
630 
631  int operator()(const Element *pEl1, const Element *pEl2)
632  { return (*SortFunc)(pEl1, pEl2, par)>0; }
633  };
634 
635  void ListBox::SortElements(SortFunction SortFunc, void *par)
636  {
637  // sort list items:
638  // create an array of all list items, sort it, and reorder them afterwards
639  if (!pClientWindow) return;
640  int32_t iElemCount = pClientWindow->GetElementCount();
641  if (iElemCount <= 1) return;
642  Element **ppElements = new Element *[iElemCount];
643  try
644  {
645  int32_t i=0;
646  for (Element *pEl = pClientWindow->GetFirst(); pEl; pEl = pEl->GetNext())
647  ppElements[i++] = pEl;
648  std::sort(ppElements, ppElements+iElemCount, SortCompareElements(SortFunc, par));
649  for (i=0; i<iElemCount; ++i)
650  pClientWindow->ReaddElement(ppElements[i]);
651  }
652  catch (...)
653  {
654  delete [] ppElements;
655  throw;
656  }
657  delete [] ppElements;
659  }
660 
661 } // end of namespace
662 
C4Config Config
Definition: C4Config.cpp:930
C4Draw * pDraw
Definition: C4Draw.cpp:42
#define C4GUI_ListBoxBarColor
Definition: C4Gui.h:68
#define C4GUI_ListBoxInactSelColor
Definition: C4Gui.h:63
#define C4GUI_ListBoxSelColor
Definition: C4Gui.h:62
#define C4GUI_ListBoxBarIndent
Definition: C4Gui.h:124
@ KEYSCOPE_Gui
@ KEYS_Alt
const int32_t C4MC_Button_LeftDown
const int32_t C4MC_Button_LeftDouble
uint32_t DWORD
int32_t GamepadGuiControl
Definition: C4Config.h:233
C4ConfigControls Controls
Definition: C4Config.h:263
std::vector< C4KeyCodeEx > CodeList
void DrawBoxDw(C4Surface *sfcDest, int iX1, int iY1, int iX2, int iY2, DWORD dwClr)
Definition: C4Draw.cpp:840
void DrawLineDw(C4Surface *sfcTarget, float x1, float y1, float x2, float y2, DWORD dwClr, float width=1.0f)
Definition: C4Draw.cpp:608
C4Surface * Surface
Definition: C4Facet.h:117
virtual void DoCall(class Element *pElement)=0
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
void ReaddElement(Element *pChild)
Element * GetFirst()
Definition: C4Gui.h:829
void InsertElement(Element *pChild, Element *pInsertBefore)
Element * GetFirstContained() override
Definition: C4Gui.h:773
friend class ScrollWindow
Definition: C4Gui.h:844
friend class ListBox
Definition: C4Gui.h:1070
virtual void OnGetFocus(bool fByMouse)
Definition: C4Gui.h:1056
virtual bool CharIn(const char *)
Definition: C4Gui.h:1051
void MouseInput(CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam) override
bool DoContext()
Definition: C4Gui.cpp:417
virtual bool GetListItemTopSpacingBar()
Definition: C4Gui.h:462
Element * GetPrev() const
Definition: C4Gui.h:450
C4Rect rcBounds
Definition: C4Gui.h:385
Element * GetNext() const
Definition: C4Gui.h:449
void SetBounds(const C4Rect &rcNewBound)
Definition: C4Gui.h:446
Container * GetParent()
Definition: C4Gui.h:429
bool fVisible
Definition: C4Gui.h:383
Element * pNext
Definition: C4Gui.h:377
virtual bool CheckNameHotkey(const char *)
Definition: C4Gui.h:407
C4Rect & GetBounds()
Definition: C4Gui.h:445
virtual int32_t GetListItemTopSpacing()
Definition: C4Gui.h:461
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 UpdateOwnPos()
Definition: C4Gui.h:434
Element * GetSelectedItem()
Definition: C4Gui.h:1581
void ElementPosChanged(Element *pOfElement) override
bool InsertElement(Element *pChild, Element *pInsertBefore, int32_t iIndent=0)
int32_t ContractToElementHeight()
BaseCallbackHandler * pSelectionChangeHandler
Definition: C4Gui.h:1512
bool AddElement(Element *pChild, int32_t iIndent=0)
bool CharIn(const char *c) override
Element * GetFirst()
Definition: C4Gui.h:1572
void UpdateElementPositions()
ScrollWindow * pClientWindow
Definition: C4Gui.h:1510
bool fDrawBackground
Definition: C4Gui.h:1513
Element * pSelectedItem
Definition: C4Gui.h:1511
void DrawElement(C4TargetFacet &cgo) override
~ListBox() override
void ScrollItemInView(Element *pItem)
void ElementSizeChanged(Element *pOfElement) override
void SelectionChanged(bool fByUser)
void MouseInput(CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam) override
bool fDrawBorder
Definition: C4Gui.h:1514
void UpdateColumnCount()
int32_t(* SortFunction)(const Element *pEl1, const Element *pEl2, void *par)
Definition: C4Gui.h:1596
int32_t GetItemWidth()
Definition: C4Gui.h:1546
void SortElements(SortFunction SortFunc, void *par)
bool IsMultiColumn() const
Definition: C4Gui.h:1587
int32_t GetMarginTop() override
Definition: C4Gui.h:1576
int32_t iColCount
Definition: C4Gui.h:1509
BaseCallbackHandler * pSelectionDblClickHandler
Definition: C4Gui.h:1512
void SelectEntry(Element *pNewSel, bool fByUser)
void UpdateElementPosition(Element *pOfElement, int32_t iIndent)
int32_t GetMarginLeft() override
Definition: C4Gui.h:1577
int32_t iMultiColItemWidth
Definition: C4Gui.h:1508
bool fSelectionDisabled
Definition: C4Gui.h:1515
void RemoveElement(Element *pChild) override
void OnGetFocus(bool fByMouse) override
void SetClientHeight(int32_t iToHgt)
Definition: C4Gui.h:973
bool IsRangeInView(int32_t iY, int32_t iHgt)
int32_t GetScrollY()
Definition: C4Gui.h:987
void ScrollPages(int iPageCount)
void ScrollRangeInView(int32_t iY, int32_t iHgt)
SortCompareElements(ListBox::SortFunction SortFunc, void *par)
int operator()(const Element *pEl1, const Element *pEl2)
void UpdateOwnPos() 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
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 Right(T &keys)