Code::Blocks  SVN r11506
switcherdlg.cpp
Go to the documentation of this file.
1 // Name: switcherdlg.h
3 // Purpose: Pane switcher dialog
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 2007-08-19
7 // RCS-ID: $Id: switcherdlg.cpp 11396 2018-05-05 13:52:23Z killerbot $
8 // Copyright: (c) Julian Smart
9 // Licence: wxWidgets licence
11 
12 #include <wx/wx.h>
13 
14 #include <wx/settings.h>
15 #include <wx/dcbuffer.h>
16 
17 #if defined(__WXMSW__) && wxUSE_UXTHEME
18 #include <wx/msw/uxtheme.h>
19 #endif
20 
21 #include "switcherdlg.h"
22 
23 #define wxSWITCHER_TEXT_MARGIN_X 4
24 #define wxSWITCHER_TEXT_MARGIN_Y 2
25 #define wxSWITCHER_USE_BUFFERED_PAINTING 1
26 
27 #include <wx/arrimpl.cpp>
28 
29 WX_DEFINE_OBJARRAY(wxSwitcherItemArray);
30 
35 IMPLEMENT_CLASS(wxSwitcherItem, wxObject)
36 
37 void wxSwitcherItem::Init()
38 {
39  m_id = 0;
40  m_isGroup = false;
41  m_breakColumn = false;
42  m_rowPos = 0;
43  m_colPos = 0;
44  m_window = NULL;
45 }
46 
48 {
49  m_id = item.m_id;
50  m_name = item.m_name;
51  m_title = item.m_title;
52  m_isGroup = item.m_isGroup;
54  m_rect = item.m_rect;
55  m_font = item.m_font;
57  m_bitmap = item.m_bitmap;
59  m_rowPos = item.m_rowPos;
60  m_colPos = item.m_colPos;
61  m_window = item.m_window;
62 }
63 
65 {
66  return (
67  m_id == item.m_id &&
68  m_name == item.m_name &&
69  m_title == item.m_title &&
70  m_description == item.m_description &&
71  m_isGroup == item.m_isGroup &&
72  m_breakColumn == item.m_breakColumn &&
73  m_rect == item.m_rect &&
74  m_font == item.m_font &&
75  m_textColour == item.m_textColour &&
76  m_colPos == item.m_colPos &&
77  m_rowPos == item.m_rowPos &&
78  m_window == item.m_window
79  );
80 }
81 
87 IMPLEMENT_CLASS(wxSwitcherItems, wxObject)
88 
89 bool wxSwitcherItems::operator== (const wxSwitcherItems& items) const
90 {
91  if (m_items.GetCount() != items.m_items.GetCount())
92  return false;
93 
94  if (m_selection != items.m_selection || m_rowCount != items.m_rowCount || m_columnCount != items.m_columnCount)
95  return false;
96 
97  if (m_backgroundColour != items.m_backgroundColour || m_textColour != items.m_textColour ||
98  m_selectionColour != items.m_selectionColour || m_selectionOutlineColour != items.m_selectionOutlineColour ||
99  m_selectionTextColour != items.m_selectionTextColour || m_itemFont != items.m_itemFont)
100  return false;
101 
102  size_t i;
103  for (i = 0; i < m_items.GetCount(); i++)
104  {
105  if (!(m_items[i] == items.m_items[i]))
106  return false;
107  }
108 
109  return true;
110 }
111 
113 {
114  m_selection = -1;
115  m_rowCount = 10;
116  m_columnCount = 0;
117 
118 #if defined(__WXMSW__) && wxUSE_UXTHEME &&!wxCHECK_VERSION(3, 1, 1)
119  // If on Windows XP/Vista, use more appropriate colours.
120  // Alatar: What for??? Why should we use fixed colours?
121  if (wxUxThemeEngine::GetIfActive())
122  {
123  SetSelectionOutlineColour(wxColour(49, 106, 197));
124  SetSelectionColour(wxColour(193,210, 238));
125  SetSelectionTextColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
126  }
127 #endif
128 }
129 
131 {
132  Clear();
133 
134  size_t i;
135  for (i = 0; i < items.m_items.GetCount(); i++)
136  {
137  m_items.Add(items.m_items[i]);
138  }
139 
140  m_selection = items.m_selection;
141  m_rowCount = items.m_rowCount;
142  m_columnCount = items.m_columnCount;
143 
144  m_backgroundColour = items.m_backgroundColour;
145  m_textColour = items.m_textColour;
146  m_selectionColour = items.m_selectionColour;
147  m_selectionOutlineColour = items.m_selectionOutlineColour;
148  m_selectionTextColour = items.m_selectionTextColour;
149  m_itemFont = items.m_itemFont;
150 }
151 
152 wxSwitcherItem& wxSwitcherItems::AddItem(const wxString& title, const wxString& name, int id, const wxBitmap& bitmap)
153 {
154  wxSwitcherItem item;
155  item.SetTitle(title);
156  item.SetName(name);
157  item.SetId(id);
158  item.SetBitmap(bitmap);
159 
160  return AddItem(item);
161 }
162 
163 wxSwitcherItem& wxSwitcherItems::AddItem(const wxString& title, const wxString& name, const wxString& descr, int id, const wxBitmap& bitmap)
164 {
165  wxSwitcherItem item;
166  item.SetTitle(title);
167  item.SetName(name);
168  item.SetDescription(descr);
169  item.SetId(id);
170  item.SetBitmap(bitmap);
171 
172  return AddItem(item);
173 }
174 
176 {
177  m_items.Add(item);
178  return m_items[GetItemCount() - 1];
179 }
180 
181 wxSwitcherItem& wxSwitcherItems::AddGroup(const wxString& title, const wxString& name, int id, const wxBitmap& bitmap)
182 {
183  wxSwitcherItem& item = AddItem(title, name, id, bitmap);
184  item.SetIsGroup(true);
185 
186  return item;
187 }
188 
190 {
191  m_items.Clear();
192 }
193 
195 {
196  size_t i;
197  for (i = 0; i < m_items.GetCount(); i++)
198  {
199  if (m_items[i].GetName() == name)
200  return i;
201  }
202 
203  return -1;
204 }
205 
207 {
208  size_t i;
209  for (i = 0; i < m_items.GetCount(); i++)
210  {
211  if (m_items[i].GetId() == id)
212  return i;
213  }
214 
215  return -1;
216 }
217 
219 {
220  m_selection = sel;
221 }
222 
224 {
225  int idx = FindItemByName(name);
226  if (idx != -1)
227  SetSelection(idx);
228 }
229 
231 {
232  return m_items[i];
233 }
234 
236 {
237  return m_items[i];
238 }
239 
241 {
249  groupFont.SetWeight(wxFONTWEIGHT_BOLD);
250 
251  if (GetBackgroundColour().Ok())
252  backgroundColour = GetBackgroundColour();
253 
254  if (GetTextColour().Ok())
255  standardTextColour = GetTextColour();
256 
257  if (GetSelectionColour().Ok())
258  selectionColour = GetSelectionColour();
259 
260  if (GetSelectionOutlineColour().Ok())
261  selectionOutlineColour = GetSelectionOutlineColour();
262 
263  if (GetSelectionTextColour().Ok())
264  selectionTextColour = GetSelectionTextColour();
265 
266  if (GetItemFont().Ok())
267  {
268  standardFont = GetItemFont();
269  groupFont = wxFont(standardFont.GetPointSize(), standardFont.GetFamily(), standardFont.GetStyle(),
270  wxFONTWEIGHT_BOLD, standardFont.GetUnderlined(), standardFont.GetFaceName());
271  }
272 
273  int textMarginX = wxSWITCHER_TEXT_MARGIN_X;
274 
275  dc.SetLogicalFunction(wxCOPY);
276  dc.SetBrush(wxBrush(backgroundColour));
277  dc.SetPen(*wxTRANSPARENT_PEN);
278  dc.DrawRectangle(win->GetClientRect());
279  dc.SetBackgroundMode(wxTRANSPARENT);
280 
281  size_t i;
282  for (i = 0; i < m_items.GetCount(); i++)
283  {
284  wxSwitcherItem& item = m_items[i];
285  bool selected = ((int) i == m_selection);
286 
287  if (selected)
288  {
289  dc.SetPen(wxPen(selectionOutlineColour));
290  dc.SetBrush(wxBrush(selectionColour));
291  dc.DrawRectangle(item.GetRect());
292  }
293 
294  wxRect clippingRect(item.GetRect());
295  clippingRect.Deflate(1, 1);
296 
297  dc.SetClippingRegion(clippingRect);
298 
299  if (selected)
300  dc.SetTextForeground(selectionTextColour);
301  else if (item.GetTextColour().Ok())
302  dc.SetTextForeground(item.GetTextColour());
303  else
304  dc.SetTextForeground(standardTextColour);
305 
306  if (item.GetFont().Ok())
307  dc.SetFont(item.GetFont());
308  else
309  {
310  if (item.GetIsGroup())
311  dc.SetFont(groupFont);
312  else
313  dc.SetFont(standardFont);
314  }
315 
316  int w, h;
317  dc.GetTextExtent(item.GetTitle(), & w, & h);
318 
319  int x = item.GetRect().x;
320 
321  x += textMarginX;
322 
323  if (!item.GetIsGroup())
324  {
325  if (item.GetBitmap().Ok() && item.GetBitmap().GetWidth() <= 16 && item.GetBitmap().GetHeight() <= 16)
326  {
327  dc.DrawBitmap(item.GetBitmap(), x, item.GetRect().y + (item.GetRect().height - item.GetBitmap().GetHeight()) / 2, true);
328  }
329 
330  x += 16;
331 
332  x += textMarginX;
333  }
334 
335  int y = item.GetRect().y + (item.GetRect().height - h)/2;
336  dc.DrawText(item.GetTitle(), x, y);
337 
338  dc.DestroyClippingRegion();
339  }
340 }
341 
343 {
344  // Start off allowing for an icon
345  wxSize sz(150, 16);
348  groupFont.SetWeight(wxFONTWEIGHT_BOLD);
349 
350  int textMarginX = wxSWITCHER_TEXT_MARGIN_X;
351  int textMarginY = wxSWITCHER_TEXT_MARGIN_Y;
352  int maxWidth = 300;
353  int maxHeight = 40;
354 
355  if (GetItemFont().Ok())
356  standardFont = GetItemFont();
357 
358  size_t i;
359  for (i = 0; i < m_items.GetCount(); i++)
360  {
361  wxSwitcherItem& item = m_items[i];
362 
363  if (item.GetFont().Ok())
364  dc.SetFont(item.GetFont());
365  else
366  {
367  if (item.GetIsGroup())
368  dc.SetFont(groupFont);
369  else
370  dc.SetFont(standardFont);
371  }
372 
373  int w, h;
374  dc.GetTextExtent(item.GetTitle(), & w, & h);
375 
376  w += 16 + 2*textMarginX;
377 
378  if (w > sz.x)
379  sz.x = wxMin(w, maxWidth);
380  if (h > sz.y)
381  sz.y = wxMin(h, maxHeight);
382  }
383 
384  if (sz == wxSize(16, 16))
385  sz = wxSize(100, 25);
386  else
387  {
388  sz.x += textMarginX*2;
389  sz.y += textMarginY*2;
390  }
391 
392  return sz;
393 }
394 
395 // Find the index for the item associated with the current focus
397 {
398  for (size_t i = 0; i < m_items.GetCount(); i++)
399  {
400  wxSwitcherItem& item = m_items[i];
401  if (item.GetWindow())
402  {
403  if (wxFindFocusDescendant(item.GetWindow()))
404  return i;
405  }
406  }
407 
408  return wxNOT_FOUND;
409 }
410 
411 // Hit test, returning an index or -1
412 int wxSwitcherItems::HitTest(const wxPoint& pt) const
413 {
414  for (size_t i = 0; i < m_items.GetCount(); i++)
415  {
416  wxSwitcherItem& item = m_items[i];
417  if ( !item.GetIsGroup() && item.GetRect().Contains(pt))
418  return (int) i;
419  }
420 
421  return wxNOT_FOUND;
422 }
423 
424 /*
425  * A control for displaying several columns (not scrollable)
426  */
427 
428 BEGIN_EVENT_TABLE(wxMultiColumnListCtrl, wxControl)
430  EVT_ERASE_BACKGROUND(wxMultiColumnListCtrl::OnEraseBackground)
431  EVT_MOUSE_EVENTS(wxMultiColumnListCtrl::OnMouseEvent)
433  EVT_KEY_DOWN(wxMultiColumnListCtrl::OnKey)
434  EVT_KEY_UP(wxMultiColumnListCtrl::OnKey)
435 END_EVENT_TABLE()
436 
437 IMPLEMENT_CLASS(wxMultiColumnListCtrl, wxControl)
438 
439 wxMultiColumnListCtrl::wxMultiColumnListCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
440 {
441  Init();
442 
443  Create(parent, id, pos, size, style);
444 }
445 
446 bool wxMultiColumnListCtrl::Create(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
447 {
448  wxControl::Create(parent, id, pos, size, style);
449 
450  SetInitialSize(size);
451 
452  return true;
453 }
454 
455 // Overrides
457 {
458  return m_overallSize;
459 }
460 
462 {
463  wxWindow* topLevel = GetParent();
464  while (topLevel && !topLevel->IsTopLevel())
465  topLevel = topLevel->GetParent();
466 
467  if (topLevel)
468  {
469  wxCloseEvent closeEvent(wxEVT_CLOSE_WINDOW, topLevel->GetId());
470  closeEvent.SetEventObject(topLevel);
471  closeEvent.SetCanVeto(false);
472 
473  topLevel->GetEventHandler()->ProcessEvent(closeEvent);
474  return;
475  }
476 }
477 
479 {
480  // Do nothing
481 }
482 
484 {
485 #if wxSWITCHER_USE_BUFFERED_PAINTING
486  wxBufferedPaintDC dc(this);
487 #else
488  wxPaintDC dc(this);
489 #endif
490 
491  if (m_items.GetColumnCount() == 0)
492  CalculateLayout(dc);
493 
494  if (m_items.GetColumnCount() == 0)
495  return;
496 
497  m_items.PaintItems(dc, this);
498 }
499 
501 {
502  if (event.GetEventType() == wxEVT_MOUSEWHEEL)
503  {
504  int dir = event.GetWheelRotation();
505 
506  if (dir > 0)
507  {
508  m_items.SetSelection(m_items.GetSelection() - 1);
509  if (m_items.GetSelection() < 0)
510  m_items.SetSelection(m_items.GetItemCount() - 1);
511 
512  AdvanceToNextSelectableItem(-1);
513  }
514  else if (dir < 0)
515  {
516  m_items.SetSelection(m_items.GetSelection() + 1);
517  if (m_items.GetSelection() >= m_items.GetItemCount())
518  m_items.SetSelection(0);
519 
520  AdvanceToNextSelectableItem(1);
521  }
522 
523  GenerateSelectionEvent();
524 
525  Refresh();
526  }
527  else if (event.GetButton() == wxMOUSE_BTN_NONE)
528  { // Mouse move
529  bool bCanSelectItem = true;
530  if (m_ptMouse.x != -2 && m_ptMouse.y != -2)
531  { // If ==-2 => Don't select item on mouse pointer : used when user select the window with keyboard
532  if (m_ptMouse.x != -1 && m_ptMouse.y != -1)
533  { // If ==-1 => The client already move the mouse, select the item under the mouse cursor
534  wxPoint ptCurrent = ClientToScreen(event.GetPosition());
535  if (abs(ptCurrent.x - m_ptMouse.x) >= 3 || abs(ptCurrent.y - m_ptMouse.y) >= 3)
536  { // the user has moved the mouse over a 3 pixels square
537  m_ptMouse.x = m_ptMouse.y = -1; // Accept to select an item
538  }
539  else
540  { // Select this item is not allowed for the moment, the user must move the mouse
541  bCanSelectItem = false;
542  }
543  }
544  if (bCanSelectItem)
545  {
546  int idx = m_items.HitTest(event.GetPosition());
547  if (idx != wxNOT_FOUND)
548  {
549  m_items.SetSelection(idx);
550  GenerateSelectionEvent();
551  Refresh();
552  }
553  }
554  }
555  }
556  else if (event.LeftDown())
557  {
558  m_ptMouse.x = m_ptMouse.y = -1; // Accept to select an item
559  SendCloseEvent();
560  SetFocus();
561  }
562 }
563 
565 {
566 }
567 
569 {
570  if (event.GetEventType() == wxEVT_KEY_UP)
571  {
572  if (event.GetKeyCode() == GetModifierKey())
573  {
574  // The window will close, don't select the item under mouse pointer
575  m_ptMouse.x = m_ptMouse.y = -2;
576  SendCloseEvent();
577  }
578  event.Skip();
579  return;
580  }
581 
582  if (event.GetKeyCode() == WXK_ESCAPE || event.GetKeyCode() == WXK_RETURN || event.GetKeyCode() == WXK_NUMPAD_ENTER)
583  {
584  // The window will close, don't select the item under mouse pointer
585  m_ptMouse.x = m_ptMouse.y = -2;
586 
587  if (event.GetKeyCode() == WXK_ESCAPE)
588  m_items.SetSelection(-1);
589 
590  SendCloseEvent();
591  }
592  else if (event.GetKeyCode() == WXK_TAB || event.GetKeyCode() == GetExtraNavigationKey())
593  {
594  if (event.ShiftDown())
595  {
596  m_items.SetSelection(m_items.GetSelection() - 1);
597  if (m_items.GetSelection() < 0)
598  m_items.SetSelection(m_items.GetItemCount() - 1);
599 
600  AdvanceToNextSelectableItem(-1);
601  }
602  else
603  {
604  m_items.SetSelection(m_items.GetSelection() + 1);
605  if (m_items.GetSelection() >= m_items.GetItemCount())
606  m_items.SetSelection(0);
607 
608  AdvanceToNextSelectableItem(1);
609  }
610 
611  GenerateSelectionEvent();
612 
613  Refresh();
614  }
615  else if (event.GetKeyCode() == WXK_DOWN || event.GetKeyCode() == WXK_NUMPAD_DOWN)
616  {
617  m_items.SetSelection(m_items.GetSelection() + 1);
618  if (m_items.GetSelection() >= m_items.GetItemCount())
619  m_items.SetSelection(0);
620 
621  AdvanceToNextSelectableItem(1);
622 
623  GenerateSelectionEvent();
624 
625  Refresh();
626  }
627  else if (event.GetKeyCode() == WXK_UP || event.GetKeyCode() == WXK_NUMPAD_UP)
628  {
629  m_items.SetSelection(m_items.GetSelection() - 1);
630  if (m_items.GetSelection() < 0)
631  m_items.SetSelection(m_items.GetItemCount() - 1);
632 
633  AdvanceToNextSelectableItem(-1);
634 
635  GenerateSelectionEvent();
636 
637  Refresh();
638  }
639  else if (event.GetKeyCode() == WXK_HOME || event.GetKeyCode() == WXK_NUMPAD_HOME)
640  {
641  m_items.SetSelection(0);
642 
643  AdvanceToNextSelectableItem(1);
644 
645  GenerateSelectionEvent();
646 
647  Refresh();
648  }
649  else if (event.GetKeyCode() == WXK_END || event.GetKeyCode() == WXK_NUMPAD_END)
650  {
651  m_items.SetSelection(m_items.GetItemCount() - 1);
652 
653  AdvanceToNextSelectableItem(-1);
654 
655  GenerateSelectionEvent();
656 
657  Refresh();
658  }
659  else if (event.GetKeyCode() == WXK_LEFT || event.GetKeyCode() == WXK_NUMPAD_LEFT)
660  {
661  wxSwitcherItem& item = m_items.GetItem(m_items.GetSelection());
662 
663  int row = item.GetRowPos();
664  int newCol = item.GetColPos() - 1;
665  if (newCol < 0)
666  newCol = (m_items.GetColumnCount() - 1);
667 
668  // Find the first item from the end whose row matches and whose column is equal or lower
669  int i;
670  for (i = m_items.GetItemCount()-1; i >= 0; i--)
671  {
672  wxSwitcherItem& item2 = m_items.GetItem(i);
673  if (item2.GetColPos() == newCol && item2.GetRowPos() <= row)
674  {
675  m_items.SetSelection(i);
676  break;
677  }
678  }
679 
680  AdvanceToNextSelectableItem(-1);
681 
682  GenerateSelectionEvent();
683 
684  Refresh();
685  }
686  else if (event.GetKeyCode() == WXK_RIGHT || event.GetKeyCode() == WXK_NUMPAD_RIGHT)
687  {
688  wxSwitcherItem& item = m_items.GetItem(m_items.GetSelection());
689 
690  int row = item.GetRowPos();
691  int newCol = item.GetColPos() + 1;
692  if (newCol >= m_items.GetColumnCount())
693  newCol = 0;
694 
695  // Find the first item from the end whose row matches and whose column is equal or lower
696  int i;
697  for (i = m_items.GetItemCount()-1; i >= 0; i--)
698  {
699  wxSwitcherItem& item2 = m_items.GetItem(i);
700  if (item2.GetColPos() == newCol && item2.GetRowPos() <= row)
701  {
702  m_items.SetSelection(i);
703  break;
704  }
705  }
706 
707  AdvanceToNextSelectableItem(1);
708 
709  GenerateSelectionEvent();
710 
711  Refresh();
712  }
713  else
714  event.Skip();
715 }
716 
717 // Advance to the next selectable item
719 {
720  if (m_items.GetItemCount() < 2)
721  return;
722 
723  if (m_items.GetSelection() == -1)
724  m_items.SetSelection(0);
725 
726  int oldSel = m_items.GetSelection();
727 
728  while (true)
729  {
730  if (m_items.GetItem(m_items.GetSelection()).GetIsGroup())
731  {
732  m_items.SetSelection(m_items.GetSelection() + direction);
733  if (m_items.GetSelection() == -1)
734  m_items.SetSelection(m_items.GetItemCount()-1);
735  else if (m_items.GetSelection() == m_items.GetItemCount())
736  m_items.SetSelection(0);
737 
738  if (m_items.GetSelection() == oldSel)
739  break;
740  }
741  else
742  break;
743  }
744 }
745 
746 
748 {
749  wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, GetId());
750  event.SetEventObject(this);
751  event.SetInt(m_items.GetSelection());
752 
753  GetEventHandler()->ProcessEvent(event);
754 }
755 
757 {
758  wxClientDC dc(this);
759  CalculateLayout(dc);
760 }
761 
763 {
764  if (m_items.GetSelection() == -1)
765  m_items.SetSelection(0);
766 
767  int columnCount = 1;
768 
769  // Spacing between edge of window or between columns
770  int xMargin = 4;
771  int yMargin = 4;
772 
773  // Inter-row spacing
774  int rowSpacing = 2;
775 
776  wxSize itemSize = m_items.CalculateItemSize(dc);
777  m_overallSize = wxSize(350, 200);
778 
779  size_t i;
780  int currentRow = 0;
781  int x = xMargin;
782  int y = yMargin;
783 
784  bool breaking = false;
785 
786  for (i = 0; i < (size_t) m_items.GetItemCount(); i++)
787  {
788  wxSize oldOverallSize = m_overallSize;
789 
790  m_items.GetItem(i).SetRect(wxRect(x, y, itemSize.x, itemSize.y));
791  m_items.GetItem(i).SetColPos(columnCount-1);
792  m_items.GetItem(i).SetRowPos(currentRow);
793 
794  if (m_items.GetItem(i).GetRect().GetBottom() > m_overallSize.y)
795  m_overallSize.y = m_items.GetItem(i).GetRect().GetBottom() + yMargin;
796 
797  if (m_items.GetItem(i).GetRect().GetRight() > m_overallSize.x)
798  m_overallSize.x = m_items.GetItem(i).GetRect().GetRight() + xMargin;
799 
800  currentRow ++;
801 
802  y += (rowSpacing + itemSize.y);
803 
804  bool stopBreaking = breaking;
805 
806  if ((currentRow > m_items.GetRowCount()) || (m_items.GetItem(i).GetBreakColumn() && !breaking && (currentRow != 1)))
807  {
808  currentRow = 0;
809  columnCount ++;
810  x += (xMargin + itemSize.x);
811  y = yMargin;
812 
813  // Make sure we don't orphan a group
814  if (m_items.GetItem(i).GetIsGroup() || (m_items.GetItem(i).GetBreakColumn() && !breaking))
815  {
816  m_overallSize = oldOverallSize;
817 
818  if (m_items.GetItem(i).GetBreakColumn())
819  breaking = true;
820 
821  // Repeat the last item, in the next column
822  i --;
823  }
824  }
825 
826  if (stopBreaking)
827  breaking = false;
828  }
829 
830  m_items.SetColumnCount(columnCount);
831 
832  InvalidateBestSize();
833 }
834 
836 {
837  m_overallSize = wxSize(200, 100);
838  m_modifierKey = WXK_CONTROL;
839  m_extraNavigationKey = 0;
840  m_ptMouse = wxGetMousePosition();
841 }
842 
848 BEGIN_EVENT_TABLE(wxSwitcherDialog, wxScrollingDialog)
850  EVT_ACTIVATE(wxSwitcherDialog::OnActivate)
852  EVT_PAINT(wxSwitcherDialog::OnPaint)
853 END_EVENT_TABLE()
854 
856  const wxString& title, const wxPoint &position, const wxSize& size, long style )
857 {
858  Init();
859 
860  Create(items, parent, id, title, position, size, style);
861 }
862 
864  const wxString& title, const wxPoint &position, const wxSize& size, long style )
865 {
866  m_switcherBorderStyle = (style & wxBORDER_MASK);
867  if (m_switcherBorderStyle == wxBORDER_NONE)
868  m_switcherBorderStyle = wxBORDER_SIMPLE;
869 
870  style &= wxBORDER_MASK;
871  style |= wxBORDER_NONE;
872 
873  wxScrollingDialog::Create( parent, id, title, position, size, style );
874 
875  m_listCtrl = new wxMultiColumnListCtrl();
876  m_listCtrl->SetItems(items);
878  m_listCtrl->CalculateLayout();
879 
880  if (m_extraNavigationKey != -1)
881  m_listCtrl->SetExtraNavigationKey(m_extraNavigationKey);
882 
883  if (m_modifierKey != -1)
884  m_listCtrl->SetModifierKey(m_modifierKey);
885 
886  int borderStyle = wxSIMPLE_BORDER;
887  borderStyle = wxBORDER_NONE;
888 
889  m_descriptionCtrl = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 100), borderStyle);
890  m_descriptionCtrl->SetHTMLBackgroundColour(GetBackgroundColour());
891 
892 #ifdef __WXGTK20__
893  int fontSize = 11;
894  m_descriptionCtrl->SetStandardFonts(fontSize);
895 #endif
896 
897  wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
898  SetSizer(sizer);
899 
900  sizer->Add(m_listCtrl, 1, wxALL|wxEXPAND, 10);
901  sizer->Add(m_descriptionCtrl, 0, wxALL|wxEXPAND, 10);
902 
903  sizer->SetSizeHints(this);
904 
905  m_listCtrl->SetFocus();
906 
907  Centre(wxBOTH);
908 
909  if (m_listCtrl->GetItems().GetSelection() == -1)
910  m_listCtrl->GetItems().SetSelection(0);
911 
912  m_listCtrl->AdvanceToNextSelectableItem(1);
913 
914  ShowDescription(m_listCtrl->GetItems().GetSelection());
915 
916  return true;
917 }
918 
920 {
921  m_listCtrl = NULL;
922  m_descriptionCtrl = NULL;
923  m_closing = false;
924  m_switcherBorderStyle = 0;
925 
926  m_modifierKey = -1;
927  m_extraNavigationKey = -1;
928 
929 #if defined(__WXMSW__) && wxUSE_UXTHEME &&!wxCHECK_VERSION(3, 1, 1)
930  if (wxUxThemeEngine::GetIfActive())
931  m_borderColour = wxColour(49, 106, 197);
932  else
933 #endif
934  m_borderColour = *wxBLACK;
935 }
936 
938 {
939  if (m_closing)
940  return;
941 
942  if (IsModal())
943  {
944  m_closing = true;
945 
946  if (GetSelection() == -1)
948  else
949  EndModal(wxID_OK);
950  }
951 }
952 
953 // Get the selected item
955 {
956  return m_listCtrl->GetItems().GetSelection();
957 }
958 
960 {
961  if (!event.GetActive())
962  {
963  if (!m_closing)
964  {
965  m_closing = true;
967  }
968  }
969 }
970 
972 {
973  wxPaintDC dc(this);
974 
975  if (m_switcherBorderStyle == wxBORDER_SIMPLE)
976  {
977  dc.SetPen(wxPen(m_borderColour));
978  dc.SetBrush(*wxTRANSPARENT_BRUSH);
979 
980  wxRect rect(GetClientRect());
981  dc.DrawRectangle(rect);
982 
983  // Draw border around the HTML control
984  rect = m_descriptionCtrl->GetRect();
985  rect.Inflate(1,1);
986  dc.DrawRectangle(rect);
987  }
988 }
989 
991 {
992  ShowDescription(event.GetSelection());
993 }
994 
995 // Convert a colour to a 6-digit hex string
997 {
998  wxString hex;
999 
1000  hex += wxDecToHex(col.Red());
1001  hex += wxDecToHex(col.Green());
1002  hex += wxDecToHex(col.Blue());
1003 
1004  return hex;
1005 }
1006 
1007 
1009 {
1010  wxSwitcherItem& item = m_listCtrl->GetItems().GetItem(i);
1011 
1012  wxColour colour = m_listCtrl->GetItems().GetBackgroundColour();
1013  if (!colour.Ok())
1014  colour = GetBackgroundColour();
1015 
1016  wxString backgroundColourHex = ColourToHexString(colour);
1017 
1018  wxString html = wxT("<body bgcolor=\"#") + backgroundColourHex + wxT("\"><b>") + item.GetTitle() + wxT("</b>");
1019 
1020  if (!item.GetDescription().IsEmpty())
1021  {
1022  html += wxT("<p>");
1023  html += item.GetDescription();
1024  }
1025 
1026  html += wxT("</body>");
1027 
1028  m_descriptionCtrl->SetPage(html);
1029 }
1030 
1032 {
1033  m_extraNavigationKey = keyCode;
1034  if (m_listCtrl)
1035  m_listCtrl->SetExtraNavigationKey(keyCode);
1036 }
1037 
1039 {
1040  m_modifierKey = modifierKey;
1041  if (m_listCtrl)
1042  m_listCtrl->SetModifierKey(modifierKey);
1043 }
const wxString & GetDescription() const
Definition: switcherdlg.h:51
WX_DEFINE_OBJARRAY(wxSwitcherItemArray)
wxPoint wxGetMousePosition()
void EndModal(int retCode)
Definition: sc_dialog.cpp:112
void AdvanceToNextSelectableItem(int direction)
int GetKeyCode() const
wxBrush * wxTRANSPARENT_BRUSH
virtual bool GetUnderlined() const
wxColour * wxBLACK
const wxRect & GetRect() const
Definition: switcherdlg.h:63
int HitTest(const wxPoint &pt) const
wxWindow * GetWindow() const
Definition: switcherdlg.h:81
wxEventType wxEVT_KEY_UP
wxColour m_selectionOutlineColour
Definition: switcherdlg.h:192
wxWindow * m_window
Definition: switcherdlg.h:97
wxSwitcherItem & SetName(const wxString &name)
Definition: switcherdlg.h:47
void Copy(const wxSwitcherItem &item)
Definition: switcherdlg.cpp:47
const wxFont & GetFont() const
Definition: switcherdlg.h:69
static wxFont GetFont(wxSystemFont index)
void OnEraseBackground(wxEraseEvent &event)
const wxBitmap & GetBitmap() const
Definition: switcherdlg.h:72
wxSwitcherItem & SetTitle(const wxString &title)
Definition: switcherdlg.h:44
virtual wxSize DoGetBestSize() const
wxColour m_selectionColour
Definition: switcherdlg.h:191
#define wxSWITCHER_TEXT_MARGIN_X
Definition: switcherdlg.cpp:23
virtual unsigned char Red() const
int GetIndexForFocus() const
const wxSwitcherItem & GetItem(int i) const
int GetRowPos() const
Definition: switcherdlg.h:75
int FindItemByName(const wxString &name) const
virtual void SetWeight(wxFontWeight weight)
void SetExtraNavigationKey(int keyCode)
wxSwitcherItemArray m_items
Definition: switcherdlg.h:184
wxSwitcherItem & AddGroup(const wxString &title, const wxString &name, int id=0, const wxBitmap &bitmap=wxNullBitmap)
int GetButton() const
const wxString & GetTitle() const
Definition: switcherdlg.h:45
wxColour m_backgroundColour
Definition: switcherdlg.h:189
wxEventType wxEVT_MOUSEWHEEL
#define wxT(string)
wxSwitcherItem & SetDescription(const wxString &descr)
Definition: switcherdlg.h:50
#define wxNOT_FOUND
#define wxSWITCHER_TEXT_MARGIN_Y
Definition: switcherdlg.cpp:24
wxPoint GetPosition() const
int FindItemById(int id) const
wxString m_title
Definition: switcherdlg.h:85
bool LeftDown() const
#define wxWANTS_CHARS
wxBitmap m_bitmap
Definition: switcherdlg.h:92
bool operator==(const wxSwitcherItem &item) const
Definition: switcherdlg.cpp:64
void ShowDescription(int i)
virtual wxFontStyle GetStyle() const
wxString m_description
Definition: switcherdlg.h:87
bool Contains(int x, int y) const
void OnKey(wxKeyEvent &event)
int GetId() const
Definition: switcherdlg.h:54
wxColour m_selectionTextColour
Definition: switcherdlg.h:193
void OnPaint(wxPaintEvent &event)
bool Create(const wxSwitcherItems &items, wxWindow *parent, wxWindowID id=-1, const wxString &title=_("Pane Switcher"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxSTAY_ON_TOP|wxDIALOG_NO_PARENT|wxBORDER_SIMPLE)
virtual int GetWidth() const
wxColour m_textColour
Definition: switcherdlg.h:190
wxSwitcherItem & SetBitmap(const wxBitmap &bitmap)
Definition: switcherdlg.h:71
virtual unsigned char Green() const
const wxSize wxDefaultSize
wxSwitcherItem & AddItem(const wxString &title, const wxString &name, int id=0, const wxBitmap &bitmap=wxNullBitmap)
const wxPoint wxDefaultPosition
virtual wxFontFamily GetFamily() const
static wxColour GetColour(wxSystemColour index)
void OnActivate(wxActivateEvent &event)
virtual unsigned char Blue() const
bool Create(wxWindow *parent, wxWindowID id, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=0)
wxColour m_textColour
Definition: switcherdlg.h:93
void OnSelectItem(wxCommandEvent &event)
wxEventType wxEVT_CLOSE_WINDOW
static wxString ColourToHexString(const wxColour &col)
wxRect & Deflate(wxCoord dx, wxCoord dy)
wxSize CalculateItemSize(wxDC &dc)
wxSwitcherItem & SetId(int id)
Definition: switcherdlg.h:53
wxString m_name
Definition: switcherdlg.h:86
#define wxSIMPLE_BORDER
void OnPaint(wxPaintEvent &event)
bool IsEmpty() const
bool GetActive() const
bool GetIsGroup() const
Definition: switcherdlg.h:57
#define wxNO_BORDER
bool m_breakColumn
Definition: switcherdlg.h:90
virtual int GetHeight() const
wxRect & Inflate(wxCoord dx, wxCoord dy)
virtual int GetPointSize() const
void OnCloseWindow(wxCloseEvent &event)
void SetCanVeto(bool canVeto)
const wxColour & GetTextColour() const
Definition: switcherdlg.h:66
int height
void SetModifierKey(int modifierKey)
virtual wxString GetFaceName() const
bool ShiftDown() const
void Copy(const wxSwitcherItems &items)
int GetColPos() const
Definition: switcherdlg.h:78
wxPen * wxTRANSPARENT_PEN
int GetSelection() const
void SetSelection(int sel)
#define NULL
Definition: prefix.cpp:59
int wxWindowID
const wxString & GetName() const
Definition: switcherdlg.h:48
void OnChar(wxKeyEvent &event)
void OnMouseEvent(wxMouseEvent &event)
void PaintItems(wxDC &dc, wxWindow *win)
wxSwitcherItem & SetIsGroup(bool isGroup)
Definition: switcherdlg.h:56