Example #1
0
	def __init__(self, parent):
		"""
		Create a new control panel.
		
		Args:
		    parent: the wx parent window
		"""
		self.parent = parent
		wx.Panel.__init__(self, parent)
		parent[SHOW_CONTROL_PANEL_KEY] = True
		parent.subscribe(SHOW_CONTROL_PANEL_KEY, self.Show)
		control_box = wx.BoxSizer(wx.VERTICAL)
		#checkboxes for average and peak hold
		control_box.AddStretchSpacer()
		options_box = forms.static_box_sizer(
			parent=self, sizer=control_box, label='Options',
			bold=True, orient=wx.VERTICAL,
		)
		forms.check_box(
			sizer=options_box, parent=self, label='Peak Hold',
			ps=parent, key=PEAK_HOLD_KEY,
		)
		forms.check_box(
			sizer=options_box, parent=self, label='Average',
			ps=parent, key=AVERAGE_KEY,
		)
		#static text and slider for averaging
		avg_alpha_text = forms.static_text(
			sizer=options_box, parent=self, label='Avg Alpha',
			converter=forms.float_converter(lambda x: '%.4f'%x),
			ps=parent, key=AVG_ALPHA_KEY, width=50,
		)
		avg_alpha_slider = forms.log_slider(
			sizer=options_box, parent=self,
			min_exp=AVG_ALPHA_MIN_EXP,
			max_exp=AVG_ALPHA_MAX_EXP,
			num_steps=SLIDER_STEPS,
			ps=parent, key=AVG_ALPHA_KEY,
		)
		for widget in (avg_alpha_text, avg_alpha_slider):
			parent.subscribe(AVERAGE_KEY, widget.Enable)
			widget.Enable(parent[AVERAGE_KEY])
		#run/stop
		control_box.AddStretchSpacer()
		forms.toggle_button(
			sizer=control_box, parent=self,
			true_label='Stop', false_label='Run',
			ps=parent, key=RUNNING_KEY,
		)
		#set sizer
		self.SetSizerAndFit(control_box)
Example #2
0
    def __init__(self, parent):
        """
		Create a new control panel.

		Args:
		    parent: the wx parent window
		"""
        self.parent = parent
        wx.Panel.__init__(self, parent, style=wx.SUNKEN_BORDER)
        parent[SHOW_CONTROL_PANEL_KEY] = True
        parent.subscribe(SHOW_CONTROL_PANEL_KEY, self.Show)
        control_box = wx.BoxSizer(wx.VERTICAL)
        control_box.AddStretchSpacer()
        #checkboxes for average and peak hold
        options_box = forms.static_box_sizer(
            parent=self,
            sizer=control_box,
            label='Trace Options',
            bold=True,
            orient=wx.VERTICAL,
        )
        forms.check_box(
            sizer=options_box,
            parent=self,
            label='Peak Hold',
            ps=parent,
            key=PEAK_HOLD_KEY,
        )
        forms.check_box(
            sizer=options_box,
            parent=self,
            label='Average',
            ps=parent,
            key=AVERAGE_KEY,
        )
        #static text and slider for averaging
        avg_alpha_text = forms.static_text(
            sizer=options_box,
            parent=self,
            label='Avg Alpha',
            converter=forms.float_converter(lambda x: '%.4f' % x),
            ps=parent,
            key=AVG_ALPHA_KEY,
            width=50,
        )
        avg_alpha_slider = forms.log_slider(
            sizer=options_box,
            parent=self,
            min_exp=AVG_ALPHA_MIN_EXP,
            max_exp=AVG_ALPHA_MAX_EXP,
            num_steps=SLIDER_STEPS,
            ps=parent,
            key=AVG_ALPHA_KEY,
        )
        for widget in (avg_alpha_text, avg_alpha_slider):
            parent.subscribe(AVERAGE_KEY, widget.Enable)
            widget.Enable(parent[AVERAGE_KEY])
            parent.subscribe(AVERAGE_KEY, widget.ShowItems)
            #allways show initially, so room is reserved for them
            widget.ShowItems(True)  # (parent[AVERAGE_KEY])

        parent.subscribe(AVERAGE_KEY, self._update_layout)

        forms.check_box(
            sizer=options_box,
            parent=self,
            label='Persistence',
            ps=parent,
            key=USE_PERSISTENCE_KEY,
        )
        #static text and slider for persist alpha
        persist_alpha_text = forms.static_text(
            sizer=options_box,
            parent=self,
            label='Persist Alpha',
            converter=forms.float_converter(lambda x: '%.4f' % x),
            ps=parent,
            key=PERSIST_ALPHA_KEY,
            width=50,
        )
        persist_alpha_slider = forms.log_slider(
            sizer=options_box,
            parent=self,
            min_exp=PERSIST_ALPHA_MIN_EXP,
            max_exp=PERSIST_ALPHA_MAX_EXP,
            num_steps=SLIDER_STEPS,
            ps=parent,
            key=PERSIST_ALPHA_KEY,
        )
        for widget in (persist_alpha_text, persist_alpha_slider):
            parent.subscribe(USE_PERSISTENCE_KEY, widget.Enable)
            widget.Enable(parent[USE_PERSISTENCE_KEY])
            parent.subscribe(USE_PERSISTENCE_KEY, widget.ShowItems)
            #allways show initially, so room is reserved for them
            widget.ShowItems(True)  # (parent[USE_PERSISTENCE_KEY])

        parent.subscribe(USE_PERSISTENCE_KEY, self._update_layout)

        #trace menu
        for trace in TRACES:
            trace_box = wx.BoxSizer(wx.HORIZONTAL)
            options_box.Add(trace_box, 0, wx.EXPAND)
            forms.check_box(
                sizer=trace_box,
                parent=self,
                ps=parent,
                key=TRACE_SHOW_KEY + trace,
                label='Trace %s' % trace,
            )
            trace_box.AddSpacer(10)
            forms.single_button(
                sizer=trace_box,
                parent=self,
                ps=parent,
                key=TRACE_STORE_KEY + trace,
                label='Store',
                style=wx.BU_EXACTFIT,
            )
            trace_box.AddSpacer(10)
        #radio buttons for div size
        control_box.AddStretchSpacer()
        y_ctrl_box = forms.static_box_sizer(
            parent=self,
            sizer=control_box,
            label='Axis Options',
            bold=True,
            orient=wx.VERTICAL,
        )
        forms.incr_decr_buttons(
            parent=self,
            sizer=y_ctrl_box,
            label='dB/Div',
            on_incr=self._on_incr_db_div,
            on_decr=self._on_decr_db_div,
        )
        #ref lvl buttons
        forms.incr_decr_buttons(
            parent=self,
            sizer=y_ctrl_box,
            label='Ref Level',
            on_incr=self._on_incr_ref_level,
            on_decr=self._on_decr_ref_level,
        )
        y_ctrl_box.AddSpacer(2)
        #autoscale
        forms.single_button(
            sizer=y_ctrl_box,
            parent=self,
            label='Autoscale',
            callback=self.parent.autoscale,
        )
        #run/stop
        control_box.AddStretchSpacer()
        forms.toggle_button(
            sizer=control_box,
            parent=self,
            true_label='Stop',
            false_label='Run',
            ps=parent,
            key=RUNNING_KEY,
        )
        #set sizer
        self.SetSizerAndFit(control_box)

        #mouse wheel event
        def on_mouse_wheel(event):
            if event.GetWheelRotation() < 0: self._on_incr_ref_level(event)
            else: self._on_decr_ref_level(event)

        parent.plotter.Bind(wx.EVT_MOUSEWHEEL, on_mouse_wheel)
