class XAxisRangeBox(wx.Panel): """ panel for adjusting x-axis range """ def __init__(self, parent, ID, minvalue=XMIN, initvalue=XWIDTH, increment=SPININC): wx.Panel.__init__(self, parent, ID) self.minvalue = minvalue self.value = initvalue # initial x-axis range width (in sliding mode) # controls self.radio_full = wx.RadioButton(self, -1, label='Full range', style=wx.RB_GROUP) self.radio_slide = wx.RadioButton(self, -1, label='Sliding') self.slide_width = FloatSpin(self, -1, size=(50, -1), digits=0, value=self.value, min_val=minvalue, increment=increment) self.slide_width.GetTextCtrl().SetEditable(False) # event bindings self.Bind(wx.EVT_UPDATE_UI, self.on_update_radio_buttons, self.radio_full) self.Bind(EVT_FLOATSPIN, self.on_float_spin, self.slide_width) # layout box = wx.StaticBox(self, -1, 'X-axis') sizer = wx.StaticBoxSizer(box, wx.VERTICAL) slide_box = wx.BoxSizer(wx.HORIZONTAL) slide_box.Add(self.radio_slide, flag=wx.ALIGN_CENTER_VERTICAL) slide_box.Add(self.slide_width, flag=wx.ALIGN_CENTER_VERTICAL) sizer.Add(self.radio_full, 0, wx.ALL, 10) sizer.Add(slide_box, 0, wx.ALL, 10) self.SetSizer(sizer) sizer.Fit(self) def on_update_radio_buttons(self, event): """ called when the radio buttons are toggled """ self.slide_width.Enable(self.radio_slide.GetValue()) def on_float_spin(self, event): """ called when the sliding mode spinbox is changed """ self.value = self.slide_width.GetValue() def is_full(self): """ return True if full range is checked """ return self.radio_full.GetValue()
class ConfigFrame(wx.Frame): """ configuration window class, shown at the start of the simulation, for picking the configuration file and setting visualization flags """ def __init__(self, parent, id, title, defaultFile, defaultPath, app): wx.Frame.__init__(self, parent, id, title, style=wx.CAPTION | wx.TAB_TRAVERSAL | wx.CLIP_CHILDREN) self.defaultFile = defaultFile # the filename of the default config file self.defaultPath = defaultPath # the initial path that is given for the file picker dialog self.app = app # reference to the application that constructed this frame # dimensions of main panel fullWidth = 300 buttonWidth = 100 borderWidth = 10 # create main panel mainPanel = wx.Panel(self, wx.ID_ANY) # create configuration widgets configBox = wx.StaticBox(mainPanel, wx.ID_ANY, label='Configuration file', style=wx.BORDER_SUNKEN) configBoxSizer = wx.StaticBoxSizer(configBox, wx.VERTICAL) self.configText = wx.TextCtrl(mainPanel, wx.ID_ANY, value=self.defaultFilename(), size=(fullWidth, -1), style=wx.TE_READONLY) self.createButton = wx.Button(mainPanel, wx.ID_ANY, label='Create...', size=(buttonWidth, -1)) self.loadButton = wx.Button(mainPanel, wx.ID_ANY, label='Load...', size=(buttonWidth, -1)) # layout configuration widgets configButtonSizer = wx.BoxSizer(wx.HORIZONTAL) configButtonSizer.Add(self.createButton, flag=wx.ALL, border=0) configButtonSizer.Add((fullWidth - 2 * buttonWidth, -1), 1) configButtonSizer.Add(self.loadButton, flag=wx.ALL, border=0) configBoxSizer.Add(self.configText, 0, wx.ALL, border=borderWidth) configBoxSizer.Add(configButtonSizer, 0, wx.LEFT | wx.RIGHT | wx.BOTTOM, border=borderWidth) configBoxSizer.Fit(configBox) # create visualization widgets visualBox = wx.StaticBox(mainPanel, wx.ID_ANY, label='Demonstration options', style=wx.BORDER_SUNKEN) visualBoxSizer = wx.StaticBoxSizer(visualBox, wx.VERTICAL) self.checkLevels = wx.CheckBox( mainPanel, wx.ID_ANY, label=' Print A-weighted SPL at receivers to console') self.checkVehicles = wx.CheckBox( mainPanel, wx.ID_ANY, label=' Print detailed vehicle information to console') self.checkTimeseries = wx.CheckBox( mainPanel, wx.ID_ANY, label=' Send level timeseries at receivers to Viewer') # create slowdown spinbox self.slowdownTxt1 = wx.StaticText(mainPanel, -1, label=' Slowdown: ') self.slowdownSpin = FloatSpin(mainPanel, -1, size=(60, -1), digits=0, value=0, min_val=0, increment=50) self.slowdownSpin.GetTextCtrl().SetEditable(False) self.slowdownTxt2 = wx.StaticText(mainPanel, -1, label=' milliseconds/timestep') self.enableSlowdown(False) self.slowdownBoxSizer = wx.BoxSizer(wx.HORIZONTAL) self.slowdownBoxSizer.Add(self.slowdownTxt1, border=0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL) self.slowdownBoxSizer.Add(self.slowdownSpin, border=0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL) self.slowdownBoxSizer.Add(self.slowdownTxt2, border=0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL) # layout visualization widgets visualBoxSizer.Add(self.checkLevels, 0, wx.ALL, border=borderWidth) visualBoxSizer.Add(self.checkVehicles, 0, wx.LEFT | wx.RIGHT | wx.BOTTOM, border=borderWidth) visualBoxSizer.Add(self.checkTimeseries, 0, wx.LEFT | wx.RIGHT | wx.BOTTOM, border=borderWidth) visualBoxSizer.Add(self.slowdownBoxSizer, 0, wx.LEFT | wx.RIGHT | wx.BOTTOM, border=borderWidth) visualBoxSizer.Add((fullWidth + 2 * borderWidth, -1), 1) visualBoxSizer.Fit(visualBox) # create buttons self.disableButton = wx.Button(mainPanel, wx.ID_ANY, label='Disable plugin', size=(buttonWidth, -1)) self.okButton = wx.Button(mainPanel, wx.ID_ANY, label='Ok', size=(buttonWidth, -1)) okButtonSizer = wx.BoxSizer(wx.HORIZONTAL) okButtonSizer.Add(self.disableButton, flag=wx.ALL, border=0) okButtonSizer.Add((fullWidth + 3 * borderWidth - 2 * buttonWidth, -1), 1) okButtonSizer.Add(self.okButton, flag=wx.ALL, border=0) # finally, add main sizer with border mainSizer = wx.BoxSizer(wx.VERTICAL) mainSizer.Add(configBoxSizer, 0, flag=wx.ALL, border=borderWidth) mainSizer.Add(visualBoxSizer, 0, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM, border=borderWidth) mainSizer.Add(okButtonSizer, 0, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM, border=borderWidth) mainPanel.SetSizerAndFit(mainSizer) self.Fit() # associate events with class methods self.createButton.Bind(wx.EVT_BUTTON, self.OnCreate) self.loadButton.Bind(wx.EVT_BUTTON, self.OnLoad) self.disableButton.Bind(wx.EVT_BUTTON, self.OnDisable) self.okButton.Bind(wx.EVT_BUTTON, self.OnOK) self.checkTimeseries.Bind(wx.EVT_CHECKBOX, self.OnTimeseries) self.okButton.SetFocus() # set result value to default self.checkFilename() self.app.result = None def defaultFilename(self): """ return the default filename, including the full path """ return os.path.join(self.defaultPath, self.defaultFile) def checkFilename(self): """ check if the filename in the configText exists, and apply the necessary gui updates """ # fetch the full filename filename = self.configText.GetValue() if os.path.exists(filename): # enable OK button self.okButton.Enable(True) return True else: # clear the filename box self.configText.SetValue('') # disable the OK button self.okButton.Enable(False) return False def enableSlowdown(self, flag=True): """ enable or disable the slowdown spinbox """ for widget in [ self.slowdownTxt1, self.slowdownSpin, self.slowdownTxt2 ]: widget.Enable(flag) def OnTimeseries(self, event): """ executed when the user toggles the checkTimeseries check box """ self.enableSlowdown(self.checkTimeseries.GetValue()) def OnCreate(self, event): """ executed when the user presses the Create button """ # ask for filename dialog = wx.FileDialog(None, message='Save the configuration file as...', defaultDir=self.defaultPath, wildcard=('*.%s' % version.name), style=wx.SAVE | wx.FD_OVERWRITE_PROMPT) if dialog.ShowModal() == wx.ID_OK: # create a default configuration file filename = dialog.GetPath() cfg = Configuration() cfg.save(filename) # finally, update the filename box and the gui self.configText.SetValue(filename) self.checkFilename() def OnLoad(self, event): """ executed when the user presses the Load button """ # show a file picker dialog dialog = wx.FileDialog(None, message='Select a configuration file', defaultDir=self.defaultPath, wildcard=('*.%s' % version.name), style=wx.OPEN) if dialog.ShowModal() == wx.ID_OK: self.configText.SetValue(dialog.GetPath()) self.checkFilename() def OnDisable(self, event): """ executed when the user presses the Disable button """ # close without a configuration filename (thus disable the plugin) self.app.result = (None, False, False, False, 0) self.Destroy() def OnOK(self, event): """ executed when the user presses the OK button """ # fetch the options if self.checkFilename(): self.app.result = (self.configText.GetValue(), self.checkLevels.GetValue(), self.checkVehicles.GetValue(), self.checkTimeseries.GetValue(), self.slowdownSpin.GetValue()) self.Destroy()
class YAxisRangeBox(wx.Panel): """ panel for adjusting y-axis range """ def __init__(self, parent, ID, minvalue=YMIN, initvalue=YRANGE, increment=SPININC): wx.Panel.__init__(self, parent, ID) self.value = initvalue # initial y-axis range (in manual mode), i.e. (min, max-min) # controls self.radio_auto = wx.RadioButton(self, -1, label='Auto', style=wx.RB_GROUP) self.radio_manual = wx.RadioButton(self, -1, label='Manual') self.manual_min = FloatSpin(self, -1, size=(50, -1), digits=0, value=self.value[0], min_val=minvalue[0], increment=increment) self.manual_min.GetTextCtrl().SetEditable(False) self.manual_width = FloatSpin(self, -1, size=(50, -1), digits=0, value=self.value[1], min_val=minvalue[1], increment=increment) self.manual_width.GetTextCtrl().SetEditable(False) # event bindings self.Bind(wx.EVT_UPDATE_UI, self.on_update_radio_buttons, self.radio_auto) self.Bind(EVT_FLOATSPIN, self.on_float_spin, self.manual_min) self.Bind(EVT_FLOATSPIN, self.on_float_spin, self.manual_width) # layout box = wx.StaticBox(self, -1, 'Y-axis') sizer = wx.StaticBoxSizer(box, wx.VERTICAL) manual_box = wx.BoxSizer(wx.HORIZONTAL) manual_box.Add(self.radio_manual, flag=wx.ALIGN_CENTER_VERTICAL) manual_box.Add(self.manual_min, flag=wx.ALIGN_CENTER_VERTICAL) manual_box.Add(self.manual_width, flag=wx.ALIGN_CENTER_VERTICAL) sizer.Add(self.radio_auto, 0, wx.ALL, 10) sizer.Add(manual_box, 0, wx.ALL, 10) self.SetSizer(sizer) sizer.Fit(self) def on_update_radio_buttons(self, event): """ called when the radio buttons are toggled """ toggle = self.radio_manual.GetValue() self.manual_min.Enable(toggle) self.manual_width.Enable(toggle) def on_float_spin(self, event): """ called when one of the manual mode spinboxes is changed """ self.value = (self.manual_min.GetValue(), self.manual_width.GetValue()) def is_auto(self): """ return True if auto range is checked """ return self.radio_auto.GetValue()