Merged wxgui/forms branch r11124:11183
[debian/gnuradio] / gr-wxgui / src / python / number_window.py
index e3fc4653efe7197e318a385c0f52faa5de46b79e..8a8249764c03e94acdb573b6cbbeed42aaeff3dd 100644 (file)
@@ -28,6 +28,7 @@ import wx
 import pubsub
 from constants import *
 from gnuradio import gr #for gr.prefs
+import forms
 
 ##################################################
 # Constants
@@ -38,6 +39,9 @@ AVG_ALPHA_MIN_EXP, AVG_ALPHA_MAX_EXP = -3, 0
 DEFAULT_NUMBER_RATE = gr.prefs().get_long('wxgui', 'number_rate', 5)
 DEFAULT_WIN_SIZE = (300, 300)
 DEFAULT_GAUGE_RANGE = 1000
+VALUE_REPR_KEY = 'value_repr'
+VALUE_REAL_KEY = 'value_real'
+VALUE_IMAG_KEY = 'value_imag'
 
 ##################################################
 # Number window control panel
@@ -53,35 +57,52 @@ class control_panel(wx.Panel):
                @param parent the wx parent window
                """
                self.parent = parent
-               wx.Panel.__init__(self, parent, -1, style=wx.SUNKEN_BORDER)
+               wx.Panel.__init__(self, parent)
                control_box = wx.BoxSizer(wx.VERTICAL)
                #checkboxes for average and peak hold
                control_box.AddStretchSpacer()
-               control_box.Add(common.LabelText(self, 'Options'), 0, wx.ALIGN_CENTER)
-               self.average_check_box = common.CheckBoxController(self, 'Average', parent.ext_controller, parent.average_key)
-               control_box.Add(self.average_check_box, 0, wx.EXPAND)
-               self.peak_hold_check_box = common.CheckBoxController(self, 'Peak Hold', parent, PEAK_HOLD_KEY)
-               control_box.Add(self.peak_hold_check_box, 0, wx.EXPAND)
-               control_box.AddSpacer(2)
-               self.avg_alpha_slider = common.LogSliderController(
-                       self, 'Avg Alpha',
-                       AVG_ALPHA_MIN_EXP, AVG_ALPHA_MAX_EXP, SLIDER_STEPS,
-                       parent.ext_controller, parent.avg_alpha_key,
-                       formatter=lambda x: ': %.4f'%x,
+               options_box = forms.static_box_sizer(
+                       parent=self, sizer=control_box, label='Options',
+                       bold=True, orient=wx.VERTICAL,
                )
-               parent.ext_controller.subscribe(parent.average_key, self.avg_alpha_slider.Enable)
-               control_box.Add(self.avg_alpha_slider, 0, wx.EXPAND)
+               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()
-               self.run_button = common.ToggleButtonController(self, parent, RUNNING_KEY, 'Stop', 'Run')
-               control_box.Add(self.run_button, 0, wx.EXPAND)
+               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)
 
 ##################################################
 # Numbersink window with label and gauges
 ##################################################
-class number_window(wx.Panel, pubsub.pubsub, common.prop_setter):
+class number_window(wx.Panel, pubsub.pubsub):
        def __init__(
                self,
                parent,
@@ -98,43 +119,56 @@ class number_window(wx.Panel, pubsub.pubsub, common.prop_setter):
                avg_alpha_key,
                peak_hold,
                msg_key,
+               sample_rate_key,
        ):
                pubsub.pubsub.__init__(self)
-               wx.Panel.__init__(self, parent, -1, style=wx.SUNKEN_BORDER)
+               wx.Panel.__init__(self, parent, style=wx.SUNKEN_BORDER)
                #setup
                self.peak_val_real = NEG_INF
                self.peak_val_imag = NEG_INF
-               self.ext_controller = controller
                self.real = real
                self.units = units
-               self.minval = minval
-               self.maxval = maxval
                self.decimal_places = decimal_places
-               self.average_key = average_key
-               self.avg_alpha_key = avg_alpha_key
+               #proxy the keys
+               self.proxy(MSG_KEY, controller, msg_key)
+               self.proxy(AVERAGE_KEY, controller, average_key)
+               self.proxy(AVG_ALPHA_KEY, controller, avg_alpha_key)
+               self.proxy(SAMPLE_RATE_KEY, controller, sample_rate_key)
+               #initialize values
+               self[PEAK_HOLD_KEY] = peak_hold
+               self[RUNNING_KEY] = True
+               self[VALUE_REAL_KEY] = minval
+               self[VALUE_IMAG_KEY] = minval
                #setup the box with display and controls
                self.control_panel = control_panel(self)
                main_box = wx.BoxSizer(wx.HORIZONTAL)
-               sizer = wx.BoxSizer(wx.VERTICAL)
-               main_box.Add(sizer, 1, wx.EXPAND)
+               sizer = forms.static_box_sizer(
+                       parent=self, sizer=main_box, label=title,
+                       bold=True, orient=wx.VERTICAL, proportion=1,
+               )
                main_box.Add(self.control_panel, 0, wx.EXPAND)
-               sizer.Add(common.LabelText(self, title), 1, wx.ALIGN_CENTER)
-               self.text = wx.StaticText(self, size=(size[0], -1))
-               sizer.Add(self.text, 1, wx.EXPAND)
-               self.gauge_real = wx.Gauge(self, range=DEFAULT_GAUGE_RANGE, style=wx.GA_HORIZONTAL)
-               self.gauge_imag = wx.Gauge(self, range=DEFAULT_GAUGE_RANGE, style=wx.GA_HORIZONTAL)
+               sizer.AddStretchSpacer()
+               forms.static_text(
+                       parent=self, sizer=sizer,
+                       ps=self, key=VALUE_REPR_KEY, width=size[0],
+                       converter=forms.str_converter(),
+               )
+               sizer.AddStretchSpacer()
+               self.gauge_real = forms.gauge(
+                       parent=self, sizer=sizer, style=wx.GA_HORIZONTAL,
+                       ps=self, key=VALUE_REAL_KEY, length=size[0],
+                       minimum=minval, maximum=maxval, num_steps=DEFAULT_GAUGE_RANGE,
+               )
+               self.gauge_imag = forms.gauge(
+                       parent=self, sizer=sizer, style=wx.GA_HORIZONTAL,
+                       ps=self, key=VALUE_IMAG_KEY, length=size[0],
+                       minimum=minval, maximum=maxval, num_steps=DEFAULT_GAUGE_RANGE,
+               )
                #hide/show gauges
                self.show_gauges(show_gauge)
-               sizer.Add(self.gauge_real, 1, wx.EXPAND)
-               sizer.Add(self.gauge_imag, 1, wx.EXPAND)
                self.SetSizerAndFit(main_box)
-               #initial setup
-               self.ext_controller[self.average_key] = self.ext_controller[self.average_key]
-               self.ext_controller[self.avg_alpha_key] = self.ext_controller[self.avg_alpha_key]
-               self._register_set_prop(self, PEAK_HOLD_KEY, peak_hold)
-               self._register_set_prop(self, RUNNING_KEY, True)
                #register events
-               self.ext_controller.subscribe(msg_key, self.handle_msg)
+               self.subscribe(MSG_KEY, self.handle_msg)
 
        def show_gauges(self, show_gauge):
                """