Example #3
0
    def __init__(self, parent):
        """
		Create a new control panel.

		Args:
		    parent: the wx parent window
		"""
        self.parent = parent
        wx.Panel.__init__(self, parent, style=wx.SUNKEN_BORDER)
        parent[SHOW_CONTROL_PANEL_KEY] = True
        parent.subscribe(SHOW_CONTROL_PANEL_KEY, self.Show)
        control_box = wx.BoxSizer(wx.VERTICAL)
        control_box.AddStretchSpacer()
        options_box = forms.static_box_sizer(
            parent=self,
            sizer=control_box,
            label='Options',
            bold=True,
            orient=wx.VERTICAL,
        )
        #average
        forms.check_box(
            sizer=options_box,
            parent=self,
            label='Average',
            ps=parent,
            key=AVERAGE_KEY,
        )
        avg_alpha_text = forms.static_text(
            sizer=options_box,
            parent=self,
            label='Avg Alpha',
            converter=forms.float_converter(lambda x: '%.4f' % x),
            ps=parent,
            key=AVG_ALPHA_KEY,
            width=50,
        )
        avg_alpha_slider = forms.log_slider(
            sizer=options_box,
            parent=self,
            min_exp=AVG_ALPHA_MIN_EXP,
            max_exp=AVG_ALPHA_MAX_EXP,
            num_steps=SLIDER_STEPS,
            ps=parent,
            key=AVG_ALPHA_KEY,
        )
        for widget in (avg_alpha_text, avg_alpha_slider):
            parent.subscribe(AVERAGE_KEY, widget.Enable)
            widget.Enable(parent[AVERAGE_KEY])
        #begin axes box
        control_box.AddStretchSpacer()
        axes_box = forms.static_box_sizer(
            parent=self,
            sizer=control_box,
            label='Axes Options',
            bold=True,
            orient=wx.VERTICAL,
        )
        #num lines buttons
        forms.incr_decr_buttons(
            parent=self,
            sizer=axes_box,
            label='Time Scale',
            on_incr=self._on_incr_time_scale,
            on_decr=self._on_decr_time_scale,
        )
        #dyanmic range buttons
        forms.incr_decr_buttons(
            parent=self,
            sizer=axes_box,
            label='Dyn Range',
            on_incr=self._on_incr_dynamic_range,
            on_decr=self._on_decr_dynamic_range,
        )
        #ref lvl buttons
        forms.incr_decr_buttons(
            parent=self,
            sizer=axes_box,
            label='Ref Level',
            on_incr=self._on_incr_ref_level,
            on_decr=self._on_decr_ref_level,
        )
        #color mode
        forms.drop_down(
            parent=self,
            sizer=axes_box,
            width=100,
            ps=parent,
            key=COLOR_MODE_KEY,
            label='Color',
            choices=map(lambda x: x[1], COLOR_MODES),
            labels=map(lambda x: x[0], COLOR_MODES),
        )
        #autoscale
        forms.single_button(
            parent=self,
            sizer=axes_box,
            label='Autoscale',
            callback=self.parent.autoscale,
        )
        #clear
        control_box.AddStretchSpacer()
        forms.single_button(
            parent=self,
            sizer=control_box,
            label='Clear',
            callback=self._on_clear_button,
        )
        #run/stop
        forms.toggle_button(
            sizer=control_box,
            parent=self,
            true_label='Stop',
            false_label='Run',
            ps=parent,
            key=RUNNING_KEY,
        )
        #set sizer
        self.SetSizerAndFit(control_box)
