import wx import metrics class PreferenceFrame(wx.Frame): """ This allows the user to set their preferences. Changes automatically update as the user makes them; when they're done, they close the window. """ def __init__(self, app, parent = None): self.app = app wx.Frame.__init__(self, parent, wx.ID_ANY, title = self.app.NAME + ' Preferences', \ style = wx.MINIMIZE_BOX | wx.CLOSE_BOX | wx.CAPTION | wx.SYSTEM_MENU) panel = wx.Panel(parent = self, id = wx.ID_ANY) borderSizer = wx.BoxSizer(wx.VERTICAL) panel.SetSizer(borderSizer) panelSizer = wx.FlexGridSizer(14, 2, metrics.size('relatedControls'), metrics.size('relatedControls')) borderSizer.Add(panelSizer, flag = wx.ALL, border = metrics.size('windowBorder')) self.editorFont = wx.FontPickerCtrl(panel, style = wx.FNTP_FONTDESC_AS_LABEL) self.editorFont.SetSelectedFont(self.getPrefFont('windowed')) self.editorFont.Bind(wx.EVT_FONTPICKER_CHANGED, lambda e: self.saveFontPref('windowed', \ self.editorFont.GetSelectedFont())) self.monoFont = wx.FontPickerCtrl(panel, style = wx.FNTP_FONTDESC_AS_LABEL) self.monoFont.SetSelectedFont(self.getPrefFont('monospace')) self.monoFont.Bind(wx.EVT_FONTPICKER_CHANGED, lambda e: self.saveFontPref('monospace', \ self.monoFont.GetSelectedFont())) self.fsFont = wx.FontPickerCtrl(panel, style = wx.FNTP_FONTDESC_AS_LABEL) self.fsFont.SetSelectedFont(self.getPrefFont('fs')) self.fsFont.Bind(wx.EVT_FONTPICKER_CHANGED, lambda e: self.saveFontPref('fs', \ self.fsFont.GetSelectedFont())) self.fsTextColor = wx.ColourPickerCtrl(panel) self.fsTextColor.SetColour(self.app.config.Read('fsTextColor')) self.fsTextColor.Bind(wx.EVT_COLOURPICKER_CHANGED, lambda e: self.savePref('fsTextColor', \ self.fsTextColor.GetColour())) self.fsBgColor = wx.ColourPickerCtrl(panel) self.fsBgColor.SetColour(self.app.config.Read('fsBgColor')) self.fsBgColor.Bind(wx.EVT_COLOURPICKER_CHANGED, lambda e: self.savePref('fsBgColor', \ self.fsBgColor.GetColour())) fsLineHeightPanel = wx.Panel(panel) fsLineHeightSizer = wx.BoxSizer(wx.HORIZONTAL) fsLineHeightPanel.SetSizer(fsLineHeightSizer) self.fsLineHeight = wx.ComboBox(fsLineHeightPanel, choices = ('100', '125', '150', '175', '200')) self.fsLineHeight.Bind(wx.EVT_TEXT, lambda e: self.savePref('fsLineHeight', int(self.fsLineHeight.GetValue()))) self.fsLineHeight.SetValue(str(self.app.config.ReadInt('fslineHeight'))) fsLineHeightSizer.Add(self.fsLineHeight, flag = wx.ALIGN_CENTER_VERTICAL) fsLineHeightSizer.Add(wx.StaticText(fsLineHeightPanel, label = '%'), flag = wx.ALIGN_CENTER_VERTICAL) def checkbox(self, name, label, panel=panel): setattr(self, name, wx.CheckBox(panel, label=label)) attr = getattr(self, name) attr.Bind(wx.EVT_CHECKBOX, lambda e, name=name, attr=attr: self.savePref(name, attr.GetValue())) attr.SetValue(self.app.config.ReadBool(name)) checkbox(self, "fastStoryPanel", 'Faster but rougher story map display') checkbox(self, "flatDesign", 'Flat Design(TM) mode') checkbox(self, "imageArrows", 'Connector arrows for images and stylesheets') checkbox(self, "displayArrows", 'Connector arrows for <>ed passages') checkbox(self, "createPassagePrompt", 'Offer to create new passages for broken links') checkbox(self, "importImagePrompt", 'Offer to import externally linked images') checkbox(self, "passageWarnings", 'Warn about possible passage code errors') panelSizer.Add(wx.StaticText(panel, label = 'Normal Font'), flag = wx.ALIGN_CENTER_VERTICAL) panelSizer.Add(self.editorFont) panelSizer.Add(wx.StaticText(panel, label = 'Monospace Font'), flag = wx.ALIGN_CENTER_VERTICAL) panelSizer.Add(self.monoFont) panelSizer.Add(wx.StaticText(panel, label = 'Fullscreen Editor Font'), flag = wx.ALIGN_CENTER_VERTICAL) panelSizer.Add(self.fsFont) panelSizer.Add(wx.StaticText(panel, label = 'Fullscreen Editor Text Color'), flag = wx.ALIGN_CENTER_VERTICAL) panelSizer.Add(self.fsTextColor) panelSizer.Add(wx.StaticText(panel, label = 'Fullscreen Editor Background Color'), \ flag = wx.ALIGN_CENTER_VERTICAL) panelSizer.Add(self.fsBgColor) panelSizer.Add(wx.StaticText(panel, label = 'Fullscreen Editor Line Spacing'), flag = wx.ALIGN_CENTER_VERTICAL) panelSizer.Add(fsLineHeightPanel, flag = wx.ALIGN_CENTER_VERTICAL) panelSizer.Add(self.fastStoryPanel) # pylint: disable=no-member panelSizer.Add((1,2)) panelSizer.Add(self.flatDesign) # pylint: disable=no-member panelSizer.Add((1,2)) panelSizer.Add(self.imageArrows) # pylint: disable=no-member panelSizer.Add((1,2)) panelSizer.Add(self.displayArrows) # pylint: disable=no-member panelSizer.Add((1,2)) panelSizer.Add(wx.StaticText(panel, label = 'When closing a passage:'), flag = wx.ALIGN_CENTER_VERTICAL) panelSizer.Add((1,2)) panelSizer.Add(self.createPassagePrompt) # pylint: disable=no-member panelSizer.Add((1,2)) panelSizer.Add(self.importImagePrompt) # pylint: disable=no-member panelSizer.Add((1,2)) panelSizer.Add(self.passageWarnings) # pylint: disable=no-member panelSizer.Fit(self) borderSizer.Fit(self) self.SetIcon(self.app.icon) self.Show() self.panelSizer = panelSizer self.borderSizer = borderSizer def getPrefFont(self, key): """ Returns a font saved in preferences as a wx.Font instance. """ return wx.Font(self.app.config.ReadInt(key + 'FontSize'), wx.FONTFAMILY_MODERN, \ wx.FONTSTYLE_NORMAL, wx.NORMAL, False, self.app.config.Read(key + 'FontFace')) def savePref(self, key, value): """ Saves changes to a preference and sends an update message to the application. """ if isinstance(value, wx.Colour): self.app.config.Write(key, value.GetAsString(wx.C2S_HTML_SYNTAX)) elif type(value) is int: self.app.config.WriteInt(key, value) elif type(value) is bool: self.app.config.WriteBool(key, value) else: self.app.config.Write(key, value) self.app.applyPrefs() def saveFontPref(self, key, font): """ Saves a user-chosen font to preference keys, then sends an update message to the application. """ self.app.config.Write(key + 'FontFace', font.GetFaceName()) self.app.config.WriteInt(key + 'FontSize', font.GetPointSize()) self.app.applyPrefs() self.panelSizer.Fit(self) self.borderSizer.Fit(self)