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 
379  void SetInteriorColor(Clr c);
380  void SetHiliteColor(Clr c);
381 
383  void SetStyle(Flags<ListBoxStyle> s);
384 
385  void SetColHeaders(Row* r);
386  void RemoveColHeaders();
387 
388  void SetColWidth(std::size_t n, X w);
389  void SetNumCols(std::size_t n);
390  void SetSortCol(std::size_t n);
391 
396  void SetSortCmp(const boost::function<bool (const Row&, const Row&, std::size_t)>& sort_cmp);
397 
402  void LockColWidths();
403 
406  void UnLockColWidths();
407 
409  void SetColAlignment(std::size_t n, Alignment align);
410 
412  void SetRowAlignment(iterator it, Alignment align);
413 
416  void AllowDropType(const std::string& str);
417 
422  void DisallowDropType(const std::string& str);
423 
427  void AutoScrollDuringDragDrops(bool auto_scroll);
428 
432  void SetAutoScrollMargin(unsigned int margin);
433 
436  void SetAutoScrollInterval(unsigned int interval);
438 
444  template <class RowType>
446  {
448  bool operator()(const Row& lhs, const Row& rhs, std::size_t column) const;
449  };
450 
451  static const unsigned int BORDER_THICK;
452 
454 
455  GG_ABSTRACT_EXCEPTION(Exception);
456 
460  GG_CONCRETE_EXCEPTION(DontAcceptDrop, GG::ListBox, Exception);
462 
463 protected:
465  ListBox();
466 
467 
469  X RightMargin() const;
470  Y BottomMargin() const;
471  unsigned int CellMargin() const;
472 
473  iterator RowUnderPt(const Pt& pt) const;
474 
475  iterator OldSelRow() const;
476  iterator OldRDownRow() const;
477  iterator LClickRow() const;
478  iterator RClickRow() const;
479 
480  bool AutoScrollingUp() const;
481  bool AutoScrollingDown() const;
482  bool AutoScrollingLeft() const;
483  bool AutoScrollingRight() const;
484 
485 
487  virtual void KeyPress(Key key, boost::uint32_t key_code_point, Flags<ModKey> mod_keys);
488  virtual void MouseWheel(const Pt& pt, int move, Flags<ModKey> mod_keys);
489  virtual void DragDropEnter(const Pt& pt, const std::map<Wnd*, Pt>& drag_drop_wnds, Flags<ModKey> mod_keys);
490  virtual void DragDropHere(const Pt& pt, const std::map<Wnd*, Pt>& drag_drop_wnds, Flags<ModKey> mod_keys);
491  virtual void DragDropLeave();
492  virtual void TimerFiring(unsigned int ticks, Timer* timer);
493 
494  virtual bool EventFilter(Wnd* w, const WndEvent& event);
495 
496  iterator Insert(Row* row, iterator it, bool dropped);
497  Row* Erase(iterator it, bool removing_duplicate, bool signal);
498  void BringCaretIntoView();
499  void RecreateScrolls();
500  void ResetAutoScrollVars();
501  void Resort();
502 
503 
504 private:
505  void ConnectSignals();
506  void ValidateStyle();
507  void AdjustScrolls(bool adjust_for_resize);
508  void VScrolled(int tab_low, int tab_high, int low, int high);
509  void HScrolled(int tab_low, int tab_high, int low, int high);
510  void ClickAtRow(iterator it, Flags<ModKey> mod_keys);
511  void NormalizeRow(Row* row);
512  iterator FirstRowShownWhenBottomIs(iterator bottom_row, Y client_height);
513  std::size_t FirstColShownWhenRightIs(std::size_t right_col, X client_width);
514 
515  std::list<Row*> m_rows;
516 
517  Scroll* m_vscroll;
518  Scroll* m_hscroll;
519  iterator m_caret;
520  SelectionSet m_selections;
521  iterator m_old_sel_row;
522  bool m_old_sel_row_selected;
523  iterator m_old_rdown_row;
524  iterator m_lclick_row;
525  iterator m_rclick_row;
526  iterator m_last_row_browsed;
527 
528  iterator m_first_row_shown;
529  std::size_t m_first_col_shown;
530  std::vector<X> m_col_widths;
531  std::vector<Alignment>
532  m_col_alignments;
533  unsigned int m_cell_margin;
534 
535  Clr m_int_color;
536  Clr m_hilite_color;
538  m_style;
539 
540  Row* m_header_row;
541  bool m_keep_col_widths;
542  bool m_clip_cells;
543  std::size_t m_sort_col;
544  boost::function<bool (const Row&, const Row&, std::size_t)>
545  m_sort_cmp;
546  std::set<std::string>
547  m_allowed_drop_types;
548 
549  bool m_auto_scroll_during_drag_drops;
550  unsigned int m_auto_scroll_margin;
551  bool m_auto_scrolling_up;
552  bool m_auto_scrolling_down;
553  bool m_auto_scrolling_left;
554  bool m_auto_scrolling_right;
555  Timer m_auto_scroll_timer;
556 
557  iterator* m_iterator_being_erased;
558 
559  friend class DropDownList;
560 };
561 
562 } // namespace GG
563 
564 
565 // template implementations
566 template <class Cont>
568  m_container()
569 { assert(m_container); }
570 
571 template <class Cont>
573  m_container(c)
574 { assert(m_container); }
575 
576 template <class Cont>
577 bool GG::ListBox::RowPtrIteratorLess<Cont>::operator()(Iter lhs, Iter rhs) const
578 {
579  // If you've seen an error message that lead you here, it is because you
580  // are attempting to use RowPtrIteratorLess to sort a type that is not
581  // iterators-to-pointers-to-ListBox::Rows!
582  BOOST_MPL_ASSERT((boost::is_same<typename Iter::value_type, ::GG::ListBox::Row*>));
583  return LessThan(lhs, rhs, m_container->end());
584 }
585 
586 template <class Cont>
587 bool GG::ListBox::RowPtrIteratorLess<Cont>::LessThan(Iter lhs, Iter rhs, Iter end)
588 {
589  return lhs == end ?
590  false :
591  (rhs == end ?
592  true : (*lhs)->UpperLeft().y < (*rhs)->UpperLeft().y);
593 }
594 
595 template <class RowType>
596 bool GG::ListBox::DefaultRowCmp<RowType>::operator()(const GG::ListBox::Row& lhs, const GG::ListBox::Row& rhs, std::size_t column) const
597 {
598  return static_cast<const RowType&>(lhs).SortKey(column) < static_cast<const RowType&>(rhs).SortKey(column);
599 }
600 
601 #endif