Example #4
0
    def __init__(self, parent):
        """
		Create a new control panel.
		@param parent the wx parent window
		"""
        WIDTH = 90
        self.parent = parent
        wx.Panel.__init__(self, parent, style=wx.SUNKEN_BORDER)
        parent[SHOW_CONTROL_PANEL_KEY] = True
        parent.subscribe(SHOW_CONTROL_PANEL_KEY, self.Show)
        control_box = wx.BoxSizer(wx.VERTICAL)

        ##################################################
        # Persistence
        ##################################################

        forms.check_box(
            sizer=control_box,
            parent=self,
            label='Persistence',
            ps=parent,
            key=USE_PERSISTENCE_KEY,
        )
        #static text and slider for analog alpha
        persist_alpha_text = forms.static_text(
            sizer=control_box,
            parent=self,
            label='Analog Alpha',
            converter=forms.float_converter(lambda x: '%.4f' % x),
            ps=parent,
            key=PERSIST_ALPHA_KEY,
            width=50,
        )
        persist_alpha_slider = forms.log_slider(
            sizer=control_box,
            parent=self,
            min_exp=PERSIST_ALPHA_MIN_EXP,
            max_exp=PERSIST_ALPHA_MAX_EXP,
            num_steps=SLIDER_STEPS,
            ps=parent,
            key=PERSIST_ALPHA_KEY,
        )
        for widget in (persist_alpha_text, persist_alpha_slider):
            parent.subscribe(USE_PERSISTENCE_KEY, widget.Enable)
            widget.Enable(parent[USE_PERSISTENCE_KEY])
            parent.subscribe(USE_PERSISTENCE_KEY, widget.ShowItems)
            #allways show initially, so room is reserved for them
            widget.ShowItems(True)  # (parent[USE_PERSISTENCE_KEY])

        parent.subscribe(USE_PERSISTENCE_KEY, self._update_layout)

        ##################################################
        # Axes Options
        ##################################################
        control_box.AddStretchSpacer()
        axes_options_box = forms.static_box_sizer(
            parent=self,
            sizer=control_box,
            label='Axes Options',
            bold=True,
            orient=wx.VERTICAL,
        )
        ##################################################
        # Scope Mode Box
        ##################################################
        scope_mode_box = wx.BoxSizer(wx.VERTICAL)
        axes_options_box.Add(scope_mode_box, 0, wx.EXPAND)
        #x axis divs
        forms.incr_decr_buttons(
            parent=self,
            sizer=scope_mode_box,
            label='Secs/Div',
            on_incr=self._on_incr_t_divs,
            on_decr=self._on_decr_t_divs,
        )
        #y axis divs
        y_buttons_scope = forms.incr_decr_buttons(
            parent=self,
            sizer=scope_mode_box,
            label='Counts/Div',
            on_incr=self._on_incr_y_divs,
            on_decr=self._on_decr_y_divs,
        )
        #y axis ref lvl
        y_off_buttons_scope = forms.incr_decr_buttons(
            parent=self,
            sizer=scope_mode_box,
            label='Y Offset',
            on_incr=self._on_incr_y_off,
            on_decr=self._on_decr_y_off,
        )
        #t axis ref lvl
        scope_mode_box.AddSpacer(5)
        forms.slider(
            parent=self,
            sizer=scope_mode_box,
            ps=parent,
            key=T_FRAC_OFF_KEY,
            label='T Offset',
            minimum=0,
            maximum=1,
            num_steps=1000,
        )
        scope_mode_box.AddSpacer(5)
        ##################################################
        # XY Mode Box
        ##################################################
        xy_mode_box = wx.BoxSizer(wx.VERTICAL)
        axes_options_box.Add(xy_mode_box, 0, wx.EXPAND)
        #x div controls
        x_buttons = forms.incr_decr_buttons(
            parent=self,
            sizer=xy_mode_box,
            label='X/Div',
            on_incr=self._on_incr_x_divs,
            on_decr=self._on_decr_x_divs,
        )
        #y div controls
        y_buttons = forms.incr_decr_buttons(
            parent=self,
            sizer=xy_mode_box,
            label='Y/Div',
            on_incr=self._on_incr_y_divs,
            on_decr=self._on_decr_y_divs,
        )
        #x offset controls
        x_off_buttons = forms.incr_decr_buttons(
            parent=self,
            sizer=xy_mode_box,
            label='X Off',
            on_incr=self._on_incr_x_off,
            on_decr=self._on_decr_x_off,
        )
        #y offset controls
        y_off_buttons = forms.incr_decr_buttons(
            parent=self,
            sizer=xy_mode_box,
            label='Y Off',
            on_incr=self._on_incr_y_off,
            on_decr=self._on_decr_y_off,
        )
        for widget in (y_buttons_scope, y_off_buttons_scope, x_buttons,
                       y_buttons, x_off_buttons, y_off_buttons):
            parent.subscribe(AUTORANGE_KEY, widget.Disable)
            widget.Disable(parent[AUTORANGE_KEY])
        xy_mode_box.ShowItems(False)
        #autorange check box
        forms.check_box(
            parent=self,
            sizer=axes_options_box,
            label='Autorange',
            ps=parent,
            key=AUTORANGE_KEY,
        )
        ##################################################
        # Channel Options
        ##################################################
        TRIGGER_PAGE_INDEX = parent.num_inputs
        XY_PAGE_INDEX = parent.num_inputs + 1
        control_box.AddStretchSpacer()
        chan_options_box = forms.static_box_sizer(
            parent=self,
            sizer=control_box,
            label='Channel Options',
            bold=True,
            orient=wx.VERTICAL,
        )
        options_notebook = wx.Notebook(self)
        options_notebook_args = list()
        CHANNELS = [('Ch %d' % (i + 1), i) for i in range(parent.num_inputs)]
        ##################################################
        # Channel Menu Boxes
        ##################################################
        for i in range(parent.num_inputs):
            channel_menu_panel = wx.Panel(options_notebook)
            options_notebook_args.append(
                (channel_menu_panel, i, 'Ch%d' % (i + 1)))
            channel_menu_box = wx.BoxSizer(wx.VERTICAL)
            channel_menu_panel.SetSizer(channel_menu_box)
            #ac couple check box
            channel_menu_box.AddStretchSpacer()
            forms.drop_down(
                parent=channel_menu_panel,
                sizer=channel_menu_box,
                ps=parent,
                key=common.index_key(AC_COUPLE_KEY, i),
                choices=map(lambda x: x[1], COUPLING_MODES),
                labels=map(lambda x: x[0], COUPLING_MODES),
                label='Coupling',
                width=WIDTH,
            )
            #marker
            channel_menu_box.AddStretchSpacer()
            forms.drop_down(
                parent=channel_menu_panel,
                sizer=channel_menu_box,
                ps=parent,
                key=common.index_key(MARKER_KEY, i),
                choices=map(lambda x: x[1], MARKER_TYPES),
                labels=map(lambda x: x[0], MARKER_TYPES),
                label='Marker',
                width=WIDTH,
            )
            channel_menu_box.AddStretchSpacer()
        ##################################################
        # Trigger Menu Box
        ##################################################
        trigger_menu_panel = wx.Panel(options_notebook)
        options_notebook_args.append(
            (trigger_menu_panel, TRIGGER_PAGE_INDEX, 'Trig'))
        trigger_menu_box = wx.BoxSizer(wx.VERTICAL)
        trigger_menu_panel.SetSizer(trigger_menu_box)
        #trigger mode
        forms.drop_down(
            parent=trigger_menu_panel,
            sizer=trigger_menu_box,
            ps=parent,
            key=TRIGGER_MODE_KEY,
            choices=map(lambda x: x[1], TRIGGER_MODES),
            labels=map(lambda x: x[0], TRIGGER_MODES),
            label='Mode',
            width=WIDTH,
        )
        #trigger slope
        trigger_slope_chooser = forms.drop_down(
            parent=trigger_menu_panel,
            sizer=trigger_menu_box,
            ps=parent,
            key=TRIGGER_SLOPE_KEY,
            choices=map(lambda x: x[1], TRIGGER_SLOPES),
            labels=map(lambda x: x[0], TRIGGER_SLOPES),
            label='Slope',
            width=WIDTH,
        )
        #trigger channel
        trigger_channel_chooser = forms.drop_down(
            parent=trigger_menu_panel,
            sizer=trigger_menu_box,
            ps=parent,
            key=TRIGGER_CHANNEL_KEY,
            choices=map(lambda x: x[1], CHANNELS),
            labels=map(lambda x: x[0], CHANNELS),
            label='Channel',
            width=WIDTH,
        )
        #trigger level
        hbox = wx.BoxSizer(wx.HORIZONTAL)
        trigger_menu_box.Add(hbox, 0, wx.EXPAND)
        hbox.Add(wx.StaticText(trigger_menu_panel, label='Level:'), 1,
                 wx.ALIGN_CENTER_VERTICAL)
        trigger_level_button = forms.single_button(
            parent=trigger_menu_panel,
            sizer=hbox,
            label='50%',
            callback=parent.set_auto_trigger_level,
            style=wx.BU_EXACTFIT,
        )
        hbox.AddSpacer(WIDTH - 60)
        trigger_level_buttons = forms.incr_decr_buttons(
            parent=trigger_menu_panel,
            sizer=hbox,
            on_incr=self._on_incr_trigger_level,
            on_decr=self._on_decr_trigger_level,
        )

        def disable_all(trigger_mode):
            for widget in (trigger_slope_chooser, trigger_channel_chooser,
                           trigger_level_buttons, trigger_level_button):
                widget.Disable(trigger_mode == gr.gr_TRIG_MODE_FREE)

        parent.subscribe(TRIGGER_MODE_KEY, disable_all)
        disable_all(parent[TRIGGER_MODE_KEY])
        ##################################################
        # XY Menu Box
        ##################################################
        if parent.num_inputs > 1:
            xy_menu_panel = wx.Panel(options_notebook)
            options_notebook_args.append((xy_menu_panel, XY_PAGE_INDEX, 'XY'))
            xy_menu_box = wx.BoxSizer(wx.VERTICAL)
            xy_menu_panel.SetSizer(xy_menu_box)
            #x and y channel choosers
            xy_menu_box.AddStretchSpacer()
            forms.drop_down(
                parent=xy_menu_panel,
                sizer=xy_menu_box,
                ps=parent,
                key=X_CHANNEL_KEY,
                choices=map(lambda x: x[1], CHANNELS),
                labels=map(lambda x: x[0], CHANNELS),
                label='Channel X',
                width=WIDTH,
            )
            xy_menu_box.AddStretchSpacer()
            forms.drop_down(
                parent=xy_menu_panel,
                sizer=xy_menu_box,
                ps=parent,
                key=Y_CHANNEL_KEY,
                choices=map(lambda x: x[1], CHANNELS),
                labels=map(lambda x: x[0], CHANNELS),
                label='Channel Y',
                width=WIDTH,
            )
            #marker
            xy_menu_box.AddStretchSpacer()
            forms.drop_down(
                parent=xy_menu_panel,
                sizer=xy_menu_box,
                ps=parent,
                key=XY_MARKER_KEY,
                choices=map(lambda x: x[1], MARKER_TYPES),
                labels=map(lambda x: x[0], MARKER_TYPES),
                label='Marker',
                width=WIDTH,
            )
            xy_menu_box.AddStretchSpacer()
        ##################################################
        # Setup Options Notebook
        ##################################################
        forms.notebook(
            parent=self,
            sizer=chan_options_box,
            notebook=options_notebook,
            ps=parent,
            key=CHANNEL_OPTIONS_KEY,
            pages=map(lambda x: x[0], options_notebook_args),
            choices=map(lambda x: x[1], options_notebook_args),
            labels=map(lambda x: x[2], options_notebook_args),
        )

        #gui handling for channel options changing
        def options_notebook_changed(chan_opt):
            try:
                parent[TRIGGER_SHOW_KEY] = chan_opt == TRIGGER_PAGE_INDEX
                parent[XY_MODE_KEY] = chan_opt == XY_PAGE_INDEX
            except wx.PyDeadObjectError:
                pass

        parent.subscribe(CHANNEL_OPTIONS_KEY, options_notebook_changed)

        #gui handling for xy mode changing
        def xy_mode_changed(mode):
            #ensure xy tab is selected
            if mode and parent[CHANNEL_OPTIONS_KEY] != XY_PAGE_INDEX:
                parent[CHANNEL_OPTIONS_KEY] = XY_PAGE_INDEX
            #ensure xy tab is not selected
            elif not mode and parent[CHANNEL_OPTIONS_KEY] == XY_PAGE_INDEX:
                parent[CHANNEL_OPTIONS_KEY] = 0
            #show/hide control buttons
            scope_mode_box.ShowItems(not mode)
            xy_mode_box.ShowItems(mode)
            control_box.Layout()

        parent.subscribe(XY_MODE_KEY, xy_mode_changed)
        xy_mode_changed(parent[XY_MODE_KEY])
        ##################################################
        # Run/Stop Button
        ##################################################
        #run/stop
        control_box.AddStretchSpacer()
        forms.toggle_button(
            sizer=control_box,
            parent=self,
            true_label='Stop',
            false_label='Run',
            ps=parent,
            key=RUNNING_KEY,
        )
        #set sizer
        self.SetSizerAndFit(control_box)

        #mouse wheel event
        def on_mouse_wheel(event):
            if not parent[XY_MODE_KEY]:
                if event.GetWheelRotation() < 0: self._on_incr_t_divs(event)
                else: self._on_decr_t_divs(event)

        parent.plotter.Bind(wx.EVT_MOUSEWHEEL, on_mouse_wheel)
