def UpdateFontSize(self): self.__fnt_tiny = wx.Font(ScaleFont(self.GetSettings().playback_font_size), wx.NORMAL, wx.NORMAL, wx.NORMAL) self.__fnt_bold_med = wx.Font(ScaleFont(self.GetSettings().playback_font_size), wx.NORMAL, wx.NORMAL, wx.BOLD) self.__fnt = wx.Font(ScaleFont(self.GetSettings().playback_font_size), wx.NORMAL, wx.NORMAL, wx.NORMAL) self.__fnt_hl = self.__fnt.Underlined() self.SetFont(self.__fnt) self.__drop_clock.SetFont(self.__fnt) self.__static_curcycle.SetFont(self.__fnt_bold_med) self.__static_curtick.SetFont(self.__fnt_tiny) self.__hl_start.SetFont(self.__fnt_hl) self.__hl_end.SetFont(self.__fnt_hl) self.__btn_rw_hold.SetFont(self.__fnt) self.__btn_back30.SetFont(self.__fnt) self.__btn_back10.SetFont(self.__fnt) self.__btn_back3.SetFont(self.__fnt) self.__btn_back1.SetFont(self.__fnt) self.__btn_forward1.SetFont(self.__fnt) self.__btn_forward3.SetFont(self.__fnt) self.__btn_forward10.SetFont(self.__fnt) self.__btn_forward30.SetFont(self.__fnt) self.__btn_ff_hold.SetFont(self.__fnt) self.__txt_goto.SetFont(self.__fnt) self.__btn_goto.SetFont(self.__fnt) self.__static_playback_speed_units.SetFont(self.__fnt) self.__spin_playback_speed.SetFont(self.__fnt) self.__btn_playpause.SetFont(self.__fnt) self.Layout()
def __init__(self, parent, id, title, elements=None): size = (500, 300) self.__parent = parent wx.Frame.__init__(self, parent, id, "Element Properties Editor", size = size, \ style = wx.RESIZE_BORDER | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN | wx.STAY_ON_TOP) # used for temporary display of error messages self.__timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.Draw, self.__timer) self.SetBackgroundColour("WHITE") self.CreateStatusBar() self.__fnt_location = wx.Font(ScaleFont(12), wx.NORMAL, wx.NORMAL, wx.NORMAL) self.SetFont(self.__fnt_location) self.__sizer = wx.BoxSizer(wx.VERTICAL) self.__list = ElementPropertyList(self, id) self.__sizer.Add(self.__list, 1, wx.EXPAND) self.SetSizerAndFit(self.__sizer) self.SetAutoLayout(True) self.Show(True) self.Move((200, 200)) # better than center self.Bind(wx.EVT_CLOSE, self.Hide) self.Bind(wx.EVT_KEY_DOWN, self.__OnKeyDown)
def __init__(self, parent, id, title, layout_context): self.__layout_context = layout_context size = (600, 100) self.__parent = parent wx.Frame.__init__(self, parent, id, title + " properties dialog", size, style=wx.RESIZE_BORDER | wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN) self.__fnt_location = wx.Font(ScaleFont(12), wx.NORMAL, wx.NORMAL, wx.NORMAL) self.SetFont(self.__fnt_location) # work could be done to make these prettier self.__sizer = wx.BoxSizer(wx.VERTICAL) self.__list = VarsListCtrl( self, id, style=wx.LC_REPORT | wx.BORDER_NONE | wx.LC_SORT_ASCENDING, variables=layout_context.GetLocationVariables()) self.__sizer.Add(self.__list, 1, wx.EXPAND) self.SetSizer(self.__sizer) self.SetAutoLayout(True)
def __init__(self, frame): super(LayoutExitDialog, self).__init__(frame, -1, title='Unsaved Changes to this Layout') layout_name = frame.GetContext().GetLayout().GetFilename() if layout_name is not None: layout_name = os.path.split(layout_name)[-1] else: layout_name = '<unsaved layout>' fnt_filename = wx.Font(ScaleFont(13), wx.NORMAL, wx.NORMAL, wx.NORMAL, wx.FONTWEIGHT_BOLD) lbl_filename = wx.StaticText(self, -1, layout_name) lbl_filename.SetFont(fnt_filename) BTN_ICON_SIZE = 16 bmp_discard = wx.ArtProvider.GetBitmap(wx.ART_DELETE, wx.ART_MESSAGE_BOX, (BTN_ICON_SIZE,BTN_ICON_SIZE)) bmp_save = wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE, wx.ART_MESSAGE_BOX, (BTN_ICON_SIZE,BTN_ICON_SIZE)) bmp_return = wx.ArtProvider.GetBitmap(wx.ART_GO_BACK, wx.ART_MESSAGE_BOX, (BTN_ICON_SIZE,BTN_ICON_SIZE)) STYLE = platebtn.PB_STYLE_SQUARE btn_discard = platebtn.PlateButton(self, wx.ID_DELETE, ' Discard Changes ', bmp_discard, style=STYLE) btn_discard.SetBackgroundColour((240,80,80)) btn_save = platebtn.PlateButton(self, wx.ID_SAVE, ' Save ', bmp_save, style=STYLE) btn_save.SetBackgroundColour((170,170,170)) btn_return = platebtn.PlateButton(self, wx.ID_BACKWARD, ' Back to Editing ', bmp_return, style=STYLE) btn_return.SetBackgroundColour((170,170,170)) button_sizer = wx.BoxSizer(wx.HORIZONTAL) button_sizer.Add(btn_discard, 0, wx.ALL, 4) button_sizer.Add((50,1), 0) button_sizer.Add(btn_save, 0, wx.ALL, 4) button_sizer.Add(btn_return, 0, wx.ALL, 4) message_sizer = wx.BoxSizer(wx.VERTICAL) message_sizer.Add((1,10), 0) message_sizer.Add(wx.StaticText(self, -1, 'Layout has been modified since last save!'), 0, wx.ALL, 8) message_sizer.Add((1,1), 0) message_sizer.Add(lbl_filename, 0, wx.ALL, 8) message_sizer.Add((1,20), 0) bmp = wx.ArtProvider.GetBitmap(wx.ART_WARNING, wx.ART_MESSAGE_BOX, (64,64)) upper_sizer = wx.BoxSizer(wx.HORIZONTAL) upper_sizer.Add(wx.StaticBitmap(self, -1, bmp, (0,0), (bmp.GetWidth(), bmp.GetHeight())), 0, wx.ALL, 10) upper_sizer.Add(message_sizer, 1, wx.EXPAND) main_sizer = wx.BoxSizer(wx.VERTICAL) main_sizer.Add(upper_sizer, 1, wx.EXPAND) main_sizer.Add(button_sizer, 0, wx.EXPAND | wx.ALL, 5) self.SetSizer(main_sizer) self.Layout() self.Fit() def GenAssigner(val): def Assigner(*args): self.__result = val self.EndModal(val) return Assigner btn_discard.Bind(wx.EVT_BUTTON, GenAssigner(wx.ID_DELETE)) btn_save.Bind(wx.EVT_BUTTON, GenAssigner(wx.ID_SAVE)) btn_return.Bind(wx.EVT_BUTTON, GenAssigner(wx.ID_CANCEL)) self.Bind(wx.EVT_CLOSE, GenAssigner(wx.ID_CANCEL)) self.__result = None
def __init__(self, parent, elpropsdlg): ''' @param parent Parent Layout_Frame @param elpropsdlg Element Properties Dialog for this frame ''' self.__layout_frame = parent self.__el_props_dlg = elpropsdlg self.__db = parent.GetContext().dbhandle.database self.__tree_dict = {} # Create Controls title = "Locations for {0}".format(self.__db.filename) wx.Frame.__init__(self, parent, -1, title, size = (1025, 600), style = wx.MAXIMIZE_BOX | wx.RESIZE_BORDER | wx.CAPTION | wx.CLOSE_BOX | wx.SYSTEM_MENU) self.__fnt_small = wx.Font(ScaleFont(12), wx.NORMAL, wx.NORMAL, wx.NORMAL) static_heading = wx.StaticText(self, -1, "Showing all locations for:") static_filename = wx.StaticText(self, -1, self.__db.filename) static_filename.SetFont(self.__fnt_small) filter_label = wx.StaticText(self, -1, "Filter") self.__filter_ctrl = wx.TextCtrl(self, -1) # TODO style had wx.TR_EXTENDED but seemed missing from the API self.__tree_ctrl = wx.lib.gizmos.treelistctrl.TreeListCtrl(self, -1, size = wx.Size(-1, 100), style = wx.TR_DEFAULT_STYLE | wx.TR_FULL_ROW_HIGHLIGHT | \ wx.TR_MULTIPLE | wx.TR_HIDE_ROOT) self.__tree_ctrl.AddColumn('Node') self.__tree_ctrl.SetColumnWidth(self.COL_NODE, 400) self.__tree_ctrl.AddColumn('Clock') self.__tree_ctrl.SetColumnWidth(self.COL_CLOCK, 100) self.__tree_ctrl.AddColumn('Full Path') self.__tree_ctrl.SetColumnWidth(self.COL_PATH, 500) tree = self.__db.location_manager.location_tree self.__root = self.__tree_ctrl.AddRoot('<root>') self.__use_filter = False self.__SetLocationTree(tree) # User preference is to NOT expand tree. ## self.__tree_ctrl.ExpandAll() self.__btn_create_element = wx.Button(self, -1, "Create Element(s)") self.__btn_create_element.SetToolTip('Creates a new element for each of the selected ' \ 'locations in the tree') self.__btn_set = wx.Button(self, -1, "Set Location to Selected") self.__btn_set.SetToolTip('Sets the location string for all selected elements to the ' \ 'selected location in the tree. Generally, the selected ' \ 'location should be a leaf node') # Prepare self.__UpdateButtons() # Bindings self.__tree_ctrl.Bind(wx.EVT_TREE_SEL_CHANGED, self.__OnTreeSelChanged) self.__btn_create_element.Bind(wx.EVT_BUTTON, self.__OnCreateElements) self.__btn_set.Bind(wx.EVT_BUTTON, self.__OnSetLocation) self.__filter_ctrl.Bind(wx.EVT_TEXT, self.__OnFilterChanged) self.Bind(wx.EVT_CLOSE, lambda evt: self.Hide()) # Hide instead of closing self.__tree_ctrl.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.__OnExpandItem) # Layout button_sizer = wx.BoxSizer(wx.HORIZONTAL) button_sizer.Add(self.__btn_create_element, 0, wx.RIGHT, 2) button_sizer.Add(self.__btn_set, 0) button_sizer.Add((1, 1), 1, wx.EXPAND) sz = wx.BoxSizer(wx.VERTICAL) sz.Add((1, 3), 0) sz.Add(static_heading, 0, wx.EXPAND | wx.ALL, 2) sz.Add(static_filename, 0, wx.EXPAND | wx.ALL, 4) filter_sizer = wx.BoxSizer(wx.HORIZONTAL) filter_sizer.Add((2, 1), 0) filter_sizer.Add(filter_label, 0, wx.EXPAND | wx.ALL) filter_sizer.Add(self.__filter_ctrl, 0, wx.EXPAND | wx.ALL) sz.Add(filter_sizer, 0, wx.EXPAND | wx.ALL) sz.Add(self.__tree_ctrl, 2, wx.EXPAND | wx.ALL, 1) sz.Add(button_sizer, 0, wx.EXPAND | wx.ALL, 4) self.SetSizer(sz) self.Bind(wx.EVT_ACTIVATE, self.__OnActivate) # Fire a text event to load the filter for the first time wx.PostEvent(self.__filter_ctrl.GetEventHandler(), wx.PyCommandEvent(wx.EVT_TEXT.typeId, self.GetId()))
def __init__(self, frame, layout): self.__parent = frame self.__layout = layout wx.Panel.__init__(self, self.__parent, wx.ID_ANY) self.__db = self.__parent.GetContext().dbhandle.database self.__qapi = self.__parent.GetContext().dbhandle.api # Vars # keep a list of clock instances that are referenced self.__referenced_clocks = self.__parent.GetContext().GetVisibleClocks( ) self.__current_clock = None self.__is_auto_clock = False # Dummy to hold play rate when playing. If None, refers to the play speed spin # control. Otherwise indicates an actual play speed. Set when starting and pausing # playback self.__play_rate = None self.__last_play_tick = None # Timestamp of last play tick self.__accum_play_cycle_fraction = None # Cumulative advance time across multiple cycles self.__slider_hooked = False # Is user controlling the slider (True prevents auto-updates to the slider) # Fonts & Colors self.__fnt_tiny = wx.Font(ScaleFont(12), wx.NORMAL, wx.NORMAL, wx.NORMAL) self.__fnt_bold_med = wx.Font(ScaleFont(12), wx.NORMAL, wx.NORMAL, wx.BOLD) self.__fnt = wx.Font(ScaleFont(12), wx.NORMAL, wx.NORMAL, wx.NORMAL) self.SetFont(self.__fnt) self.__med_blue = wx.Colour(0, 0, 220) # Controls self.__play_timer = wx.Timer( self) # Placeholder. Will be created as needed self.__hl_start = hl.HyperLinkCtrl(self, wx.ID_ANY, label=' ', URL='') self.__hl_start.SetToolTip( 'Jump to first cycle in the transaction database') self.__hl_start.AutoBrowse(False) self.__hl_end = hl.HyperLinkCtrl(self, wx.ID_ANY, label=' ', URL='') self.__hl_end.SetToolTip( 'Jump to final cycle in the transaction database') self.__hl_end.AutoBrowse(False) self.__time_slider = wx.Slider(self, wx.ID_ANY) self.__time_slider.SetToolTip( 'Displays the current position in the transaction database. Slide this bar to quickly move around' ) # self.__time_slider.SetThumbLength(2) # self.__time_slider.SetLineSize(1) self.__time_slider.SetRange(0, self.TIME_SLIDER_RANGE) self.__time_slider.SetForegroundColour(self.__med_blue) clocks = self.__db.clock_manager.getClocks() clock_choices = ['<any clk edge>'] self.__ALL_CLOCKS = 0 for clk in clocks: clock_choices.append(clk.name) self.__drop_clock = wx.ComboBox(self, choices=clock_choices, size=(150, -1), style=wx.CB_DROPDOWN | wx.CB_READONLY) self.__drop_clock.SetToolTip('Current clock domain. This dictates the units in which this ' \ 'frame prints time. Playback and step controls will operate ' \ 'on this clock domain. Select any clock domain from the list.') self.__drop_clock.SetFont(self.__fnt) # self.__drop_clock.SetValue(ClockManager.HYPERCYCLE_CLOCK_NAME) self.__drop_clock.SetSelection(0) curtime_msg = 'Current cycle in the current clock domain. Also shows ' \ 'the hyper-tick (common time) tick count of this frame' self.__static_curcycle = wx.StaticText(self, wx.ID_ANY, size=(90, -1)) self.__static_curcycle.SetToolTip(curtime_msg) self.__static_curcycle.SetForegroundColour(self.__med_blue) self.__static_curcycle.SetFont(self.__fnt_bold_med) self.__static_curtick = wx.StaticText(self, wx.ID_ANY, size=(90, -1)) self.__static_curtick.SetToolTip(curtime_msg) self.__static_curtick.SetForegroundColour(self.__med_blue) self.__static_curtick.SetFont(self.__fnt_tiny) PLAYBACK_BUTTON_WIDTH = 40 self.__btn_rw_hold = ShyButton(self, wx.ID_ANY, '<<', size=(PLAYBACK_BUTTON_WIDTH, -1), style=wx.BU_EXACTFIT) self.__btn_rw_hold.SetToolTip('Rewinds while left-mouse is held. Using space or enter to activate ' \ 'this control also rewinds but rate is dictated by keyboard repeat rate') self.__btn_back30 = ShyButton(self, wx.ID_ANY, '-30', size=(PLAYBACK_BUTTON_WIDTH, -1), style=wx.BU_EXACTFIT) self.__btn_back30.SetToolTip( 'Steps back 30 cycle in the current clock domain') self.__btn_back10 = ShyButton(self, wx.ID_ANY, '-10', size=(PLAYBACK_BUTTON_WIDTH, -1), style=wx.BU_EXACTFIT) self.__btn_back10.SetToolTip( 'Steps back 10 cycle in the current clock domain') self.__btn_back3 = ShyButton(self, wx.ID_ANY, '-3', size=(PLAYBACK_BUTTON_WIDTH, -1), style=wx.BU_EXACTFIT) self.__btn_back3.SetToolTip( 'Steps back 3 cycle in the current clock domain') self.__btn_back1 = ShyButton(self, wx.ID_ANY, '-1', size=(PLAYBACK_BUTTON_WIDTH, -1), style=wx.BU_EXACTFIT) self.__btn_back1.SetToolTip( 'Steps back 1 cycle in the current clock domain') self.__btn_forward1 = ShyButton(self, wx.ID_ANY, '+1', size=(PLAYBACK_BUTTON_WIDTH, -1), style=wx.BU_EXACTFIT) self.__btn_forward1.SetToolTip( 'Steps forward 1 cycle in the current clock domain') self.__btn_forward3 = ShyButton(self, wx.ID_ANY, '+3', size=(PLAYBACK_BUTTON_WIDTH, -1), style=wx.BU_EXACTFIT) self.__btn_forward3.SetToolTip( 'Steps forward 3 cycle in the current clock domain') self.__btn_forward10 = ShyButton(self, wx.ID_ANY, '+10', size=(PLAYBACK_BUTTON_WIDTH, -1), style=wx.BU_EXACTFIT) self.__btn_forward10.SetToolTip( 'Steps forward 10 cycle in the current clock domain') self.__btn_forward30 = ShyButton(self, wx.ID_ANY, '+30', size=(PLAYBACK_BUTTON_WIDTH, -1), style=wx.BU_EXACTFIT) self.__btn_forward30.SetToolTip( 'Steps forward 30 cycle in the current clock domain') self.__btn_ff_hold = ShyButton(self, wx.ID_ANY, '>>', size=(PLAYBACK_BUTTON_WIDTH, -1), style=wx.BU_EXACTFIT) self.__btn_ff_hold.SetToolTip('Fast-Forwards while left-mouse is held. Using space or enter to activate ' \ 'this control also fast-forwards but rate is dictated by keyboard repeat rate') self.__txt_goto = wx.TextCtrl(self, wx.ID_ANY, size=(60, -1), value='+10') self.__txt_goto.SetToolTip('Enter an absolute or relative cycle number (in the current clock domain) ' \ 'to jump to. Decimal, octal (0NNN), hex (0xNNN), or binary (0bNNN) ' \ 'literals are all acceptable inputs. Prefixing the number with a + or ' \ '- sign will result in this value being interpreted as a relative value ' \ 'from the current cycle. Press Enter or click "jump" to jump to the ' \ 'specified cycle') self.__btn_goto = ShyButton(self, wx.ID_ANY, 'jump', size=(60, -1), style=wx.BU_EXACTFIT) self.__btn_goto.SetToolTip( 'Jump to the absolute or relative cycle specified in the jump text control' ) self.__static_playback_speed_units = wx.StaticText( self, wx.ID_ANY, 'cyc/\nsec') self.__spin_playback_speed = wx.SpinCtrl(self, wx.ID_ANY, '1') self.__spin_playback_speed.SetToolTip('Set the number of cycles (in current clock domain) to display ' \ 'per second during playback. This can be positive or negative. ' \ 'A value of 0 prevents playing') self.__spin_playback_speed.SetRange(-self.MAX_PLAY_RATE, self.MAX_PLAY_RATE) self.__spin_playback_speed.SetValue(1.5) self.__btn_playpause = ShyButton(self, wx.ID_ANY, self.LABEL_PLAY, size=(45, -1), style=wx.BU_EXACTFIT) self.__btn_playpause.SetToolTip('Automatically steps through cycles (in the current clock domain) at ' \ 'the rate (positive or negative) specified by the "cyc/sec" ' \ 'spin-control beside this button') # Event Bindings self.Bind(wx.EVT_TIMER, self.__OnPlayTimer, self.__play_timer) self.Bind(wx.EVT_CHILD_FOCUS, self.__OnChildFocus) self.__hl_start.Bind(hl.EVT_HYPERLINK_LEFT, self.__OnGotoStart) self.__hl_end.Bind(hl.EVT_HYPERLINK_LEFT, self.__OnGotoEnd) self.__time_slider.Bind(wx.EVT_SLIDER, self.__OnTimeSlider) self.__time_slider.Bind(wx.EVT_LEFT_DOWN, self.__OnTimeSliderLeftDown) self.__time_slider.Bind(wx.EVT_LEFT_UP, self.__OnTimeSliderLeftUp) self.__time_slider.Bind(wx.EVT_CHAR, self.__OnTimeSliderChar) self.__drop_clock.Bind(wx.EVT_COMBOBOX, self.__OnClockSelect) self.__btn_rw_hold.Bind(wx.EVT_LEFT_DOWN, self.__OnRWButtonDown) self.__btn_rw_hold.Bind(wx.EVT_LEFT_UP, self.__OnRWButtonUp) self.__btn_rw_hold.Bind(wx.EVT_KEY_DOWN, self.__OnRWKeyDown) self.__btn_back30.Bind(wx.EVT_BUTTON, self.__OnBack30) self.__btn_back10.Bind(wx.EVT_BUTTON, self.__OnBack10) self.__btn_back3.Bind(wx.EVT_BUTTON, self.__OnBack3) self.__btn_back1.Bind(wx.EVT_BUTTON, self.__OnBack1) self.__btn_back1.Bind(wx.EVT_LEFT_DOWN, self.__OnBack1LeftDown) self.__btn_back1.Bind(wx.EVT_LEFT_UP, self.__OnBack1LeftUp) self.__btn_forward1.Bind(wx.EVT_BUTTON, self.__OnForward1) self.__btn_forward1.Bind(wx.EVT_LEFT_DOWN, self.__OnForward1LeftDown) self.__btn_forward1.Bind(wx.EVT_LEFT_UP, self.__OnForward1LeftUp) self.__btn_forward3.Bind(wx.EVT_BUTTON, self.__OnForward3) self.__btn_forward10.Bind(wx.EVT_BUTTON, self.__OnForward10) self.__btn_forward30.Bind(wx.EVT_BUTTON, self.__OnForward30) self.__btn_ff_hold.Bind(wx.EVT_LEFT_DOWN, self.__OnFFButtonDown) self.__btn_ff_hold.Bind(wx.EVT_LEFT_UP, self.__OnFFButtonUp) self.__btn_ff_hold.Bind(wx.EVT_KEY_DOWN, self.__OnFFKeyDown) self.__txt_goto.Bind(wx.EVT_TEXT, self.__OnChangeGotoValue) self.__txt_goto.Bind(wx.EVT_CHAR, self.__OnGotoChar) self.__btn_goto.Bind(wx.EVT_BUTTON, self.__OnGoto) self.__spin_playback_speed.Bind(wx.EVT_SPINCTRL, self.__OnPlaySpinValChange) self.__spin_playback_speed.Bind(wx.EVT_CHAR, self.__OnPlaySpinValChar) self.__btn_playpause.Bind(wx.EVT_BUTTON, self.__OnPlayPause) # Layout curticks = wx.BoxSizer(wx.VERTICAL) curticks.Add(self.__static_curcycle, 1, wx.EXPAND) curticks.Add(self.__static_curtick, 1, wx.EXPAND) row1 = wx.BoxSizer(wx.HORIZONTAL) row1.Add(self.__hl_start, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 2) slider_sizer = wx.BoxSizer(wx.HORIZONTAL) slider_sizer.Add(self.__time_slider, 1, wx.ALIGN_CENTER_VERTICAL) row1.Add(slider_sizer, 1, wx.EXPAND) row1.Add(self.__hl_end, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, 2) row2 = wx.FlexGridSizer(cols=6) for i in range(5): row2.AddGrowableCol(i) row2.AddGrowableRow(0) clock_sizer = wx.FlexGridSizer(2) clock_sizer.AddGrowableRow(0) clock_sizer.Add(self.__drop_clock, 0, wx.ALIGN_CENTER_VERTICAL | wx.SHAPED) clock_sizer.Add(curticks, 0, wx.EXPAND | wx.LEFT, 3) row2.Add(clock_sizer, 0, wx.ALIGN_CENTER_VERTICAL | wx.EXPAND) nav_sizer = wx.FlexGridSizer(10) nav_sizer.AddGrowableRow(0) nav_sizer.Add(self.__btn_rw_hold, 0, wx.ALIGN_CENTER_VERTICAL) nav_sizer.Add(self.__btn_back30, 0, wx.ALIGN_CENTER_VERTICAL) nav_sizer.Add(self.__btn_back10, 0, wx.ALIGN_CENTER_VERTICAL) nav_sizer.Add(self.__btn_back3, 0, wx.ALIGN_CENTER_VERTICAL) nav_sizer.Add(self.__btn_back1, 0, wx.ALIGN_CENTER_VERTICAL) nav_sizer.Add(self.__btn_forward1, 0, wx.ALIGN_CENTER_VERTICAL) nav_sizer.Add(self.__btn_forward3, 0, wx.ALIGN_CENTER_VERTICAL) nav_sizer.Add(self.__btn_forward10, 0, wx.ALIGN_CENTER_VERTICAL) nav_sizer.Add(self.__btn_forward30, 0, wx.ALIGN_CENTER_VERTICAL) nav_sizer.Add(self.__btn_ff_hold, 0, wx.ALIGN_CENTER_VERTICAL) row2.Add(nav_sizer, 0, wx.ALIGN_CENTER_VERTICAL | wx.EXPAND) line_sizer1 = wx.BoxSizer(wx.HORIZONTAL) line_sizer1.Add(wx.StaticLine(self, wx.ID_ANY, style=wx.VERTICAL), 0, wx.SHAPED | wx.ALIGN_CENTER_VERTICAL) row2.Add(line_sizer1, 0, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL) goto_sizer = wx.FlexGridSizer(2) goto_sizer.AddGrowableRow(0) goto_sizer.Add(self.__txt_goto, 0, wx.ALIGN_CENTER_VERTICAL) goto_sizer.Add(self.__btn_goto, 0, wx.ALIGN_CENTER_VERTICAL) row2.Add(goto_sizer, 0, wx.ALIGN_CENTER_VERTICAL | wx.EXPAND) line_sizer2 = wx.BoxSizer(wx.HORIZONTAL) line_sizer2.Add(wx.StaticLine(self, wx.ID_ANY, style=wx.VERTICAL), 0, wx.SHAPED | wx.ALIGN_CENTER_VERTICAL) row2.Add(line_sizer2, 0, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL) playback_sizer = wx.FlexGridSizer(2) playback_sizer.AddGrowableRow(0) playback_sizer.Add(self.__btn_playpause, 0, wx.ALIGN_CENTER_VERTICAL) spinner_sizer = wx.BoxSizer(wx.HORIZONTAL) spinner_sizer.Add(self.__static_playback_speed_units, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 2) spinner_sizer.Add(self.__spin_playback_speed, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 1) playback_sizer.Add(spinner_sizer, 0, wx.ALIGN_CENTER_VERTICAL) row2.Add(playback_sizer, 0, wx.ALIGN_RIGHT | wx.EXPAND) playback_controls = [ c for c in self.GetChildren() if not isinstance(c, wx.StaticText) and row2.GetItem(c, recursive=True) is not None ] min_playback_height = max(c.GetBestSize().GetHeight() for c in playback_controls) for c in playback_controls: orig_width, _ = c.GetMinSize() c.SetMinSize((orig_width, min_playback_height)) rows = wx.BoxSizer(wx.VERTICAL) rows.Add(row2, 0, wx.EXPAND | wx.TOP, 2) rows.Add(wx.StaticLine(self, wx.ID_ANY), 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 4) rows.Add(row1, 0, wx.EXPAND) self.SetSizer(rows) self.Fit() self.SetAutoLayout(1) # Initialization self.__OnChangeGotoValue() # Validate initial GOTO value self.__GetSelectedClock() self.__Update()