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