Example #5
0
	def __init__(self, parent):
		"""
		Create a new control panel.

                Args:
		    parent: the wx parent window
		"""
		WIDTH = 90
		self.parent = parent
		wx.Panel.__init__(self, parent, style=wx.SUNKEN_BORDER)
		parent[SHOW_CONTROL_PANEL_KEY] = True
		parent.subscribe(SHOW_CONTROL_PANEL_KEY, self.Show)
		control_box = wx.BoxSizer(wx.VERTICAL)

		##################################################
		# Persistence
		##################################################

		forms.check_box(
			sizer=control_box, parent=self, label='Persistence',
			ps=parent, key=USE_PERSISTENCE_KEY,
		)
		#static text and slider for analog alpha
		persist_alpha_text = forms.static_text(
			sizer=control_box, parent=self, label='Analog Alpha',
			converter=forms.float_converter(lambda x: '%.4f'%x),
			ps=parent, key=PERSIST_ALPHA_KEY, width=50,
		)
		persist_alpha_slider = forms.log_slider(
			sizer=control_box, parent=self,
			min_exp=PERSIST_ALPHA_MIN_EXP,
			max_exp=PERSIST_ALPHA_MAX_EXP,
			num_steps=SLIDER_STEPS,
			ps=parent, key=PERSIST_ALPHA_KEY,
		)
		for widget in (persist_alpha_text, persist_alpha_slider):
			parent.subscribe(USE_PERSISTENCE_KEY, widget.Enable)
			widget.Enable(parent[USE_PERSISTENCE_KEY])
			parent.subscribe(USE_PERSISTENCE_KEY, widget.ShowItems)
                        #always show initially, so room is reserved for them
			widget.ShowItems(True) # (parent[USE_PERSISTENCE_KEY])

                parent.subscribe(USE_PERSISTENCE_KEY, self._update_layout)

		##################################################
		# Axes Options
		##################################################
		control_box.AddStretchSpacer()
		axes_options_box = forms.static_box_sizer(
			parent=self, sizer=control_box, label='Axes Options',
			bold=True, orient=wx.VERTICAL,
		)
		##################################################
		# Scope Mode Box
		##################################################
		scope_mode_box = wx.BoxSizer(wx.VERTICAL)
		axes_options_box.Add(scope_mode_box, 0, wx.EXPAND)
		#x axis divs
		forms.incr_decr_buttons(
			parent=self, sizer=scope_mode_box, label='Secs/Div',
			on_incr=self._on_incr_t_divs, on_decr=self._on_decr_t_divs,
		)
		#y axis divs
		y_buttons_scope = forms.incr_decr_buttons(
			parent=self, sizer=scope_mode_box, label='Counts/Div',
			on_incr=self._on_incr_y_divs, on_decr=self._on_decr_y_divs,
		)
		#y axis ref lvl
		y_off_buttons_scope = forms.incr_decr_buttons(
			parent=self, sizer=scope_mode_box, label='Y Offset',
			on_incr=self._on_incr_y_off, on_decr=self._on_decr_y_off,
		)
		#t axis ref lvl
		scope_mode_box.AddSpacer(5)
		forms.slider(
			parent=self, sizer=scope_mode_box,
			ps=parent, key=T_FRAC_OFF_KEY, label='T Offset',
			minimum=0, maximum=1, num_steps=1000,
		)
		scope_mode_box.AddSpacer(5)
		##################################################
		# XY Mode Box
		##################################################
		xy_mode_box = wx.BoxSizer(wx.VERTICAL)
		axes_options_box.Add(xy_mode_box, 0, wx.EXPAND)
		#x div controls
		x_buttons = forms.incr_decr_buttons(
			parent=self, sizer=xy_mode_box, label='X/Div',
			on_incr=self._on_incr_x_divs, on_decr=self._on_decr_x_divs,
		)
		#y div controls
		y_buttons = forms.incr_decr_buttons(
			parent=self, sizer=xy_mode_box, label='Y/Div',
			on_incr=self._on_incr_y_divs, on_decr=self._on_decr_y_divs,
		)
		#x offset controls
		x_off_buttons = forms.incr_decr_buttons(
			parent=self, sizer=xy_mode_box, label='X Off',
			on_incr=self._on_incr_x_off, on_decr=self._on_decr_x_off,
		)
		#y offset controls
		y_off_buttons = forms.incr_decr_buttons(
			parent=self, sizer=xy_mode_box, label='Y Off',
			on_incr=self._on_incr_y_off, on_decr=self._on_decr_y_off,
		)
		for widget in (y_buttons_scope, y_off_buttons_scope, x_buttons, y_buttons, x_off_buttons, y_off_buttons):
			parent.subscribe(AUTORANGE_KEY, widget.Disable)
			widget.Disable(parent[AUTORANGE_KEY])
		xy_mode_box.ShowItems(False)
		#autorange check box
		forms.check_box(
			parent=self, sizer=axes_options_box, label='Autorange',
			ps=parent, key=AUTORANGE_KEY,
		)
		##################################################
		# Channel Options
		##################################################
		TRIGGER_PAGE_INDEX = parent.num_inputs
		XY_PAGE_INDEX = parent.num_inputs+1
		control_box.AddStretchSpacer()
		chan_options_box = forms.static_box_sizer(
			parent=self, sizer=control_box, label='Channel Options',
			bold=True, orient=wx.VERTICAL,
		)
		options_notebook = wx.Notebook(self)
		options_notebook_args = list()
		CHANNELS = [('Ch %d'%(i+1), i) for i in range(parent.num_inputs)]
		##################################################
		# Channel Menu Boxes
		##################################################
		for i in range(parent.num_inputs):
			channel_menu_panel = wx.Panel(options_notebook)
			options_notebook_args.append((channel_menu_panel, i, 'Ch%d'%(i+1)))
			channel_menu_box = wx.BoxSizer(wx.VERTICAL)
			channel_menu_panel.SetSizer(channel_menu_box)
			#ac couple check box
			channel_menu_box.AddStretchSpacer()
			forms.drop_down(
				parent=channel_menu_panel, sizer=channel_menu_box,
				ps=parent, key=common.index_key(AC_COUPLE_KEY, i),
				choices=map(lambda x: x[1], COUPLING_MODES),
				labels=map(lambda x: x[0], COUPLING_MODES),
				label='Coupling', width=WIDTH,
			)
			#marker
			channel_menu_box.AddStretchSpacer()
			forms.drop_down(
				parent=channel_menu_panel, sizer=channel_menu_box,
				ps=parent, key=common.index_key(MARKER_KEY, i),
				choices=map(lambda x: x[1], MARKER_TYPES),
				labels=map(lambda x: x[0], MARKER_TYPES),
				label='Marker', width=WIDTH,
			)
			channel_menu_box.AddStretchSpacer()
		##################################################
		# Trigger Menu Box
		##################################################
		trigger_menu_panel = wx.Panel(options_notebook)
		options_notebook_args.append((trigger_menu_panel, TRIGGER_PAGE_INDEX, 'Trig'))
		trigger_menu_box = wx.BoxSizer(wx.VERTICAL)
		trigger_menu_panel.SetSizer(trigger_menu_box)
		#trigger mode
		forms.drop_down(
			parent=trigger_menu_panel, sizer=trigger_menu_box,
			ps=parent, key=TRIGGER_MODE_KEY,
			choices=map(lambda x: x[1], TRIGGER_MODES),
			labels=map(lambda x: x[0], TRIGGER_MODES),
			label='Mode', width=WIDTH,
		)
		#trigger slope
		trigger_slope_chooser = forms.drop_down(
			parent=trigger_menu_panel, sizer=trigger_menu_box,
			ps=parent, key=TRIGGER_SLOPE_KEY,
			choices=map(lambda x: x[1], TRIGGER_SLOPES),
			labels=map(lambda x: x[0], TRIGGER_SLOPES),
			label='Slope', width=WIDTH,
		)
		#trigger channel
		trigger_channel_chooser = forms.drop_down(
			parent=trigger_menu_panel, sizer=trigger_menu_box,
			ps=parent, key=TRIGGER_CHANNEL_KEY,
			choices=map(lambda x: x[1], CHANNELS),
			labels=map(lambda x: x[0], CHANNELS),
			label='Channel', width=WIDTH,
		)
		#trigger level
		hbox = wx.BoxSizer(wx.HORIZONTAL)
		trigger_menu_box.Add(hbox, 0, wx.EXPAND)
		hbox.Add(wx.StaticText(trigger_menu_panel, label='Level:'), 1, wx.ALIGN_CENTER_VERTICAL)
		trigger_level_button = forms.single_button(
			parent=trigger_menu_panel, sizer=hbox, label='50%',
			callback=parent.set_auto_trigger_level, style=wx.BU_EXACTFIT,
		)
		hbox.AddSpacer(WIDTH-60)
		trigger_level_buttons = forms.incr_decr_buttons(
			parent=trigger_menu_panel, sizer=hbox,
			on_incr=self._on_incr_trigger_level, on_decr=self._on_decr_trigger_level,
		)
		def disable_all(trigger_mode):
			for widget in (trigger_slope_chooser, trigger_channel_chooser, trigger_level_buttons, trigger_level_button):
				widget.Disable(trigger_mode == wxgui.TRIG_MODE_FREE)
		parent.subscribe(TRIGGER_MODE_KEY, disable_all)
		disable_all(parent[TRIGGER_MODE_KEY])
		##################################################
		# XY Menu Box
		##################################################
		if parent.num_inputs > 1:
			xy_menu_panel = wx.Panel(options_notebook)
			options_notebook_args.append((xy_menu_panel, XY_PAGE_INDEX, 'XY'))
			xy_menu_box = wx.BoxSizer(wx.VERTICAL)
			xy_menu_panel.SetSizer(xy_menu_box)
			#x and y channel choosers
			xy_menu_box.AddStretchSpacer()
			forms.drop_down(
				parent=xy_menu_panel, sizer=xy_menu_box,
				ps=parent, key=X_CHANNEL_KEY,
				choices=map(lambda x: x[1], CHANNELS),
				labels=map(lambda x: x[0], CHANNELS),
				label='Channel X', width=WIDTH,
			)
			xy_menu_box.AddStretchSpacer()
			forms.drop_down(
				parent=xy_menu_panel, sizer=xy_menu_box,
				ps=parent, key=Y_CHANNEL_KEY,
				choices=map(lambda x: x[1], CHANNELS),
				labels=map(lambda x: x[0], CHANNELS),
				label='Channel Y', width=WIDTH,
			)
			#marker
			xy_menu_box.AddStretchSpacer()
			forms.drop_down(
				parent=xy_menu_panel, sizer=xy_menu_box,
				ps=parent, key=XY_MARKER_KEY,
				choices=map(lambda x: x[1], MARKER_TYPES),
				labels=map(lambda x: x[0], MARKER_TYPES),
				label='Marker', width=WIDTH,
			)
			xy_menu_box.AddStretchSpacer()
		##################################################
		# Setup Options Notebook
		##################################################
		forms.notebook(
			parent=self, sizer=chan_options_box,
			notebook=options_notebook,
			ps=parent, key=CHANNEL_OPTIONS_KEY,
			pages=map(lambda x: x[0], options_notebook_args),
			choices=map(lambda x: x[1], options_notebook_args),
			labels=map(lambda x: x[2], options_notebook_args),
		)
		#gui handling for channel options changing
		def options_notebook_changed(chan_opt):
			try:
				parent[TRIGGER_SHOW_KEY] = chan_opt == TRIGGER_PAGE_INDEX
				parent[XY_MODE_KEY] = chan_opt == XY_PAGE_INDEX
			except wx.PyDeadObjectError: pass
		parent.subscribe(CHANNEL_OPTIONS_KEY, options_notebook_changed)
		#gui handling for xy mode changing
		def xy_mode_changed(mode):
			#ensure xy tab is selected
			if mode and parent[CHANNEL_OPTIONS_KEY] != XY_PAGE_INDEX:
				parent[CHANNEL_OPTIONS_KEY] = XY_PAGE_INDEX
			#ensure xy tab is not selected
			elif not mode and parent[CHANNEL_OPTIONS_KEY] == XY_PAGE_INDEX:
				parent[CHANNEL_OPTIONS_KEY] = 0
			#show/hide control buttons
			scope_mode_box.ShowItems(not mode)
			xy_mode_box.ShowItems(mode)
			control_box.Layout()
		parent.subscribe(XY_MODE_KEY, xy_mode_changed)
		xy_mode_changed(parent[XY_MODE_KEY])
		##################################################
		# Run/Stop Button
		##################################################
		#run/stop
		control_box.AddStretchSpacer()
		forms.toggle_button(
			sizer=control_box, parent=self,
			true_label='Stop', false_label='Run',
			ps=parent, key=RUNNING_KEY,
		)
		#set sizer
		self.SetSizerAndFit(control_box)
		#mouse wheel event
		def on_mouse_wheel(event):
			if not parent[XY_MODE_KEY]:
				if event.GetWheelRotation() < 0: self._on_incr_t_divs(event)
				else: self._on_decr_t_divs(event)
		parent.plotter.Bind(wx.EVT_MOUSEWHEEL, on_mouse_wheel)
