5 The idea of `SwitcherDialog` is to make it easier to implement keyboard
6 navigation in AUI and other applications that have multiple panes and
9 A key combination with a modifier (such as ``Ctrl`` + ``Tab``) shows the
10 dialog, and the user holds down the modifier whilst navigating with
11 ``Tab`` and arrow keys before releasing the modifier to dismiss the dialog
12 and activate the selected pane.
14 The switcher dialog is a multi-column menu with no scrolling, implemented
15 by the `MultiColumnListCtrl` class. You can have headings for your items
16 for logical grouping, and you can force a column break if you need to.
18 The modifier used for invoking and dismissing the dialog can be customised,
19 as can the colours, number of rows, and the key used for cycling through
20 the items. So you can use different keys on different platforms if
21 required (especially since ``Ctrl`` + ``Tab`` is reserved on some platforms).
23 Items are shown as names and optional 16x16 images.
29 To use the dialog, you set up the items in a `SwitcherItems` object,
30 before passing this to the `SwitcherDialog` instance.
32 Call L{SwitcherItems.AddItem} and optionally L{SwitcherItems.AddGroup} to add items and headings. These
33 functions take a label (to be displayed to the user), an identifying name,
34 an integer id, and a bitmap. The name and id are purely for application-defined
35 identification. You may also set a description to be displayed when each
36 item is selected; and you can set a window pointer for convenience when
37 activating the desired window after the dialog returns.
39 Have created the dialog, you call `ShowModal()`, and if the return value is
40 ``wx.ID_OK``, retrieve the selection from the dialog and activate the pane.
42 The sample code below shows a generic method of finding panes and notebook
43 tabs within the current L{AuiManager}, and using the pane name or notebook
44 tab position to display the pane.
46 The only other code to add is a menu item with the desired accelerator,
47 whose modifier matches the one you pass to L{SwitcherDialog.SetModifierKey}
48 (the default being ``wx.WXK_CONTROL``).
56 if wx.Platform == "__WXMAC__":
57 switcherAccel = "Alt+Tab"
58 elif wx.Platform == "__WXGTK__":
59 switcherAccel = "Ctrl+/"
61 switcherAccel = "Ctrl+Tab"
63 view_menu.Append(ID_SwitchPane, _("S&witch Window...") + "\t" + switcherAccel)
68 def OnSwitchPane(self, event):
70 items = SwitcherItems()
73 # Add the main windows and toolbars, in two separate columns
74 # We'll use the item 'id' to store the notebook selection, or -1 if not a page
78 items.AddGroup(_("Main Windows"), "mainwindows")
80 items.AddGroup(_("Toolbars"), "toolbars").BreakColumn()
82 for pane in self._mgr.GetAllPanes():
84 caption = pane.caption
86 toolbar = isinstance(info.window, wx.ToolBar) or isinstance(info.window, aui.AuiToolBar)
87 if caption and (toolBar and k == 1) or (not toolBar and k == 0):
88 items.AddItem(caption, name, -1).SetWindow(pane.window)
90 # Now add the wxAuiNotebook pages
92 items.AddGroup(_("Notebook Pages"), "pages").BreakColumn()
94 for pane in self._mgr.GetAllPanes():
96 if isinstance(nb, aui.AuiNotebook):
97 for j in xrange(nb.GetPageCount()):
99 name = nb.GetPageText(j)
102 items.AddItem(name, name, j, nb.GetPageBitmap(j)).SetWindow(win)
104 # Select the focused window
106 idx = items.GetIndexForFocus()
107 if idx != wx.NOT_FOUND:
108 items.SetSelection(idx)
110 if wx.Platform == "__WXMAC__":
111 items.SetBackgroundColour(wx.WHITE)
113 # Show the switcher dialog
115 dlg = SwitcherDialog(items, wx.GetApp().GetTopWindow())
117 # In GTK+ we can't use Ctrl+Tab; we use Ctrl+/ instead and tell the switcher
118 # to treat / in the same was as tab (i.e. cycle through the names)
120 if wx.Platform == "__WXGTK__":
121 dlg.SetExtraNavigationKey(wxT('/'))
123 if wx.Platform == "__WXMAC__":
124 dlg.SetBackgroundColour(wx.WHITE)
125 dlg.SetModifierKey(wx.WXK_ALT)
127 ans = dlg.ShowModal()
129 if ans == wx.ID_OK and dlg.GetSelection() != -1:
130 item = items.GetItem(dlg.GetSelection())
132 if item.GetId() == -1:
133 info = self._mgr.GetPane(item.GetName())
136 info.window.SetFocus()
139 nb = item.GetWindow().GetParent()
140 win = item.GetWindow();
141 if isinstance(nb, aui.AuiNotebook):
142 nb.SetSelection(item.GetId())
151 from aui_utilities import FindFocusDescendant
152 from aui_constants import SWITCHER_TEXT_MARGIN_X, SWITCHER_TEXT_MARGIN_Y
155 # Define a translation function
156 _ = wx.GetTranslation
159 class SwitcherItem(object):
160 """ An object containing information about one item. """
162 def __init__(self, item=None):
163 """ Default class constructor. """
166 self._isGroup = False
167 self._breakColumn = False
171 self._description = ""
173 self._textColour = wx.NullColour
174 self._bitmap = wx.NullBitmap
175 self._font = wx.NullFont
181 def Copy(self, item):
183 Copy operator between 2 L{SwitcherItem} instances.
185 :param `item`: another instance of L{SwitcherItem}.
189 self._name = item._name
190 self._title = item._title
191 self._isGroup = item._isGroup
192 self._breakColumn = item._breakColumn
193 self._rect = item._rect
194 self._font = item._font
195 self._textColour = item._textColour
196 self._bitmap = item._bitmap
197 self._description = item._description
198 self._rowPos = item._rowPos
199 self._colPos = item._colPos
200 self._window = item._window
203 def SetTitle(self, title):
214 def SetName(self, name):
225 def SetDescription(self, descr):
227 self._description = descr
231 def GetDescription(self):
233 return self._description
247 def SetIsGroup(self, isGroup):
249 self._isGroup = isGroup
253 def GetIsGroup(self):
258 def BreakColumn(self, breakCol=True):
260 self._breakColumn = breakCol
264 def GetBreakColumn(self):
266 return self._breakColumn
269 def SetRect(self, rect):
280 def SetTextColour(self, colour):
282 self._textColour = colour
286 def GetTextColour(self):
288 return self._textColour
291 def SetFont(self, font):
302 def SetBitmap(self, bitmap):
304 self._bitmap = bitmap
313 def SetRowPos(self, pos):
324 def SetColPos(self, pos):
335 def SetWindow(self, win):
346 class SwitcherItems(object):
347 """ An object containing switcher items. """
349 def __init__(self, items=None):
350 """ Default class constructor. """
354 self._columnCount = 0
356 self._backgroundColour = wx.NullColour
357 self._textColour = wx.NullColour
358 self._selectionColour = wx.NullColour
359 self._selectionOutlineColour = wx.NullColour
360 self._itemFont = wx.NullFont
364 if wx.Platform == "__WXMSW__":
365 # If on Windows XP/Vista, use more appropriate colours
366 self.SetSelectionOutlineColour(wx.Colour(49, 106, 197))
367 self.SetSelectionColour(wx.Colour(193, 210, 238))
373 def Copy(self, items):
375 Copy operator between 2 L{SwitcherItems}.
377 :param `items`: another instance of L{SwitcherItems}.
382 for item in items._items:
383 self._items.append(item)
385 self._selection = items._selection
386 self._rowCount = items._rowCount
387 self._columnCount = items._columnCount
389 self._backgroundColour = items._backgroundColour
390 self._textColour = items._textColour
391 self._selectionColour = items._selectionColour
392 self._selectionOutlineColour = items._selectionOutlineColour
393 self._itemFont = items._itemFont
396 def AddItem(self, titleOrItem, name=None, id=0, bitmap=wx.NullBitmap):
398 if isinstance(titleOrItem, SwitcherItem):
399 self._items.append(titleOrItem)
400 return self._items[-1]
402 item = SwitcherItem()
403 item.SetTitle(titleOrItem)
406 item.SetBitmap(bitmap)
408 self._items.append(item)
409 return self._items[-1]
412 def AddGroup(self, title, name, id=0, bitmap=wx.NullBitmap):
414 item = self.AddItem(title, name, id, bitmap)
415 item.SetIsGroup(True)
425 def FindItemByName(self, name):
427 for i in xrange(len(self._items)):
428 if self._items[i].GetName() == name:
434 def FindItemById(self, id):
436 for i in xrange(len(self._items)):
437 if self._items[i].GetId() == id:
443 def SetSelection(self, sel):
445 self._selection = sel
448 def SetSelectionByName(self, name):
450 idx = self.FindItemByName(name)
451 if idx != wx.NOT_FOUND:
452 self.SetSelection(idx)
455 def GetSelection(self):
457 return self._selection
460 def GetItem(self, i):
462 return self._items[i]
465 def GetItemCount(self):
467 return len(self._items)
470 def SetRowCount(self, rows):
472 self._rowCount = rows
475 def GetRowCount(self):
477 return self._rowCount
480 def SetColumnCount(self, cols):
482 self._columnCount = cols
485 def GetColumnCount(self):
487 return self._columnCount
490 def SetBackgroundColour(self, colour):
492 self._backgroundColour = colour
495 def GetBackgroundColour(self):
497 return self._backgroundColour
500 def SetTextColour(self, colour):
502 self._textColour = colour
505 def GetTextColour(self):
507 return self._textColour
510 def SetSelectionColour(self, colour):
512 self._selectionColour = colour
515 def GetSelectionColour(self):
517 return self._selectionColour
520 def SetSelectionOutlineColour(self, colour):
522 self._selectionOutlineColour = colour
525 def GetSelectionOutlineColour(self):
527 return self._selectionOutlineColour
530 def SetItemFont(self, font):
532 self._itemFont = font
535 def GetItemFont(self):
537 return self._itemFont
540 def PaintItems(self, dc, win):
542 backgroundColour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_3DFACE)
543 standardTextColour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT)
544 selectionColour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHT)
545 selectionOutlineColour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT)
546 standardFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
547 groupFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
548 groupFont.SetWeight(wx.BOLD)
550 if self.GetBackgroundColour().IsOk():
551 backgroundColour = self.GetBackgroundColour()
553 if self.GetTextColour().IsOk():
554 standardTextColour = self.GetTextColour()
556 if self.GetSelectionColour().IsOk():
557 selectionColour = self.GetSelectionColour()
559 if self.GetSelectionOutlineColour().IsOk():
560 selectionOutlineColour = self.GetSelectionOutlineColour()
562 if self.GetItemFont().IsOk():
564 standardFont = self.GetItemFont()
565 groupFont = wx.Font(standardFont.GetPointSize(), standardFont.GetFamily(), standardFont.GetStyle(),
566 wx.BOLD, standardFont.GetUnderlined(), standardFont.GetFaceName())
568 textMarginX = SWITCHER_TEXT_MARGIN_X
570 dc.SetLogicalFunction(wx.COPY)
571 dc.SetBrush(wx.Brush(backgroundColour))
572 dc.SetPen(wx.TRANSPARENT_PEN)
573 dc.DrawRectangleRect(win.GetClientRect())
574 dc.SetBackgroundMode(wx.TRANSPARENT)
576 for i in xrange(len(self._items)):
577 item = self._items[i]
578 if i == self._selection:
579 dc.SetPen(wx.Pen(selectionOutlineColour))
580 dc.SetBrush(wx.Brush(selectionColour))
581 dc.DrawRectangleRect(item.GetRect())
583 clippingRect = wx.Rect(*item.GetRect())
584 clippingRect.Deflate(1, 1)
586 dc.SetClippingRect(clippingRect)
588 if item.GetTextColour().IsOk():
589 dc.SetTextForeground(item.GetTextColour())
591 dc.SetTextForeground(standardTextColour)
593 if item.GetFont().IsOk():
594 dc.SetFont(item.GetFont())
596 if item.GetIsGroup():
597 dc.SetFont(groupFont)
599 dc.SetFont(standardFont)
601 w, h = dc.GetTextExtent(item.GetTitle())
606 if not item.GetIsGroup():
607 if item.GetBitmap().IsOk() and item.GetBitmap().GetWidth() <= 16 \
608 and item.GetBitmap().GetHeight() <= 16:
610 dc.DrawBitmap(item.GetBitmap(), x, item.GetRect().y + \
611 (item.GetRect().height - item.GetBitmap().GetHeight())/2,
613 x += 16 + textMarginX
616 y = item.GetRect().y + (item.GetRect().height - h)/2
617 dc.DrawText(item.GetTitle(), x, y)
618 dc.DestroyClippingRegion()
621 def CalculateItemSize(self, dc):
623 # Start off allowing for an icon
624 sz = wx.Size(150, 16)
625 standardFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
626 groupFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
627 groupFont.SetWeight(wx.BOLD)
629 textMarginX = SWITCHER_TEXT_MARGIN_X
630 textMarginY = SWITCHER_TEXT_MARGIN_Y
634 if self.GetItemFont().IsOk():
635 standardFont = self.GetItemFont()
637 for item in self._items:
638 if item.GetFont().IsOk():
639 dc.SetFont(item.GetFont())
641 if item.GetIsGroup():
642 dc.SetFont(groupFont)
644 dc.SetFont(standardFont)
646 w, h = dc.GetTextExtent(item.GetTitle())
647 w += 16 + 2*textMarginX
650 sz.x = min(w, maxWidth)
652 sz.y = min(h, maxHeight)
654 if sz == wx.Size(16, 16):
655 sz = wx.Size(100, 25)
657 sz.x += textMarginX*2
658 sz.y += textMarginY*2
663 def GetIndexForFocus(self):
665 for i, item in enumerate(self._items):
668 if FindFocusDescendant(item.GetWindow()):
674 class MultiColumnListCtrl(wx.PyControl):
675 """ A control for displaying several columns (not scrollable). """
677 def __init__(self, parent, aui_manager, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize,
678 style=0, validator=wx.DefaultValidator, name="MultiColumnListCtrl"):
680 wx.PyControl.__init__(self, parent, id, pos, size, style, validator, name)
682 self._overallSize = wx.Size(200, 100)
683 self._modifierKey = wx.WXK_CONTROL
684 self._extraNavigationKey = 0
685 self._aui_manager = aui_manager
687 self.SetInitialSize(size)
688 self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
690 self.Bind(wx.EVT_PAINT, self.OnPaint)
691 self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
692 self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseEvent)
693 self.Bind(wx.EVT_CHAR, self.OnChar)
694 self.Bind(wx.EVT_KEY_DOWN, self.OnKey)
695 self.Bind(wx.EVT_KEY_UP, self.OnKey)
700 self._aui_manager.HideHint()
703 def DoGetBestSize(self):
705 return self._overallSize
708 def OnEraseBackground(self, event):
713 def OnPaint(self, event):
715 dc = wx.AutoBufferedPaintDC(self)
716 rect = self.GetClientRect()
718 if self._items.GetColumnCount() == 0:
719 self.CalculateLayout(dc)
721 if self._items.GetColumnCount() == 0:
724 self._items.PaintItems(dc, self)
727 def OnMouseEvent(self, event):
733 def OnChar(self, event):
738 def OnKey(self, event):
740 if event.GetEventType() == wx.wxEVT_KEY_UP:
741 if event.GetKeyCode() == self.GetModifierKey():
742 topLevel = wx.GetTopLevelParent(self)
743 closeEvent = wx.CloseEvent(wx.wxEVT_CLOSE_WINDOW, topLevel.GetId())
744 closeEvent.SetEventObject(topLevel)
745 closeEvent.SetCanVeto(False)
747 topLevel.GetEventHandler().ProcessEvent(closeEvent)
753 keyCode = event.GetKeyCode()
755 if keyCode in [wx.WXK_ESCAPE, wx.WXK_RETURN]:
756 if keyCode == wx.WXK_ESCAPE:
757 self._items.SetSelection(-1)
759 topLevel = wx.GetTopLevelParent(self)
760 closeEvent = wx.CloseEvent(wx.wxEVT_CLOSE_WINDOW, topLevel.GetId())
761 closeEvent.SetEventObject(topLevel)
762 closeEvent.SetCanVeto(False)
764 topLevel.GetEventHandler().ProcessEvent(closeEvent)
767 elif keyCode in [wx.WXK_TAB, self.GetExtraNavigationKey()]:
768 if event.ShiftDown():
770 self._items.SetSelection(self._items.GetSelection() - 1)
771 if self._items.GetSelection() < 0:
772 self._items.SetSelection(self._items.GetItemCount() - 1)
774 self.AdvanceToNextSelectableItem(-1)
778 self._items.SetSelection(self._items.GetSelection() + 1)
779 if self._items.GetSelection() >= self._items.GetItemCount():
780 self._items.SetSelection(0)
782 self.AdvanceToNextSelectableItem(1)
784 self.GenerateSelectionEvent()
787 elif keyCode in [wx.WXK_DOWN, wx.WXK_NUMPAD_DOWN]:
788 self._items.SetSelection(self._items.GetSelection() + 1)
789 if self._items.GetSelection() >= self._items.GetItemCount():
790 self._items.SetSelection(0)
792 self.AdvanceToNextSelectableItem(1)
793 self.GenerateSelectionEvent()
796 elif keyCode in [wx.WXK_UP, wx.WXK_NUMPAD_UP]:
797 self._items.SetSelection(self._items.GetSelection() - 1)
798 if self._items.GetSelection() < 0:
799 self._items.SetSelection(self._items.GetItemCount() - 1)
801 self.AdvanceToNextSelectableItem(-1)
802 self.GenerateSelectionEvent()
805 elif keyCode in [wx.WXK_HOME, wx.WXK_NUMPAD_HOME]:
806 self._items.SetSelection(0)
807 self.AdvanceToNextSelectableItem(1)
808 self.GenerateSelectionEvent()
811 elif keyCode in [wx.WXK_END, wx.WXK_NUMPAD_END]:
812 self._items.SetSelection(self._items.GetItemCount() - 1)
813 self.AdvanceToNextSelectableItem(-1)
814 self.GenerateSelectionEvent()
817 elif keyCode in [wx.WXK_LEFT, wx.WXK_NUMPAD_LEFT]:
818 item = self._items.GetItem(self._items.GetSelection())
820 row = item.GetRowPos()
821 newCol = item.GetColPos() - 1
823 newCol = self._items.GetColumnCount() - 1
825 # Find the first item from the end whose row matches and whose column is equal or lower
826 for i in xrange(self._items.GetItemCount()-1, -1, -1):
827 item2 = self._items.GetItem(i)
828 if item2.GetColPos() == newCol and item2.GetRowPos() <= row:
829 self._items.SetSelection(i)
832 self.AdvanceToNextSelectableItem(-1)
833 self.GenerateSelectionEvent()
836 elif keyCode in [wx.WXK_RIGHT, wx.WXK_NUMPAD_RIGHT]:
837 item = self._items.GetItem(self._items.GetSelection())
839 row = item.GetRowPos()
840 newCol = item.GetColPos() + 1
841 if newCol >= self._items.GetColumnCount():
844 # Find the first item from the end whose row matches and whose column is equal or lower
845 for i in xrange(self._items.GetItemCount()-1, -1, -1):
846 item2 = self._items.GetItem(i)
847 if item2.GetColPos() == newCol and item2.GetRowPos() <= row:
848 self._items.SetSelection(i)
851 self.AdvanceToNextSelectableItem(1)
852 self.GenerateSelectionEvent()
859 def AdvanceToNextSelectableItem(self, direction):
861 if self._items.GetItemCount() < 2:
864 if self._items.GetSelection() == -1:
865 self._items.SetSelection(0)
867 oldSel = self._items.GetSelection()
871 if self._items.GetItem(self._items.GetSelection()).GetIsGroup():
873 self._items.SetSelection(self._items.GetSelection() + direction)
874 if self._items.GetSelection() == -1:
875 self._items.SetSelection(self._items.GetItemCount()-1)
876 elif self._items.GetSelection() == self._items.GetItemCount():
877 self._items.SetSelection(0)
878 if self._items.GetSelection() == oldSel:
884 self.SetTransparency()
885 selection = self._items.GetItem(self._items.GetSelection()).GetWindow()
886 pane = self._aui_manager.GetPane(selection)
889 if isinstance(selection.GetParent(), auibook.AuiNotebook):
890 self.SetTransparency(selection)
891 self._aui_manager.ShowHint(selection.GetScreenRect())
892 wx.CallAfter(self.SetFocus)
896 self._aui_manager.HideHint()
898 if not pane.IsShown():
899 self._aui_manager.HideHint()
902 self.SetTransparency(selection)
903 self._aui_manager.ShowHint(selection.GetScreenRect())
904 # NOTE: this is odd but it is the only way for the focus to
905 # work correctly on wxMac...
906 wx.CallAfter(self.SetFocus)
910 def SetTransparency(self, selection=None):
912 if not self.GetParent().CanSetTransparent():
915 if selection is not None:
917 if selection.GetScreenRect().Intersects(self.GetParent().GetScreenRect()):
919 self.GetParent().SetTransparent(200)
922 self.GetParent().SetTransparent(255)
925 def GenerateSelectionEvent(self):
927 event = wx.CommandEvent(wx.wxEVT_COMMAND_LISTBOX_SELECTED, self.GetId())
928 event.SetEventObject(self)
929 event.SetInt(self._items.GetSelection())
930 self.GetEventHandler().ProcessEvent(event)
933 def CalculateLayout(self, dc=None):
936 dc = wx.ClientDC(self)
938 if self._items.GetSelection() == -1:
939 self._items.SetSelection(0)
943 # Spacing between edge of window or between columns
950 itemSize = self._items.CalculateItemSize(dc)
951 self._overallSize = wx.Size(350, 200)
962 oldOverallSize = self._overallSize
963 item = self._items.GetItem(i)
965 item.SetRect(wx.Rect(x, y, itemSize.x, itemSize.y))
966 item.SetColPos(columnCount-1)
967 item.SetRowPos(currentRow)
969 if item.GetRect().GetBottom() > self._overallSize.y:
970 self._overallSize.y = item.GetRect().GetBottom() + yMargin
972 if item.GetRect().GetRight() > self._overallSize.x:
973 self._overallSize.x = item.GetRect().GetRight() + xMargin
977 y += rowSpacing + itemSize.y
978 stopBreaking = breaking
980 if currentRow > self._items.GetRowCount() or (item.GetBreakColumn() and not breaking and currentRow != 1):
983 x += xMargin + itemSize.x
986 # Make sure we don't orphan a group
987 if item.GetIsGroup() or (item.GetBreakColumn() and not breaking):
988 self._overallSize = oldOverallSize
990 if item.GetBreakColumn():
993 # Repeat the last item, in the next column
1001 if i >= self._items.GetItemCount():
1004 self._items.SetColumnCount(columnCount)
1005 self.InvalidateBestSize()
1008 def SetItems(self, items):
1018 def SetExtraNavigationKey(self, keyCode):
1020 Set an extra key that can be used to cycle through items,
1021 in case not using the ``Ctrl`` + ``Tab`` combination.
1024 self._extraNavigationKey = keyCode
1027 def GetExtraNavigationKey(self):
1029 return self._extraNavigationKey
1032 def SetModifierKey(self, modifierKey):
1034 Set the modifier used to invoke the dialog, and therefore to test for
1038 self._modifierKey = modifierKey
1041 def GetModifierKey(self):
1043 return self._modifierKey
1047 class SwitcherDialog(wx.Dialog):
1049 SwitcherDialog shows a L{MultiColumnListCtrl} with a list of panes
1050 and tabs for the user to choose. ``Ctrl`` + ``Tab`` cycles through them.
1053 def __init__(self, items, parent, aui_manager, id=wx.ID_ANY, title=_("Pane Switcher"), pos=wx.DefaultPosition,
1054 size=wx.DefaultSize, style=wx.STAY_ON_TOP|wx.DIALOG_NO_PARENT|wx.BORDER_SIMPLE):
1055 """ Default class constructor. """
1057 self._switcherBorderStyle = (style & wx.BORDER_MASK)
1058 if self._switcherBorderStyle == wx.BORDER_NONE:
1059 self._switcherBorderStyle = wx.BORDER_SIMPLE
1061 style &= wx.BORDER_MASK
1062 style |= wx.BORDER_NONE
1064 wx.Dialog.__init__(self, parent, id, title, pos, size, style)
1066 self._listCtrl = MultiColumnListCtrl(self, aui_manager,
1067 style=wx.WANTS_CHARS|wx.NO_BORDER)
1068 self._listCtrl.SetItems(items)
1069 self._listCtrl.CalculateLayout()
1071 self._descriptionCtrl = wx.html.HtmlWindow(self, size=(-1, 100), style=wx.BORDER_NONE)
1072 self._descriptionCtrl.SetBackgroundColour(self.GetBackgroundColour())
1074 if wx.Platform == "__WXGTK__":
1076 self._descriptionCtrl.SetStandardFonts(fontSize)
1078 sizer = wx.BoxSizer(wx.VERTICAL)
1079 self.SetSizer(sizer)
1080 sizer.Add(self._listCtrl, 1, wx.ALL|wx.EXPAND, 10)
1081 sizer.Add(self._descriptionCtrl, 0, wx.ALL|wx.EXPAND, 10)
1082 sizer.SetSizeHints(self)
1084 self._listCtrl.SetFocus()
1086 self.Centre(wx.BOTH)
1088 if self._listCtrl.GetItems().GetSelection() == -1:
1089 self._listCtrl.GetItems().SetSelection(0)
1091 self._listCtrl.AdvanceToNextSelectableItem(1)
1093 self.ShowDescription(self._listCtrl.GetItems().GetSelection())
1095 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
1096 self.Bind(wx.EVT_ACTIVATE, self.OnActivate)
1097 self.Bind(wx.EVT_LISTBOX, self.OnSelectItem)
1098 self.Bind(wx.EVT_PAINT, self.OnPaint)
1101 self._closing = False
1102 if wx.Platform == "__WXMSW__":
1103 self._borderColour = wx.Colour(49, 106, 197)
1105 self._borderColour = wx.BLACK
1107 self._aui_manager = aui_manager
1110 def OnCloseWindow(self, event):
1116 self._closing = True
1118 if self.GetSelection() == -1:
1119 self.EndModal(wx.ID_CANCEL)
1121 self.EndModal(wx.ID_OK)
1123 self._aui_manager.HideHint()
1126 def GetSelection(self):
1128 return self._listCtrl.GetItems().GetSelection()
1131 def OnActivate(self, event):
1133 if not event.GetActive():
1134 if not self._closing:
1135 self._closing = True
1136 self.EndModal(wx.ID_CANCEL)
1139 def OnPaint(self, event):
1141 dc = wx.PaintDC(self)
1143 if self._switcherBorderStyle == wx.BORDER_SIMPLE:
1145 dc.SetPen(wx.Pen(self._borderColour))
1146 dc.SetBrush(wx.TRANSPARENT_BRUSH)
1148 rect = self.GetClientRect()
1149 dc.DrawRectangleRect(rect)
1151 # Draw border around the HTML control
1152 rect = wx.Rect(*self._descriptionCtrl.GetRect())
1154 dc.DrawRectangleRect(rect)
1157 def OnSelectItem(self, event):
1159 self.ShowDescription(event.GetSelection())
1162 # Convert a colour to a 6-digit hex string
1163 def ColourToHexString(self, col):
1165 hx = '%02x%02x%02x' % tuple([int(c) for c in col])
1169 def ShowDescription(self, i):
1171 item = self._listCtrl.GetItems().GetItem(i)
1172 colour = self._listCtrl.GetItems().GetBackgroundColour()
1174 if not colour.IsOk():
1175 colour = self.GetBackgroundColour()
1177 backgroundColourHex = self.ColourToHexString(colour)
1178 html = _("<body bgcolor=\"#") + backgroundColourHex + _("\"><b>") + item.GetTitle() + _("</b>")
1180 if item.GetDescription():
1182 html += item.GetDescription()
1184 html += _("</body>")
1185 self._descriptionCtrl.SetPage(html)
1188 def SetExtraNavigationKey(self, keyCode):
1190 self._extraNavigationKey = keyCode
1192 self._listCtrl.SetExtraNavigationKey(keyCode)
1195 def GetExtraNavigationKey(self):
1197 return self._extraNavigationKey
1200 def SetModifierKey(self, modifierKey):
1202 self._modifierKey = modifierKey
1204 self._listCtrl.SetModifierKey(modifierKey)
1207 def GetModifierKey(self):
1209 return self._modifierKey
1212 def SetBorderColour(self, colour):
1214 self._borderColour = colour