@@ -142,10 +176,8 @@ class number_window(wx.Panel, pubsub.pubsub, common.prop_setter):
                If this is real, never show the imaginary gauge.
                @param show_gauge true to show
                """
-               if show_gauge: self.gauge_real.Show()
-               else: self.gauge_real.Hide()
-               if show_gauge and not self.real: self.gauge_imag.Show()
-               else: self.gauge_imag.Hide()
+               self.gauge_real.ShowItems(show_gauge)
+               self.gauge_imag.ShowItems(show_gauge and not self.real)
 
        def handle_msg(self, msg):
                """
@@ -153,21 +185,15 @@ class number_window(wx.Panel, pubsub.pubsub, common.prop_setter):
                Convert the string based message into a float or complex.
                If more than one number was read, only take the last number.
                Perform peak hold operations, set the gauges and display.
-               @param msg the number sample as a character array
+               @param event event.data is the number sample as a character array
                """
                if not self[RUNNING_KEY]: return
-               #set gauge
-               def set_gauge_value(gauge, value):
-                       gauge_val = DEFAULT_GAUGE_RANGE*(value-self.minval)/(self.maxval-self.minval)
-                       gauge_val = max(0, gauge_val) #clip
-                       gauge_val = min(DEFAULT_GAUGE_RANGE, gauge_val) #clip
-                       gauge.SetValue(gauge_val)
                format_string = "%%.%df"%self.decimal_places
                if self.real:
                        sample = numpy.fromstring(msg, numpy.float32)[-1]
                        if self[PEAK_HOLD_KEY]: sample = self.peak_val_real = max(self.peak_val_real, sample)
                        label_text = "%s %s"%(format_string%sample, self.units)
-                       set_gauge_value(self.gauge_real, sample)
+                       self[VALUE_REAL_KEY] = sample
                else:
                        sample = numpy.fromstring(msg, numpy.complex64)[-1]
                        if self[PEAK_HOLD_KEY]:
@@ -175,10 +201,10 @@ class number_window(wx.Panel, pubsub.pubsub, common.prop_setter):
                                self.peak_val_imag = max(self.peak_val_imag, sample.imag)
                                sample = self.peak_val_real + self.peak_val_imag*1j
                        label_text = "%s + %sj %s"%(format_string%sample.real, format_string%sample.imag, self.units)
-                       set_gauge_value(self.gauge_real, sample.real)
-                       set_gauge_value(self.gauge_imag, sample.imag)
+                       self[VALUE_REAL_KEY] = sample.real
+                       self[VALUE_IMAG_KEY] = sample.imag
                #set label text
-               self.text.SetLabel(label_text)
+               self[VALUE_REPR_KEY] = label_text
                #clear peak hold
                if not self[PEAK_HOLD_KEY]:
                        self.peak_val_real = NEG_INF