Example #6
0
	def __init__(self, parent):
		"""
		Create a new control panel.
		@param parent the wx parent window
		"""
		self.parent = parent
		wx.Panel.__init__(self, parent, style=wx.SUNKEN_BORDER)
		parent[SHOW_CONTROL_PANEL_KEY] = True
		parent.subscribe(SHOW_CONTROL_PANEL_KEY, self.Show)
		control_box = wx.BoxSizer(wx.VERTICAL)
		control_box.AddStretchSpacer()
		#checkboxes for average and peak hold
		options_box = forms.static_box_sizer(
			parent=self, sizer=control_box, label='Trace Options',
			bold=True, orient=wx.VERTICAL,
		)
		forms.check_box(
			sizer=options_box, parent=self, label='Peak Hold',
			ps=parent, key=PEAK_HOLD_KEY,
		)
		forms.check_box(
			sizer=options_box, parent=self, label='Average',
			ps=parent, key=AVERAGE_KEY,
		)
		#static text and slider for averaging
		avg_alpha_text = forms.static_text(
			sizer=options_box, parent=self, label='Avg Alpha',
			converter=forms.float_converter(lambda x: '%.4f'%x),
			ps=parent, key=AVG_ALPHA_KEY, width=50,
		)
		avg_alpha_slider = forms.log_slider(
			sizer=options_box, parent=self,
			min_exp=AVG_ALPHA_MIN_EXP,
			max_exp=AVG_ALPHA_MAX_EXP,
			num_steps=SLIDER_STEPS,
			ps=parent, key=AVG_ALPHA_KEY,
		)
		for widget in (avg_alpha_text, avg_alpha_slider):
			parent.subscribe(AVERAGE_KEY, widget.Enable)
			widget.Enable(parent[AVERAGE_KEY])
			parent.subscribe(AVERAGE_KEY, widget.ShowItems)
                        #allways show initially, so room is reserved for them
			widget.ShowItems(True) # (parent[AVERAGE_KEY])

                parent.subscribe(AVERAGE_KEY, self._update_layout)

		forms.check_box(
			sizer=options_box, parent=self, label='Persistence',
			ps=parent, key=USE_PERSISTENCE_KEY,
		)
		#static text and slider for persist alpha
		persist_alpha_text = forms.static_text(
			sizer=options_box, parent=self, label='Persist Alpha',
			converter=forms.float_converter(lambda x: '%.4f'%x),
			ps=parent, key=PERSIST_ALPHA_KEY, width=50,
		)
		persist_alpha_slider = forms.log_slider(
			sizer=options_box, parent=self,
			min_exp=PERSIST_ALPHA_MIN_EXP,
			max_exp=PERSIST_ALPHA_MAX_EXP,
			num_steps=SLIDER_STEPS,
			ps=parent, key=PERSIST_ALPHA_KEY,
		)
		for widget in (persist_alpha_text, persist_alpha_slider):
			parent.subscribe(USE_PERSISTENCE_KEY, widget.Enable)
			widget.Enable(parent[USE_PERSISTENCE_KEY])
			parent.subscribe(USE_PERSISTENCE_KEY, widget.ShowItems)
                        #allways show initially, so room is reserved for them
			widget.ShowItems(True) # (parent[USE_PERSISTENCE_KEY])

                parent.subscribe(USE_PERSISTENCE_KEY, self._update_layout)

		#trace menu
		for trace in TRACES:
			trace_box = wx.BoxSizer(wx.HORIZONTAL)
			options_box.Add(trace_box, 0, wx.EXPAND)
			forms.check_box(
				sizer=trace_box, parent=self,
				ps=parent, key=TRACE_SHOW_KEY+trace,
				label='Trace %s'%trace,
			)
			trace_box.AddSpacer(10)
			forms.single_button(
				sizer=trace_box, parent=self,
				ps=parent, key=TRACE_STORE_KEY+trace,
				label='Store', style=wx.BU_EXACTFIT,
			)
			trace_box.AddSpacer(10)
		#radio buttons for div size
		control_box.AddStretchSpacer()
		y_ctrl_box = forms.static_box_sizer(
			parent=self, sizer=control_box, label='Axis Options',
			bold=True, orient=wx.VERTICAL,
		)
		forms.incr_decr_buttons(
			parent=self, sizer=y_ctrl_box, label='dB/Div',
			on_incr=self._on_incr_db_div, on_decr=self._on_decr_db_div,
		)
		#ref lvl buttons
		forms.incr_decr_buttons(
			parent=self, sizer=y_ctrl_box, label='Ref Level',
			on_incr=self._on_incr_ref_level, on_decr=self._on_decr_ref_level,
		)
		y_ctrl_box.AddSpacer(2)
		#autoscale
		forms.single_button(
			sizer=y_ctrl_box, parent=self, label='Autoscale',
			callback=self.parent.autoscale,
		)
		#run/stop
		control_box.AddStretchSpacer()
		forms.toggle_button(
			sizer=control_box, parent=self,
			true_label='Stop', false_label='Run',
			ps=parent, key=RUNNING_KEY,
		)
		#set sizer
		self.SetSizerAndFit(control_box)

		#mouse wheel event
		def on_mouse_wheel(event):
			if event.GetWheelRotation() < 0: self._on_incr_ref_level(event)
			else: self._on_decr_ref_level(event)
		parent.plotter.Bind(wx.EVT_MOUSEWHEEL, on_mouse_wheel)
