commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r8883 - gnuradio/branches/features/experimental-gui


From: jblum
Subject: [Commit-gnuradio] r8883 - gnuradio/branches/features/experimental-gui
Date: Mon, 14 Jul 2008 15:13:27 -0600 (MDT)

Author: jblum
Date: 2008-07-14 15:13:26 -0600 (Mon, 14 Jul 2008)
New Revision: 8883

Added:
   gnuradio/branches/features/experimental-gui/todo.txt
Modified:
   gnuradio/branches/features/experimental-gui/common.py
   gnuradio/branches/features/experimental-gui/fft_gui.py
   gnuradio/branches/features/experimental-gui/fft_top_block.py
   gnuradio/branches/features/experimental-gui/fft_window.py
   gnuradio/branches/features/experimental-gui/prop_val.py
Log:
fft window has internal controller

Modified: gnuradio/branches/features/experimental-gui/common.py
===================================================================
--- gnuradio/branches/features/experimental-gui/common.py       2008-07-14 
17:27:42 UTC (rev 8882)
+++ gnuradio/branches/features/experimental-gui/common.py       2008-07-14 
21:13:26 UTC (rev 8883)
@@ -79,42 +79,57 @@
                self._decr_button.Bind(wx.EVT_BUTTON, on_decr)
                self.Add(self._decr_button, 0, wx.ALIGN_CENTER_VERTICAL)
 
-       def Enable(self):
-               self._incr_button.Enable()
-               self._decr_button.Enable()
+       def Enable(self, enable=True):
+               if enable:
+                       self._incr_button.Enable()
+                       self._decr_button.Enable()
+               else:
+                       self._incr_button.Disable()
+                       self._decr_button.Disable()
 
-       def Disable(self):
-               self._incr_button.Disable()
-               self._decr_button.Disable()
+       def Disable(self): self.Enable(False)
 
-       def _set_slider_value(self, real_value):
-               """!
-               Translate the real numerical value into a slider value and,
-               write the value to the slider.
-               @param real_value the numeric value the slider should represent
-               """
-               slider_value = (float(real_value) - 
self.min)*self.num_steps/(self.max - self.min)
-               self.slider.SetValue(slider_value)
+class RunStopButtonController(wx.Button):
+       def __init__(self, parent, controller, control_key):
+               wx.Button.__init__(self, parent, -1, '', style=wx.BU_EXACTFIT)
+               self.Bind(wx.EVT_BUTTON, lambda e: controller.set(control_key, 
not controller[control_key]))
+               controller.add_listener(control_key, lambda x: self.SetLabel(x 
and 'Stop' or 'Run'))
 
-       def _handle_scroll(self, event=None):
-               """!
-               A scroll event is detected. Read the slider, call the callback.
-               """
-               slider_value = self.slider.GetValue()
-               new_value = slider_value*(self.max - self.min)/self.num_steps + 
self.min
-               self.text_box.SetValue(str(new_value))
-               self._value = new_value
-               self.callback(self._value)
+class CheckBoxController(wx.CheckBox):
+       def __init__(self, parent, label, controller, control_key):
+               wx.CheckBox.__init__(self, parent, style=wx.CHK_2STATE, 
label=label)
+               self.Bind(wx.EVT_CHECKBOX, lambda e: 
controller.set(control_key, bool(e.IsChecked())))
+               controller.add_listener(control_key, lambda x: 
self.SetValue(bool(x)))
 
-       def _handle_enter(self, event=None):
-               """!
-               An enter key was pressed. Read the text box, call the callback.
-               """
-               new_value = float(self.text_box.GetValue())
-               self._set_slider_value(new_value)
-               self._value = new_value
-               self.callback(self._value)
+class LogSliderController(wx.BoxSizer):
+       def __init__(self, parent, label, min_exp, max_exp, slider_steps, 
controller, control_key, formatter=lambda x: ': %.3g'%x):
+               wx.BoxSizer.__init__(self, wx.VERTICAL)
+               self._label = wx.StaticText(parent, -1, label + 
formatter(1/3.0))
+               self.Add(self._label, 0, wx.EXPAND)
+               self._slider = wx.Slider(parent, -1, 0, 0, slider_steps, 
style=wx.SL_HORIZONTAL)
+               self.Add(self._slider, 0, wx.EXPAND)
+               def _on_slider_event(event):
+                       controller[control_key] = \
+                       
10**(float(max_exp-min_exp)*self._slider.GetValue()/slider_steps + min_exp)
+               self._slider.Bind(wx.EVT_SLIDER, _on_slider_event)
+               def _on_controller_set(value):
+                       self._label.SetLabel(label + formatter(value))
+                       slider_value = 
slider_steps*(math.log10(value)-min_exp)/(max_exp-min_exp)
+                       slider_value = min(max(0, slider_value), slider_steps)
+                       if abs(slider_value - self._slider.GetValue()) > 1:
+                               self._slider.SetValue(slider_value)
+               controller.add_listener(control_key, _on_controller_set)
 
