GG
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>
113  {
114  typedef typename Cont::iterator Iter;
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 
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 
323 
329 
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>
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;
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>
569  m_container()
570 { assert(m_container); }
571 
572 template <class Cont>
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