Example #7
0
    def __init__(self, parent):
        """
		Create a new control panel.
		
		Args:
		    parent: the wx parent window
		"""
        self.parent = parent
        wx.Panel.__init__(self, parent)
        parent[SHOW_CONTROL_PANEL_KEY] = True
        parent.subscribe(SHOW_CONTROL_PANEL_KEY, self.Show)
        control_box = wx.BoxSizer(wx.VERTICAL)
        #checkboxes for average and peak hold
        control_box.AddStretchSpacer()
        options_box = forms.static_box_sizer(
            parent=self,
            sizer=control_box,
            label='Options',
            bold=True,
            orient=wx.VERTICAL,
        )
        forms.check_box(
            sizer=options_box,
            parent=self,
            label='Peak Hold',
            ps=parent,
            key=PEAK_HOLD_KEY,
        )
        forms.check_box(
            sizer=options_box,
            parent=self,
            label='Average',
            ps=parent,
            key=AVERAGE_KEY,
        )
        #static text and slider for averaging
        avg_alpha_text = forms.static_text(
            sizer=options_box,
            parent=self,
            label='Avg Alpha',
            converter=forms.float_converter(lambda x: '%.4f' % x),
            ps=parent,
            key=AVG_ALPHA_KEY,
            width=50,
        )
        avg_alpha_slider = forms.log_slider(
            sizer=options_box,
            parent=self,
            min_exp=AVG_ALPHA_MIN_EXP,
            max_exp=AVG_ALPHA_MAX_EXP,
            num_steps=SLIDER_STEPS,
            ps=parent,
            key=AVG_ALPHA_KEY,
        )
        for widget in (avg_alpha_text, avg_alpha_slider):
            parent.subscribe(AVERAGE_KEY, widget.Enable)
            widget.Enable(parent[AVERAGE_KEY])
        #run/stop
        control_box.AddStretchSpacer()
        forms.toggle_button(
            sizer=control_box,
            parent=self,
            true_label='Stop',
            false_label='Run',
            ps=parent,
            key=RUNNING_KEY,
        )
        #set sizer
        self.SetSizerAndFit(control_box)
