GG: ListBox.h Source File

GG

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

ListBox.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /* GG is a GUI for SDL and OpenGL.
3 Copyright (C) 2003-2008 T. Zachary Laine
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public License
7 as published by the Free Software Foundation; either version 2.1
8 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA
19
20 If you do not wish to comply with the terms of the LGPL please
21 contact the author as other terms are available for a fee.
22
23 Zach Laine
24 whatwasthataddress@gmail.com */
25
29 #ifndef _GG_ListBox_h_
30 #define _GG_ListBox_h_
31
32 #include <GG/AlignmentFlags.h>
33 #include <GG/ClrConstants.h>
34 #include <GG/Control.h>
35 #include <GG/Timer.h>
36
37 #include <set>
38
39
40 namespace GG {
41
42 class Font;
43 class Scroll;
44 class SubTexture;
45 class WndEvent;
46
48 GG_FLAG_TYPE(ListBoxStyle);
49 extern GG_API const ListBoxStyle LIST_NONE;
50 extern GG_API const ListBoxStyle LIST_VCENTER;
51 extern GG_API const ListBoxStyle LIST_TOP;
52 extern GG_API const ListBoxStyle LIST_BOTTOM;
53 extern GG_API const ListBoxStyle LIST_CENTER;
54 extern GG_API const ListBoxStyle LIST_LEFT;
55 extern GG_API const ListBoxStyle LIST_RIGHT;
56 extern GG_API const ListBoxStyle LIST_NOSORT;
57 extern GG_API const ListBoxStyle LIST_SORTDESCENDING;
58 extern GG_API const ListBoxStyle LIST_NOSEL;
59 extern GG_API const ListBoxStyle LIST_SINGLESEL;
60 extern GG_API const ListBoxStyle LIST_QUICKSEL;
61 extern GG_API const ListBoxStyle LIST_USERDELETE;
62 extern GG_API const ListBoxStyle LIST_BROWSEUPDATES;
63
64
100 class GG_API ListBox : public Control
101 {
102 public:
111 template <class Cont>
112 struct RowPtrIteratorLess
113 {
114 typedef typename Cont::iterator Iter;
115 RowPtrIteratorLess();
116 RowPtrIteratorLess(Cont* c);
117 bool operator()(Iter lhs, Iter rhs) const;
118 static bool LessThan(Iter lhs, Iter rhs, Iter end);
119 private:
120 Cont* m_container;
121 };
122
147 struct GG_API Row : public Control
148 {
154 struct DeferAdjustLayout
155 {
156 DeferAdjustLayout(Row* row);
157 ~DeferAdjustLayout();
158 Row* const m_row;
159 };
160
162 typedef std::string SortKeyType;
163
165 Row();
166 Row(X w, Y h, const std::string& drag_drop_data_type, Alignment align = ALIGN_VCENTER, unsigned int margin = 2);
167 virtual ~Row();
169
171 SortKeyType SortKey(std::size_t column) const;
172 std::size_t size() const;
173 bool empty() const;
174
175 Control* operator[](std::size_t n) const;
176 Control* at(std::size_t n) const;
177
178 Alignment RowAlignment() const;
179 Alignment ColAlignment(std::size_t n) const;
180 X ColWidth(std::size_t n) const;
181 unsigned int Margin() const;
182
183 Control* CreateControl(const std::string& str, const boost::shared_ptr<Font>& font, Clr color) const;
184 Control* CreateControl(const SubTexture& st) const;
185
186
188 virtual void Render();
189
190 void push_back(Control* c);
191 void push_back(const std::string& str, const boost::shared_ptr<Font>& font, Clr color = CLR_BLACK);
192 void push_back(const std::string& str, const std::string& font_filename, unsigned int pts, Clr color = CLR_BLACK);
193 void push_back(const SubTexture& st);
194 void clear();
195 void resize(std::size_t n);
196
197 void SetCell(std::size_t n, Control* c);
198 Control* RemoveCell(std::size_t n);
199 void SetRowAlignment(Alignment align);
200 void SetColAlignment(std::size_t n, Alignment align);
201 void SetColWidth(std::size_t n, X width);
202 void SetColAlignments(const std::vector<Alignment>& aligns);
203 void SetColWidths(const std::vector<X>& widths);
204 void SetMargin(unsigned int margin);
205
206
207 private:
208 void AdjustLayout(bool adjust_for_push_back = false);
209
210 std::vector<Control*> m_cells;
211 Alignment m_row_alignment;
212 std::vector<Alignment> m_col_alignments;
213 std::vector<X> m_col_widths;
214 unsigned int m_margin;
215
216 bool m_ignore_adjust_layout;
217
218 friend class DeferAdjustLayout;
219 };
220
221 typedef std::list<Row*>::iterator iterator;
222 typedef std::list<Row*>::const_iterator const_iterator;
223 typedef std::list<Row*>::reverse_iterator reverse_iterator;
224 typedef std::list<Row*>::const_reverse_iterator const_reverse_iterator;
225
226 typedef std::set<iterator, RowPtrIteratorLess<std::list<Row*> > > SelectionSet;
227
229 typedef boost::signal<void ()> ClearedSignalType;
230 typedef boost::signal<void (const SelectionSet&)> SelChangedSignalType;
231 typedef boost::signal<void (iterator)> RowSignalType;
232 typedef boost::signal<void (const_iterator)> ConstRowSignalType;
233 typedef boost::signal<void (iterator, const Pt&)> RowClickSignalType;
234
235 typedef RowSignalType InsertedSignalType;
236 typedef RowSignalType DroppedSignalType;
237 typedef ConstRowSignalType DropAcceptableSignalType;
238 typedef RowClickSignalType LeftClickedSignalType;
239 typedef RowClickSignalType RightClickedSignalType;
240 typedef RowSignalType DoubleClickedSignalType;
241 typedef RowSignalType ErasedSignalType;
242 typedef RowSignalType BrowsedSignalType;
243
244
246
247 ListBox(X x, Y y, X w, Y h, Clr color, Clr interior = CLR_ZERO, Flags<WndFlag> flags = INTERACTIVE);
248
249 virtual ~ListBox();
250
251
253 virtual void DropsAcceptable(DropsAcceptableIter first,
254 DropsAcceptableIter last,
255 const Pt& pt) const;
256
257 virtual Pt MinUsableSize() const;
258 virtual Pt ClientUpperLeft() const;
259 virtual Pt ClientLowerRight() const;
260
261 bool Empty() const;
262 const_iterator begin() const;
263 const_iterator end() const;
264 const_reverse_iterator
265 rbegin() const;
266 const_reverse_iterator
267 rend() const;
268 const Row& GetRow(std::size_t n) const;
269 iterator Caret() const;
270 const SelectionSet&
271 Selections() const;
272 bool Selected(iterator it) const;
273 Clr InteriorColor() const;
274 Clr HiliteColor() const;
275
277 Flags<ListBoxStyle> Style() const;
278
279 const Row& ColHeaders() const;
280 iterator FirstRowShown() const;
281 std::size_t FirstColShown() const;
282
283 iterator LastVisibleRow() const;
284 std::size_t LastVisibleCol() const;
285
286 std::size_t NumRows() const;
287 std::size_t NumCols() const;
288
290 bool KeepColWidths() const;
291
295 std::size_t SortCol() const;
296
297 X ColWidth(std::size_t n) const;
298 Alignment ColAlignment(std::size_t n) const;
299 Alignment RowAlignment(iterator it) const;
300
304 const std::set<std::string>& AllowedDropTypes() const;
305
308 bool AutoScrollDuringDragDrops() const;
309
312 unsigned int AutoScrollMargin() const;
313
316 unsigned int AutoScrollInterval() const;
317
322 mutable ClearedSignalType ClearedSignal;
323
328 mutable InsertedSignalType InsertedSignal;
329
330 mutable SelChangedSignalType SelChangedSignal;
331 mutable DroppedSignalType DroppedSignal;
332 mutable DropAcceptableSignalType DropAcceptableSignal;
333 mutable LeftClickedSignalType LeftClickedSignal;
334 mutable RightClickedSignalType RightClickedSignal;
335 mutable DoubleClickedSignalType DoubleClickedSignal;
336 mutable ErasedSignalType ErasedSignal;
337 mutable BrowsedSignalType BrowsedSignal;
338
339
341 virtual void StartingChildDragDrop(const Wnd* wnd, const GG::Pt& offset);
342 virtual void AcceptDrops(const std::vector<Wnd*>& wnds, const Pt& pt);
343 virtual void ChildrenDraggedAway(const std::vector<Wnd*>& wnds, const Wnd* destination);
344 virtual void Render();
345
346 virtual void SizeMove(const Pt& ul, const Pt& lr);
347
348 virtual void Disable(bool b = true);
349 virtual void SetColor(Clr c);
350
354 iterator Insert(Row* row, iterator it);
355
359 iterator Insert(Row* row);
360
361 Row* Erase(iterator it);
362 void Clear();
363 void SelectRow(iterator it);
364 void DeselectRow(iterator it);
365 void SelectAll();
366 void DeselectAll();
367 iterator begin();
368 iterator end();
369 reverse_iterator
370 rbegin();
371 reverse_iterator
372 rend();
373 Row& GetRow(std::size_t n);
374
375 void SetSelections(const SelectionSet& s);
376 void SetCaret(iterator it);
377 void BringRowIntoView(iterator it);
378 void SetFirstRowShown(iterator it);
379
380 void SetInteriorColor(Clr c);
381 void SetHiliteColor(Clr c);
382
384 void SetStyle(Flags<ListBoxStyle> s);
385
386 void SetColHeaders(Row* r);
387 void RemoveColHeaders();
388
389 void SetColWidth(std::size_t n, X w);
390 void SetNumCols(std::size_t n);
391 void SetSortCol(std::size_t n);
392
397 void SetSortCmp(const boost::function<bool (const Row&, const Row&, std::size_t)>& sort_cmp);
398
403 void LockColWidths();
404
407 void UnLockColWidths();
408
410 void SetColAlignment(std::size_t n, Alignment align);
411
413 void SetRowAlignment(iterator it, Alignment align);
414
417 void AllowDropType(const std::string& str);
418
423 void DisallowDropType(const std::string& str);
424
428 void AutoScrollDuringDragDrops(bool auto_scroll);
429
433 void SetAutoScrollMargin(unsigned int margin);
434
437 void SetAutoScrollInterval(unsigned int interval);
439
445 template <class RowType>
446 struct DefaultRowCmp
447 {
449 bool operator()(const Row& lhs, const Row& rhs, std::size_t column) const;
450 };
451
452 static const unsigned int BORDER_THICK;
453
455
456 GG_ABSTRACT_EXCEPTION(Exception);
457
461 GG_CONCRETE_EXCEPTION(DontAcceptDrop, GG::ListBox, Exception);
463
464 protected:
466 ListBox();
467
468
470 X RightMargin() const;
471 Y BottomMargin() const;
472 unsigned int CellMargin() const;
473
474 iterator RowUnderPt(const Pt& pt) const;
475
476 iterator OldSelRow() const;
477 iterator OldRDownRow() const;
478 iterator LClickRow() const;
479 iterator RClickRow() const;
480
481 bool AutoScrollingUp() const;
482 bool AutoScrollingDown() const;
483 bool AutoScrollingLeft() const;
484 bool AutoScrollingRight() const;
485
486
488 virtual void KeyPress(Key key, boost::uint32_t key_code_point, Flags<ModKey> mod_keys);
489 virtual void MouseWheel(const Pt& pt, int move, Flags<ModKey> mod_keys);
490 virtual void DragDropEnter(const Pt& pt, const std::map<Wnd*, Pt>& drag_drop_wnds, Flags<ModKey> mod_keys);
491 virtual void DragDropHere(const Pt& pt, const std::map<Wnd*, Pt>& drag_drop_wnds, Flags<ModKey> mod_keys);
492 virtual void DragDropLeave();
493 virtual void TimerFiring(unsigned int ticks, Timer* timer);
494
495 virtual bool EventFilter(Wnd* w, const WndEvent& event);
496
497 iterator Insert(Row* row, iterator it, bool dropped);
498 Row* Erase(iterator it, bool removing_duplicate, bool signal);
499 void BringCaretIntoView();
500 void RecreateScrolls();
501 void ResetAutoScrollVars();
502 void Resort();
503
504
505 private:
506 void ConnectSignals();
507 void ValidateStyle();
508 void AdjustScrolls(bool adjust_for_resize);
509 void VScrolled(int tab_low, int tab_high, int low, int high);
510 void HScrolled(int tab_low, int tab_high, int low, int high);
511 void ClickAtRow(iterator it, Flags<ModKey> mod_keys);
512 void NormalizeRow(Row* row);
513 iterator FirstRowShownWhenBottomIs(iterator bottom_row, Y client_height);
514 std::size_t FirstColShownWhenRightIs(std::size_t right_col, X client_width);
515
516 std::list<Row*> m_rows;
517
518 Scroll* m_vscroll;
519 Scroll* m_hscroll;
520 iterator m_caret;
521 SelectionSet m_selections;
522 iterator m_old_sel_row;
523 bool m_old_sel_row_selected;
524 iterator m_old_rdown_row;
525 iterator m_lclick_row;
526 iterator m_rclick_row;
527 iterator m_last_row_browsed;
528
529 iterator m_first_row_shown;
530 std::size_t m_first_col_shown;
531 std::vector<X> m_col_widths;
532 std::vector<Alignment>
533 m_col_alignments;
534 unsigned int m_cell_margin;
535
536 Clr m_int_color;
537 Clr m_hilite_color;
538 Flags<ListBoxStyle>
539 m_style;
540
541 Row* m_header_row;
542 bool m_keep_col_widths;
543 bool m_clip_cells;
544 std::size_t m_sort_col;
545 boost::function<bool (const Row&, const Row&, std::size_t)>
546 m_sort_cmp;
547 std::set<std::string>
548 m_allowed_drop_types;
549
550 bool m_auto_scroll_during_drag_drops;
551 unsigned int m_auto_scroll_margin;
552 bool m_auto_scrolling_up;
553 bool m_auto_scrolling_down;
554 bool m_auto_scrolling_left;
555 bool m_auto_scrolling_right;
556 Timer m_auto_scroll_timer;
557
558 iterator* m_iterator_being_erased;
559
560 friend class DropDownList;
561 };
562
563 } // namespace GG
564
565
566 // template implementations
567 template <class Cont>
568 GG::ListBox::RowPtrIteratorLess<Cont>::RowPtrIteratorLess() :
569 m_container()
570 { assert(m_container); }
571
572 template <class Cont>
573 GG::ListBox::RowPtrIteratorLess<Cont>::RowPtrIteratorLess(Cont* c) :
574 m_container(c)
575 { assert(m_container); }
576
577 template <class Cont>
578 bool GG::ListBox::RowPtrIteratorLess<Cont>::operator()(Iter lhs, Iter rhs) const
579 {
580 // If you've seen an error message that lead you here, it is because you
581 // are attempting to use RowPtrIteratorLess to sort a type that is not
582 // iterators-to-pointers-to-ListBox::Rows!
583 BOOST_MPL_ASSERT((boost::is_same<typename Iter::value_type, ::GG::ListBox::Row*>));
584 return LessThan(lhs, rhs, m_container->end());
585 }
586
587 template <class Cont>
588 bool GG::ListBox::RowPtrIteratorLess<Cont>::LessThan(Iter lhs, Iter rhs, Iter end)
589 {
590 return lhs == end ?
591 false :
592 (rhs == end ?
593 true : (*lhs)->UpperLeft().y < (*rhs)->UpperLeft().y);
594 }
595
596 template <class RowType>
597 bool GG::ListBox::DefaultRowCmp<RowType>::operator()(const GG::ListBox::Row& lhs, const GG::ListBox::Row& rhs, std::size_t column) const
598 {
599 return static_cast<const RowType&>(lhs).SortKey(column) < static_cast<const RowType&>(rhs).SortKey(column);
600 }
601
602 #endif