summaryrefslogtreecommitdiff
path: root/lib/gui/subtitle_combo_box.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gui/subtitle_combo_box.py')
-rw-r--r--lib/gui/subtitle_combo_box.py85
1 files changed, 85 insertions, 0 deletions
diff --git a/lib/gui/subtitle_combo_box.py b/lib/gui/subtitle_combo_box.py
new file mode 100644
index 00000000..64c42153
--- /dev/null
+++ b/lib/gui/subtitle_combo_box.py
@@ -0,0 +1,85 @@
+import wx
+import wx.adv
+from wx.lib.wordwrap import wordwrap
+
+
+class SubtitleComboBox(wx.adv.OwnerDrawnComboBox):
+ TITLE_FONT_SIZE = 12
+ SUBTITLE_FONT_SIZE = 10
+
+ # I'd love to make this 12 too, but if I do it seems to get drawn as 10
+ # initially no matter what I do.
+ CONTROL_FONT_SIZE = 12
+
+ MARGIN = 5
+
+ def __init__(self, *args, **kwargs):
+ self.titles = kwargs.get('choices', [])
+ subtitles = kwargs.pop('subtitles', {})
+ self.subtitles = [subtitles.get(title, '') for title in self.titles]
+ wx.adv.OwnerDrawnComboBox.__init__(self, *args, **kwargs)
+
+ self.control_font = wx.Font(pointSize=self.CONTROL_FONT_SIZE, family=wx.DEFAULT, style=wx.NORMAL, weight=wx.NORMAL)
+ self.title_font = wx.Font(pointSize=self.TITLE_FONT_SIZE, family=wx.DEFAULT, style=wx.NORMAL, weight=wx.NORMAL)
+ self.subtitle_font = wx.Font(pointSize=self.SUBTITLE_FONT_SIZE, family=wx.DEFAULT, style=wx.NORMAL, weight=wx.NORMAL)
+
+ def OnMeasureItemWidth(self, item):
+ # This _should_ allow us to set the width of the combobox to match the
+ # width of the widest title. In reality, this method is never called
+ # and I can't figure out why. We just use self.GetSize().GetWidth()
+ # instead and rely on the parent window to size us appropriately. Ugh.
+
+ title = self.titles[item]
+
+ # technique from https://stackoverflow.com/a/23529463/4249120
+ dc = wx.ScreenDC()
+ dc.SetFont(self.title_font)
+
+ return dc.GetTextExtent(title).GetWidth() + 2 * self.MARGIN
+
+ def OnMeasureItem(self, item):
+ title = self.titles[item]
+ subtitle = self.subtitles[item]
+
+ dc = wx.ScreenDC()
+ dc.SetFont(self.subtitle_font)
+ wrapped = wordwrap(subtitle, self.GetSize().GetWidth(), dc)
+ subtitle_height = dc.GetTextExtent(wrapped).GetHeight()
+
+ dc = wx.ScreenDC()
+ dc.SetFont(self.title_font)
+ title_height = dc.GetTextExtent(title).GetHeight()
+
+ return subtitle_height + title_height + 3 * self.MARGIN
+
+ def OnDrawBackground(self, dc, rect, item, flags):
+ if flags & wx.adv.ODCB_PAINTING_SELECTED:
+ # let the parent class draw the selected item so we don't
+ # hae to figure out the highlight color
+ wx.adv.OwnerDrawnComboBox.OnDrawBackground(self, dc, rect, item, flags)
+ else:
+ # alternate white and grey for the dropdown items, and draw the
+ # combo box itself as white
+ if flags & wx.adv.ODCB_PAINTING_CONTROL or item % 2 == 0:
+ background_color = wx.Colour(255, 255, 255)
+ else:
+ background_color = wx.Colour(240, 240, 240)
+
+ dc.SetBrush(wx.Brush(background_color))
+ dc.SetPen(wx.Pen(background_color))
+ dc.DrawRectangle(rect)
+
+ def OnDrawItem(self, dc, rect, item, flags):
+ if flags & wx.adv.ODCB_PAINTING_CONTROL:
+ # painting the selected item in the box
+ dc.SetFont(self.control_font)
+ dc.DrawText(self.titles[item], rect.x + self.MARGIN, rect.y + self.MARGIN)
+ else:
+ # painting the items in the popup
+ dc.SetFont(self.title_font)
+ title_height = dc.GetCharHeight()
+ dc.DrawText(self.titles[item], rect.x + self.MARGIN, rect.y + self.MARGIN)
+
+ dc.SetFont(self.subtitle_font)
+ subtitle = wordwrap(self.subtitles[item], self.GetSize().GetWidth(), dc)
+ dc.DrawText(subtitle, rect.x + self.MARGIN, rect.y + title_height + self.MARGIN * 2)