Example #8
0
	def __init__(self, parent):
		"""
		Create a new control panel.
		@param parent the wx parent window
		"""
		self.parent = parent
		wx.Panel.__init__(self, parent, style=wx.SUNKEN_BORDER)
		parent[SHOW_CONTROL_PANEL_KEY] = True
		parent.subscribe(SHOW_CONTROL_PANEL_KEY, self.Show)
		control_box = wx.BoxSizer(wx.VERTICAL)
		control_box.AddStretchSpacer()
		options_box = forms.static_box_sizer(
			parent=self, sizer=control_box, label='Options',
			bold=True, orient=wx.VERTICAL,
		)
		#average
		forms.check_box(
			sizer=options_box, parent=self, label='Average',
			ps=parent, key=AVERAGE_KEY,
		)
		avg_alpha_text = forms.static_text(
			sizer=options_box, parent=self, label='Avg Alpha',
			converter=forms.float_converter(lambda x: '%.4f'%x),
			ps=parent, key=AVG_ALPHA_KEY, width=50,
		)
		avg_alpha_slider = forms.log_slider(
			sizer=options_box, parent=self,
			min_exp=AVG_ALPHA_MIN_EXP,
			max_exp=AVG_ALPHA_MAX_EXP,
			num_steps=SLIDER_STEPS,
			ps=parent, key=AVG_ALPHA_KEY,
		)
		for widget in (avg_alpha_text, avg_alpha_slider):
			parent.subscribe(AVERAGE_KEY, widget.Enable)
			widget.Enable(parent[AVERAGE_KEY])
		#begin axes box
		control_box.AddStretchSpacer()
		axes_box = forms.static_box_sizer(
			parent=self, sizer=control_box, label='Axes Options',
			bold=True, orient=wx.VERTICAL,
		)
		#num lines buttons
		forms.incr_decr_buttons(
			parent=self, sizer=axes_box, label='Time Scale',
			on_incr=self._on_incr_time_scale, on_decr=self._on_decr_time_scale,
		)
		#dyanmic range buttons
		forms.incr_decr_buttons(
			parent=self, sizer=axes_box, label='Dyn Range',
			on_incr=self._on_incr_dynamic_range, on_decr=self._on_decr_dynamic_range,
		)
		#ref lvl buttons
		forms.incr_decr_buttons(
			parent=self, sizer=axes_box, label='Ref Level',
			on_incr=self._on_incr_ref_level, on_decr=self._on_decr_ref_level,
		)
		#color mode
		forms.drop_down(
			parent=self, sizer=axes_box, width=100,
			ps=parent, key=COLOR_MODE_KEY, label='Color',
			choices=map(lambda x: x[1], COLOR_MODES),
			labels=map(lambda x: x[0], COLOR_MODES),
		)
		#autoscale
		forms.single_button(
			parent=self, sizer=axes_box, label='Autoscale',
			callback=self.parent.autoscale,
		)
		#clear
		control_box.AddStretchSpacer()
		forms.single_button(
			parent=self, sizer=control_box, label='Clear',
			callback=self._on_clear_button,
		)
		#run/stop
		forms.toggle_button(
			sizer=control_box, parent=self,
			true_label='Stop', false_label='Run',
			ps=parent, key=RUNNING_KEY,
		)
		#set sizer
		self.SetSizerAndFit(control_box)