+       def Enable(self, enable=True):
+               if enable:
+                       self._slider.Enable()
+                       self._label.Enable()
+               else:
+                       self._slider.Disable()
+                       self._label.Disable()
+
+       def Disable(self): self.Enable(False)
+
 ##################################################
 # Shared Functions
 ##################################################

Modified: gnuradio/branches/features/experimental-gui/fft_gui.py
===================================================================
--- gnuradio/branches/features/experimental-gui/fft_gui.py      2008-07-14 
17:27:42 UTC (rev 8882)
+++ gnuradio/branches/features/experimental-gui/fft_gui.py      2008-07-14 
21:13:26 UTC (rev 8883)
@@ -30,9 +30,9 @@
 """
 
 class fft_gui(wxgui_app):
-    def __init__(self, controller):
-       wxgui_app.__init__(self, controller=controller, title='fft demo')
-       
+    def __init__(self, controller, title='fft demo'):
+        wxgui_app.__init__(self, controller=controller, title=title)
+
         self._win = fft_window(parent=self.GetWin(),
                                controller=controller,
                                size=(600, 300),

Modified: gnuradio/branches/features/experimental-gui/fft_top_block.py
===================================================================
--- gnuradio/branches/features/experimental-gui/fft_top_block.py        
2008-07-14 17:27:42 UTC (rev 8882)
+++ gnuradio/branches/features/experimental-gui/fft_top_block.py        
2008-07-14 21:13:26 UTC (rev 8883)
@@ -33,7 +33,7 @@
     """
     def __init__(self, 
                 fft_size=512,
-                frame_rate=30,
+                frame_rate=60,
                 ref_scale=50,
                 which=0,
                 decim=16,

Modified: gnuradio/branches/features/experimental-gui/fft_window.py
===================================================================
--- gnuradio/branches/features/experimental-gui/fft_window.py   2008-07-14 
17:27:42 UTC (rev 8882)
+++ gnuradio/branches/features/experimental-gui/fft_window.py   2008-07-14 
21:13:26 UTC (rev 8883)
@@ -27,17 +27,28 @@
 import wx
 import numpy
 import math
+import prop_val
 
 ##################################################
 # Constants
 ##################################################
 SLIDER_STEPS = 100
-AVG_ALPHA_SLIDER_MIN, AVG_ALPHA_SLIDER_MAX = -4, 0
+AVG_ALPHA_MIN_EXP, AVG_ALPHA_MAX_EXP = -3, 0
 DEFAULT_FRAME_RATE = 30
 DEFAULT_WIN_SIZE = (640, 240)
 DIV_LEVELS = (1, 2, 5, 10, 20)
 FFT_PLOT_COLOR_SPEC = (0, 0, 1)
 PEAK_VALS_COLOR_SPEC = (0, 1, 0)
+NO_PEAK_VALS = list()
+AVERAGE_KEY = 'average'
+AVG_ALPHA_KEY = 'avg_alpha'
+PEAK_HOLD_KEY = 'peak_hold'
+Y_PER_DIV_KEY = 'y_per_div'
+Y_DIVS_KEY = 'y_divs'
+X_DIVS_KEY = 'x_divs'
+REF_LEVEL_KEY = 'ref_level'
+BASEBAND_FREQ_KEY = 'baseband_freq'
+RUNNING_KEY = 'running'
 
 ##################################################
 # FFT window control panel
@@ -59,17 +70,17 @@
                #checkboxes for average and peak hold
                control_box.AddStretchSpacer()
                control_box.Add(common.LabelText(self, 'Options'), 0, 
wx.ALIGN_CENTER)
-               self.average_check_box = wx.CheckBox(parent=self, 
style=wx.CHK_2STATE, label="Average")
-               self.average_check_box.Bind(wx.EVT_CHECKBOX, self._on_average)
+               self.average_check_box = common.CheckBoxController(self, 
'Average', parent.controller, AVERAGE_KEY)
                control_box.Add(self.average_check_box, 0, wx.EXPAND)
-               self.peak_hold_check_box = wx.CheckBox(parent=self, 
style=wx.CHK_2STATE, label="Peak Hold")
-               self.peak_hold_check_box.Bind(wx.EVT_CHECKBOX, 
self._on_peak_hold)
+               self.peak_hold_check_box = common.CheckBoxController(self, 
'Peak Hold', parent.controller, PEAK_HOLD_KEY)
                control_box.Add(self.peak_hold_check_box, 0, wx.EXPAND)
                control_box.AddSpacer(2)
-               self.avg_alpha_label = wx.StaticText(self, -1, '0'*15)
-               control_box.Add(self.avg_alpha_label, 0, wx.EXPAND)
-               self.avg_alpha_slider = wx.Slider(self, -1, 0, 0, SLIDER_STEPS, 
style=wx.SL_HORIZONTAL)
-               self.avg_alpha_slider.Bind(wx.EVT_SLIDER, self._on_avg_alpha)
+               self.avg_alpha_slider = common.LogSliderController(
+                       self, 'Avg Alpha',
+                       AVG_ALPHA_MIN_EXP, AVG_ALPHA_MAX_EXP, SLIDER_STEPS,
+                       parent.controller, AVG_ALPHA_KEY,
+               )
+               parent.controller.add_listener(AVERAGE_KEY, 
self.avg_alpha_slider.Enable)
                control_box.Add(self.avg_alpha_slider, 0, wx.EXPAND)
 
                #radio buttons for div size
@@ -79,9 +90,10 @@
                self.radio_buttons = list()
                for y_per_div in DIV_LEVELS:
                        radio_button = wx.RadioButton(self, -1, "%d 
dB/div"%y_per_div)
-                       radio_button.Bind(wx.EVT_RADIOBUTTON, 
self._on_radio_button_change)
+                       radio_button.Bind(wx.EVT_RADIOBUTTON, 
self._on_y_per_div)
                        self.radio_buttons.append(radio_button)
                        radio_box.Add(radio_button, 0, wx.ALIGN_LEFT)
+               parent.controller.add_listener(Y_PER_DIV_KEY, 
self._on_set_y_per_div)
                control_box.Add(radio_box, 0, wx.EXPAND)
 
                #ref lvl buttons
@@ -94,54 +106,30 @@
 
                #run/stop
                control_box.AddStretchSpacer()
-               self.run_button = wx.Button(self, -1, '', style=wx.BU_EXACTFIT)
-               self.run_button.Bind(wx.EVT_BUTTON, self._on_run)
+               self.run_button = common.RunStopButtonController(self, 
parent.controller, RUNNING_KEY)
                control_box.Add(self.run_button, 0, wx.EXPAND)
 
                #set sizer
                self.SetSizerAndFit(control_box)
 
-       def update(self):
-               """!
-               Read the state of the fft plot settings and update the control 
panel.
-               """
-               #update the run/stop button
-               if self.parent.running: self.run_button.SetLabel('Stop')
-               else: self.run_button.SetLabel('Run')
-               #update checkboxes
-               self.average_check_box.SetValue(self.parent.average)
-               self.peak_hold_check_box.SetValue(self.parent.peak_hold)
-               #update avg alpha
-               self.avg_alpha_label.SetLabel('Avg Alpha: 
%.3g'%self.parent.avg_alpha)
-               slider_value = 
SLIDER_STEPS*(math.log10(self.parent.avg_alpha)-AVG_ALPHA_SLIDER_MIN)/(AVG_ALPHA_SLIDER_MAX-AVG_ALPHA_SLIDER_MIN)
-               if abs(slider_value - self.avg_alpha_slider.GetValue())  > 1:
-                       self.avg_alpha_slider.SetValue(slider_value)
-               if self.parent.average:
-                       self.avg_alpha_label.Enable()
-                       self.avg_alpha_slider.Enable()
-               else:
-                       self.avg_alpha_label.Disable()
-                       self.avg_alpha_slider.Disable()
-               #update radio buttons
-               try:
-                       index = list(DIV_LEVELS).index(self.parent.y_per_div)
-                       self.radio_buttons[index].SetValue(True)
-               except: pass
-
        ##################################################
        # Event handlers
        ##################################################
-       def _on_radio_button_change(self, event):
+       def _on_set_y_per_div(self, y_per_div):
+               try:
+                       index = list(DIV_LEVELS).index(y_per_div)
+                       self.radio_buttons[index].SetValue(True)
+               except: pass
+       def _on_y_per_div(self, event):
                selected_radio_button = filter(lambda rb: rb.GetValue(), 
self.radio_buttons)[0]
                index = self.radio_buttons.index(selected_radio_button)
-               self.parent.set_y_per_div(DIV_LEVELS[index])
-       def _on_average(self, event): self.parent.set_average(event.IsChecked())
-       def _on_peak_hold(self, event): 
self.parent.set_peak_hold(event.IsChecked())
-       def _on_incr_ref_level(self, event): self.parent.incr_ref_level()
-       def _on_decr_ref_level(self, event): self.parent.decr_ref_level()
-       def _on_avg_alpha(self, event): 
-               
self.parent.set_avg_alpha(10**(float(AVG_ALPHA_SLIDER_MAX-AVG_ALPHA_SLIDER_MIN)*self.avg_alpha_slider.GetValue()/SLIDER_STEPS
 + AVG_ALPHA_SLIDER_MIN))
-       def _on_run(self, event): self.parent.set_run(not self.parent.running)
+               self.parent.controller[Y_PER_DIV_KEY] = DIV_LEVELS[index]
+       def _on_incr_ref_level(self, event):
+               self.parent.set_ref_level(
+                       self.parent.controller[REF_LEVEL_KEY] + 
self.parent.controller[Y_PER_DIV_KEY])
+       def _on_decr_ref_level(self, event):
+               self.parent.set_ref_level(
+                       self.parent.controller[REF_LEVEL_KEY] - 
self.parent.controller[Y_PER_DIV_KEY])
 
 ##################################################
 # FFT window with plotter and control panel
@@ -164,69 +152,87 @@
                peak_hold,
                msg_key,
        ):
+               self.controller = prop_val.prop_val_interface()
                #ensure y_per_div
                if y_per_div not in DIV_LEVELS: y_per_div = DIV_LEVELS[0]
                #setup
-               self.controller = controller
-               self.running = True
+               self.ext_controller = controller
                self.real = real
-               self.baseband_freq = baseband_freq
                self.sample_rate_key = sample_rate_key
-               self.x_divs = 8.0 #approximate
-               self.y_per_div = y_per_div
-               self.y_divs = y_divs
-               self.ref_level = ref_level
                self.average_key = average_key
                self.avg_alpha_key = avg_alpha_key
-               self.peak_hold = peak_hold
-               self.peak_vals = []
+               self.peak_vals = NO_PEAK_VALS
                #init panel and plot
                wx.Panel.__init__(self, parent, -1, style=wx.SIMPLE_BORDER)
                self.plotter = plotter.grid_plotter(self)
                self.plotter.SetSize(wx.Size(*size))
                self.plotter.set_title(title)
-               self.plotter.set_y_units('Amplitude (dB)')
                #setup the box with plot and controls
                self.control_panel = control_panel(self)
                main_box = wx.BoxSizer(wx.HORIZONTAL)
                main_box.Add(self.plotter, 1, wx.EXPAND)
                main_box.Add(self.control_panel, 0, wx.EXPAND)
                self.SetSizerAndFit(main_box)
-               #setup controller
-               self.controller.add_listener(msg_key, self.handle_msg)
-               self.controller.add_listener(self.sample_rate_key, lambda x: 
self.update())
-               self.controller.add_listener(self.average_key, lambda x: 
self.update())
-               self.controller.add_listener(self.avg_alpha_key, lambda x: 
self.update())
-               #update
-               self.update()
-               
+               #bind internal & external keys
+               def bind_controller_keys(controller_master, controller_slave, 
master_key, slave_key):
+                       controller_slave[slave_key] = 
controller_master[master_key]
+                       controller_slave.add_listener(slave_key, lambda x: 
controller_master.set(master_key, x))
+                       controller_master.add_listener(master_key, lambda x: 
controller_slave.set(slave_key, x))
+               for in_key, ext_key in (
+                       (AVERAGE_KEY, average_key),
+                       (AVG_ALPHA_KEY, avg_alpha_key),
+               ): bind_controller_keys(self.ext_controller, self.controller, 
ext_key, in_key)
+               #initial setup
+               self.set_baseband_freq(baseband_freq)
+               self.set_peak_hold(peak_hold)
+               self.set_y_per_div(y_per_div)
+               self.set_y_divs(y_divs)
+               self.set_x_divs(8) #approximate
+               self.set_ref_level(ref_level)
+               self.set_running(True)
+               #register events
+               self.ext_controller.add_listener(msg_key, self.handle_msg)
+               self.ext_controller.add_listener(self.sample_rate_key, lambda 
x: self.update_grid())
+               self.controller.add_listener(BASEBAND_FREQ_KEY, lambda x: 
self.update_grid())
+               self.controller.add_listener(Y_PER_DIV_KEY, lambda x: 
self.update_grid())
+               self.controller.add_listener(Y_DIVS_KEY, lambda x: 
self.update_grid())
+               self.controller.add_listener(X_DIVS_KEY, lambda x: 
self.update_grid())
+               self.controller.add_listener(REF_LEVEL_KEY, lambda x: 
self.update_grid())
+               #initial update
+               self.update_grid()
+
+       ##################################################
+       # Set parameters on-the-fly
+       ##################################################
+       def set_peak_hold(self, peak_hold): self.controller[PEAK_HOLD_KEY] = 
peak_hold
+       def set_y_per_div(self, y_per_div): self.controller[Y_PER_DIV_KEY] = 
y_per_div
+       def set_y_divs(self, y_divs): self.controller[Y_DIVS_KEY] = y_divs
+       def set_x_divs(self, x_divs): self.controller[X_DIVS_KEY] = x_divs
+       def set_ref_level(self, ref_level): self.controller[REF_LEVEL_KEY] = 
ref_level
+       def set_baseband_freq(self, baseband_freq): 
self.controller[BASEBAND_FREQ_KEY] = baseband_freq
+       def set_running(self, running): self.controller[RUNNING_KEY] = running
+
        def handle_msg(self, msg):
                """!
                Handle the message from the fft sink message queue.
                If complex, reorder the fft samples so the negative bins come 
first.
                If real, keep take only the positive bins.
+               Plot the samples onto the grid as channel 1.
+               If peak hold is enabled, plot peak vals as channel 2.
                @param msg the fft array as a character array
                """
+               if not self.controller[RUNNING_KEY]: return
                #convert to floating point numbers
                samples = numpy.fromstring(msg, numpy.float32)
                num_samps = len(samples)
                #reorder fft
                if self.real: samples = samples[:num_samps/2]
                else: samples = numpy.concatenate((samples[num_samps/2+1:], 
samples[:num_samps/2]))
-               #plot
-               self.plot(samples)
-
-       def plot(self, samples):
-               """!
-               Plot the samples onto the grid as channel 1.
-               If peak hold is enabled, plot peak vals as channel 2.
-               @param samples the fft array
-               """
-               if not self.running: return
                #peak hold calculation
-               if self.peak_hold:
+               if self.controller[PEAK_HOLD_KEY]:
                        if len(self.peak_vals) != len(samples): self.peak_vals 
= samples
                        self.peak_vals = numpy.maximum(samples, self.peak_vals)
+               else: self.peak_vals = NO_PEAK_VALS
                #plot the fft
                self.plotter.set_waveform(
                        channel=1,
@@ -242,16 +248,25 @@
                #update the plotter
                self.plotter.update()
 
-       def update(self):
-               self.sample_rate = self.controller[self.sample_rate_key]
-               self.average = self.controller[self.average_key]
-               self.avg_alpha = self.controller[self.avg_alpha_key]
-               #update peak hold
-               if not self.peak_hold: self.peak_vals = []
+       def update_grid(self):
+               """!
+               Update the plotter grid.
+               This update method is dependent on the variables below.
+               Determine the x and y axis grid parameters.
+               The x axis depends on sample rate, baseband freq, and x divs.
+               The y axis depends on y per div, y divs, and ref level.
+               """
+               #grid parameters
+               sample_rate = self.ext_controller[self.sample_rate_key]
+               baseband_freq = self.controller[BASEBAND_FREQ_KEY]
+               y_per_div = self.controller[Y_PER_DIV_KEY]
+               y_divs = self.controller[Y_DIVS_KEY]
+               x_divs = self.controller[X_DIVS_KEY]
+               ref_level = self.controller[REF_LEVEL_KEY]
                #determine best fitting x_per_div
-               if self.real: x_width = self.sample_rate/2.0
-               else: x_width = self.sample_rate
-               x_per_div = common.get_clean_num(x_width/self.x_divs)
+               if self.real: x_width = sample_rate/2.0
+               else: x_width = sample_rate/1.0
+               x_per_div = common.get_clean_num(x_width/x_divs)
                exp = common.get_exp(x_per_div)
                #calculate units and scalar
                if exp > 7: x_units, scalar = 'GHz', 1e-9
@@ -261,45 +276,21 @@
                #update the x grid
                if self.real:
                        self.plotter.set_x_grid(
-                               scalar*self.baseband_freq,
-                               scalar*self.baseband_freq + 
scalar*self.sample_rate/2.0,
+                               scalar*baseband_freq,
+                               scalar*baseband_freq + scalar*sample_rate/2.0,
                                scalar*x_per_div,
                        )
                else:
                        self.plotter.set_x_grid(
-                               scalar*self.baseband_freq - 
scalar*self.sample_rate/2.0,
-                               scalar*self.baseband_freq + 
scalar*self.sample_rate/2.0,
+                               scalar*baseband_freq - scalar*sample_rate/2.0,
+                               scalar*baseband_freq + scalar*sample_rate/2.0,
                                scalar*x_per_div,
                        )
                #update x units
                self.plotter.set_x_units('Frequency (%s)'%x_units)
                #update y grid
-               
self.plotter.set_y_grid(self.ref_level-self.y_per_div*self.y_divs, 
self.ref_level, self.y_per_div)
-               #update control panel and plotter
-               self.control_panel.update()
+               self.plotter.set_y_grid(ref_level-y_per_div*y_divs, ref_level, 
y_per_div)
+               #update y units
+               self.plotter.set_y_units('Amplitude (dB)')
+               #update plotter
                self.plotter.update()
-
-       ##################################################
-       # Set parameters on-the-fly
-       ##################################################
-       def set_baseband_freq(self, baseband_freq):
-               self.baseband_freq = baseband_freq
-               self.update()
-       def set_average(self, average):
-               self.controller[self.average_key] = average
-       def set_avg_alpha(self, avg_alpha):
-               self.controller[self.avg_alpha_key] = avg_alpha
-       def set_peak_hold(self, peak_hold):
-               self.peak_hold = peak_hold
-               self.update()
-       def set_y_per_div(self, y_per_div):
-               self.y_per_div = y_per_div
-               self.update()
-       def set_ref_level(self, ref_level):
-               self.ref_level = ref_level
-               self.update()
-       def incr_ref_level(self): self.set_ref_level(self.ref_level + 
self.y_per_div)
-       def decr_ref_level(self): self.set_ref_level(self.ref_level - 
self.y_per_div)
-       def set_run(self, running):
-               self.running = running
-               self.update()

Modified: gnuradio/branches/features/experimental-gui/prop_val.py
===================================================================
--- gnuradio/branches/features/experimental-gui/prop_val.py     2008-07-14 
17:27:42 UTC (rev 8882)
+++ gnuradio/branches/features/experimental-gui/prop_val.py     2008-07-14 
21:13:26 UTC (rev 8883)
@@ -63,6 +63,7 @@
        with the new value.  If there is no provider for the property, the
        value will be cached.
        """
+       if self._cache == value: return
        (handler, obj) = self._provider
        if handler is None:
            self._cache = value
@@ -96,6 +97,8 @@
     """ 
     def __init__(self):
        self._props = { }
+       self.get = self.__getitem__
+       self.set = self.__setitem__
                
     def _get_prop(self, key):
        try:

Added: gnuradio/branches/features/experimental-gui/todo.txt
===================================================================
--- gnuradio/branches/features/experimental-gui/todo.txt                        
        (rev 0)
+++ gnuradio/branches/features/experimental-gui/todo.txt        2008-07-14 
21:13:26 UTC (rev 8883)
@@ -0,0 +1,6 @@
+TODO List
+
+-controller is a dict
+-controller property with default value for cache
+-use iteritems in cli.py
+-add/remove listener in cli.py





reply via email to

[Prev in Thread] Current Thread [Next in Thread]