Example #9
0
    def __init__(self, parent):
        """
		Create a new control panel.
		@param parent the wx parent window
		"""
        self.parent = parent
        wx.Panel.__init__(self, parent, style=wx.SUNKEN_BORDER)
        control_box = wx.BoxSizer(wx.VERTICAL)
        control_box.AddStretchSpacer()
        # checkboxes for average and peak hold
        options_box = forms.static_box_sizer(
            parent=self, sizer=control_box, label="Options", bold=True, orient=wx.VERTICAL
        )
        forms.check_box(sizer=options_box, parent=self, label="Peak Hold", ps=parent, key=PEAK_HOLD_KEY)
        forms.check_box(sizer=options_box, parent=self, label="Average", ps=parent, key=AVERAGE_KEY)
        # static text and slider for averaging
        avg_alpha_text = forms.static_text(
            sizer=options_box,
            parent=self,
            label="Avg Alpha",
            converter=forms.float_converter(lambda x: "%.4f" % x),
            ps=parent,
            key=AVG_ALPHA_KEY,
            width=50,
        )
        avg_alpha_slider = forms.log_slider(
            sizer=options_box,
            parent=self,
            min_exp=AVG_ALPHA_MIN_EXP,
            max_exp=AVG_ALPHA_MAX_EXP,
            num_steps=SLIDER_STEPS,
            ps=parent,
            key=AVG_ALPHA_KEY,
        )
        for widget in (avg_alpha_text, avg_alpha_slider):
            parent.subscribe(AVERAGE_KEY, widget.Enable)
            widget.Enable(parent[AVERAGE_KEY])
            # radio buttons for div size
        control_box.AddStretchSpacer()
        y_ctrl_box = forms.static_box_sizer(
            parent=self, sizer=control_box, label="Axis Options", bold=True, orient=wx.VERTICAL
        )
        forms.radio_buttons(
            sizer=y_ctrl_box,
            parent=self,
            ps=parent,
            key=Y_PER_DIV_KEY,
            style=wx.RA_VERTICAL | wx.NO_BORDER,
            choices=DIV_LEVELS,
            labels=map(lambda x: "%s dB/div" % x, DIV_LEVELS),
        )
        # ref lvl buttons
        forms.incr_decr_buttons(
            parent=self,
            sizer=y_ctrl_box,
            label="Ref Level",
            on_incr=self._on_incr_ref_level,
            on_decr=self._on_decr_ref_level,
        )
        y_ctrl_box.AddSpacer(2)
        # autoscale
        forms.single_button(sizer=y_ctrl_box, parent=self, label="Autoscale", callback=self.parent.autoscale)
        # run/stop
        control_box.AddStretchSpacer()
        forms.toggle_button(
            sizer=control_box, parent=self, true_label="Stop", false_label="Run", ps=parent, key=RUNNING_KEY
        )
        # set sizer
        self.SetSizerAndFit(control_box)
        # mouse wheel event
        def on_mouse_wheel(event):
            if event.GetWheelRotation() < 0:
                self._on_incr_ref_level(event)
            else:
                self._on_decr_ref_level(event)

        parent.plotter.Bind(wx.EVT_MOUSEWHEEL, on_mouse_wheel)