From 69d09a30b38567c3ae33a227a3959aee43c721a7 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 6 Oct 2009 21:52:41 -0700 Subject: added bind to visible event function to callback when visibility changes within tabs --- gr-wxgui/src/python/common.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/gr-wxgui/src/python/common.py b/gr-wxgui/src/python/common.py index 9c97ce1ec..f355fd3ce 100644 --- a/gr-wxgui/src/python/common.py +++ b/gr-wxgui/src/python/common.py @@ -19,6 +19,41 @@ # Boston, MA 02110-1301, USA. # +import wx + +def bind_to_visible_event(win, callback): + """ + Bind a callback to a window when its visibility changes. + Specifically, callback when the window changes visibility + when a notebook tab event in one of the parents occurs. + @param win the wx window + @param callback a 1 param function + """ + #is the window visible in the hierarchy + def is_wx_window_visible(my_win): + while True: + parent = my_win.GetParent() + if not parent: return True #reached the top of the hierarchy + #if we are hidden, then finish, otherwise keep traversing up + if isinstance(parent, wx.Notebook) and parent.GetCurrentPage() != my_win: return False + my_win = parent + #call the callback, the arg is shown or not + def callback_factory(my_win, my_callback): + cache = [None] + def the_callback(*args): + visible = is_wx_window_visible(my_win) + if cache[0] != visible: my_callback(visible) + cache[0] = visible + return the_callback + handler = callback_factory(win, callback) + #bind the handler to all the parent notebooks + while win: + if isinstance(win, wx.Notebook): + win.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, handler) + if not win.GetParent(): + win.Bind(wx.EVT_ACTIVATE, handler) + win = win.GetParent() + #A macro to apply an index to a key index_key = lambda key, i: "%s_%d"%(key, i+1) -- cgit From 645ab0cfa4ab46e057ab4df74066ab434ad5b90a Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 6 Oct 2009 22:28:09 -0700 Subject: work on a special connect function that registers a callback --- gr-wxgui/src/python/common.py | 20 ++++++++++++++++++++ gr-wxgui/src/python/fftsink_gl.py | 5 +++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/gr-wxgui/src/python/common.py b/gr-wxgui/src/python/common.py index f355fd3ce..09ce44719 100644 --- a/gr-wxgui/src/python/common.py +++ b/gr-wxgui/src/python/common.py @@ -54,6 +54,26 @@ def bind_to_visible_event(win, callback): win.Bind(wx.EVT_ACTIVATE, handler) win = win.GetParent() +from gnuradio import gr + +def special_connect(source, sink, hb, win, size): + nulls = [gr.null_sink(size), gr.null_source(size)] + def callback(visible, init=False): + if not init: hb.lock() + if visible: + if not init: hb.disconnect(source, nulls[0]) + if not init: hb.disconnect(nulls[1], sink) + hb.connect(source, sink) + #hb.connect(nulls[1], nulls[0]) + else: + if not init: hb.disconnect(source, sink) + #if not init: hb.disconnect(nulls[1], nulls[0]) + hb.connect(source, nulls[0]) + hb.connect(nulls[1], sink) + if not init: hb.unlock() + callback(False, init=True) #initially connect + bind_to_visible_event(win, callback) + #A macro to apply an index to a key index_key = lambda key, i: "%s_%d"%(key, i+1) diff --git a/gr-wxgui/src/python/fftsink_gl.py b/gr-wxgui/src/python/fftsink_gl.py index 3f0a93fc8..4edb11b4a 100644 --- a/gr-wxgui/src/python/fftsink_gl.py +++ b/gr-wxgui/src/python/fftsink_gl.py @@ -73,8 +73,6 @@ class _fft_sink_base(gr.hier_block2): ) msgq = gr.msg_queue(2) sink = gr.message_sink(gr.sizeof_float*fft_size, msgq, True) - #connect - self.connect(self, fft, sink) #controller self.controller = pubsub() self.controller.subscribe(AVERAGE_KEY, fft.set_average) @@ -106,6 +104,9 @@ class _fft_sink_base(gr.hier_block2): common.register_access_methods(self, self.win) setattr(self.win, 'set_baseband_freq', getattr(self, 'set_baseband_freq')) #BACKWARDS setattr(self.win, 'set_peak_hold', getattr(self, 'set_peak_hold')) #BACKWARDS + #connect + common.special_connect(self, fft, hb=self, win=self.win, size=self._item_size) + self.connect(fft, sink) class fft_sink_f(_fft_sink_base): _fft_chain = blks2.logpwrfft_f -- cgit From bbecdd8372f57d49ad0046d9d096f322059005cb Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 7 Oct 2009 01:47:38 -0700 Subject: working special connect for fftsink --- gr-wxgui/src/python/common.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/gr-wxgui/src/python/common.py b/gr-wxgui/src/python/common.py index 09ce44719..fe080aa4a 100644 --- a/gr-wxgui/src/python/common.py +++ b/gr-wxgui/src/python/common.py @@ -39,12 +39,7 @@ def bind_to_visible_event(win, callback): my_win = parent #call the callback, the arg is shown or not def callback_factory(my_win, my_callback): - cache = [None] - def the_callback(*args): - visible = is_wx_window_visible(my_win) - if cache[0] != visible: my_callback(visible) - cache[0] = visible - return the_callback + return lambda *args: my_callback(is_wx_window_visible(my_win)) handler = callback_factory(win, callback) #bind the handler to all the parent notebooks while win: @@ -57,19 +52,25 @@ def bind_to_visible_event(win, callback): from gnuradio import gr def special_connect(source, sink, hb, win, size): - nulls = [gr.null_sink(size), gr.null_source(size)] + nulls = list() + cache = [None] def callback(visible, init=False): + if visible == cache[0]: return + cache[0] = visible if not init: hb.lock() + print 'visible', visible if visible: - if not init: hb.disconnect(source, nulls[0]) - if not init: hb.disconnect(nulls[1], sink) + if not init: + hb.disconnect(source, nulls[0]) + hb.disconnect(nulls[1], nulls[2]) + hb.disconnect(nulls[2], sink) + while nulls: nulls.pop() hb.connect(source, sink) - #hb.connect(nulls[1], nulls[0]) else: if not init: hb.disconnect(source, sink) - #if not init: hb.disconnect(nulls[1], nulls[0]) + nulls.extend([gr.null_sink(size), gr.null_source(size), gr.head(size, 0)]) hb.connect(source, nulls[0]) - hb.connect(nulls[1], sink) + hb.connect(nulls[1], nulls[2], sink) if not init: hb.unlock() callback(False, init=True) #initially connect bind_to_visible_event(win, callback) -- cgit From af5e21e35cda1d9d3e4bd659364dafe181274064 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 7 Oct 2009 09:48:24 -0700 Subject: setup special wxgui connect on sinks, needs testing --- gr-wxgui/src/python/common.py | 25 +++++++++++++++-- gr-wxgui/src/python/constsink_gl.py | 6 ++-- gr-wxgui/src/python/fftsink_gl.py | 5 ++-- gr-wxgui/src/python/histosink_gl.py | 6 ++-- gr-wxgui/src/python/numbersink2.py | 6 ++-- gr-wxgui/src/python/scopesink_gl.py | 49 +++++++++++++++++---------------- gr-wxgui/src/python/waterfallsink_gl.py | 6 ++-- 7 files changed, 63 insertions(+), 40 deletions(-) diff --git a/gr-wxgui/src/python/common.py b/gr-wxgui/src/python/common.py index fe080aa4a..dca41c9a3 100644 --- a/gr-wxgui/src/python/common.py +++ b/gr-wxgui/src/python/common.py @@ -19,6 +19,9 @@ # Boston, MA 02110-1301, USA. # +################################################## +# conditional disconnections of wx flow graph +################################################## import wx def bind_to_visible_event(win, callback): @@ -51,14 +54,14 @@ def bind_to_visible_event(win, callback): from gnuradio import gr -def special_connect(source, sink, hb, win, size): +def conditional_connect(source, sink, hb, win, size): nulls = list() cache = [None] def callback(visible, init=False): if visible == cache[0]: return cache[0] = visible if not init: hb.lock() - print 'visible', visible + print 'visible', visible, source, sink if visible: if not init: hb.disconnect(source, nulls[0]) @@ -75,6 +78,24 @@ def special_connect(source, sink, hb, win, size): callback(False, init=True) #initially connect bind_to_visible_event(win, callback) +class wxgui_hb(object): + def wxgui_connect(self, *points): + """ + Use wxgui connect when the first point is the self source of the hb. + The win property of this object should be set to the wx window. + When this method tries to connect self to the next point, + it will conditionally make this connection based on the visibility state. + """ + try: + assert points[0] == self or points[0][0] == self + conditional_connect( + points[0], points[1], + win=self.win, hb=self, + size=self._hb.input_signature().sizeof_stream_item(0), + ) + if len(points[1:]) > 1: self.connect(*points[1:]) + except (AssertionError, IndexError): self.connect(*points) + #A macro to apply an index to a key index_key = lambda key, i: "%s_%d"%(key, i+1) diff --git a/gr-wxgui/src/python/constsink_gl.py b/gr-wxgui/src/python/constsink_gl.py index b3a1625b0..91bc65d9f 100644 --- a/gr-wxgui/src/python/constsink_gl.py +++ b/gr-wxgui/src/python/constsink_gl.py @@ -31,7 +31,7 @@ from constants import * ################################################## # Constellation sink block (wrapper for old wxgui) ################################################## -class const_sink_c(gr.hier_block2): +class const_sink_c(gr.hier_block2, common.wxgui_hb): """ A constellation block with a gui window. """ @@ -94,8 +94,6 @@ class const_sink_c(gr.hier_block2): agc = gr.feedforward_agc_cc(16, 1) msgq = gr.msg_queue(2) sink = gr.message_sink(gr.sizeof_gr_complex*const_size, msgq, True) - #connect - self.connect(self, self._costas, self._retime, agc, sd, sink) #controller def setter(p, k, x): p[k] = x self.controller = pubsub() @@ -131,5 +129,7 @@ class const_sink_c(gr.hier_block2): sample_rate_key=SAMPLE_RATE_KEY, ) common.register_access_methods(self, self.win) + #connect + self.wxgui_connect(self, self._costas, self._retime, agc, sd, sink) diff --git a/gr-wxgui/src/python/fftsink_gl.py b/gr-wxgui/src/python/fftsink_gl.py index 4edb11b4a..9d683d697 100644 --- a/gr-wxgui/src/python/fftsink_gl.py +++ b/gr-wxgui/src/python/fftsink_gl.py @@ -31,7 +31,7 @@ from constants import * ################################################## # FFT sink block (wrapper for old wxgui) ################################################## -class _fft_sink_base(gr.hier_block2): +class _fft_sink_base(gr.hier_block2, common.wxgui_hb): """ An fft block with real/complex inputs and a gui window. """ @@ -105,8 +105,7 @@ class _fft_sink_base(gr.hier_block2): setattr(self.win, 'set_baseband_freq', getattr(self, 'set_baseband_freq')) #BACKWARDS setattr(self.win, 'set_peak_hold', getattr(self, 'set_peak_hold')) #BACKWARDS #connect - common.special_connect(self, fft, hb=self, win=self.win, size=self._item_size) - self.connect(fft, sink) + self.wxgui_connect(self, fft, sink) class fft_sink_f(_fft_sink_base): _fft_chain = blks2.logpwrfft_f diff --git a/gr-wxgui/src/python/histosink_gl.py b/gr-wxgui/src/python/histosink_gl.py index db6606e41..509f746be 100644 --- a/gr-wxgui/src/python/histosink_gl.py +++ b/gr-wxgui/src/python/histosink_gl.py @@ -31,7 +31,7 @@ from constants import * ################################################## # histo sink block (wrapper for old wxgui) ################################################## -class histo_sink_f(gr.hier_block2): +class histo_sink_f(gr.hier_block2, common.wxgui_hb): """ A histogram block and a gui window. """ @@ -56,8 +56,6 @@ class histo_sink_f(gr.hier_block2): histo = gr.histo_sink_f(msgq) histo.set_num_bins(num_bins) histo.set_frame_size(frame_size) - #connect - self.connect(self, histo) #controller self.controller = pubsub() self.controller.subscribe(NUM_BINS_KEY, histo.set_num_bins) @@ -79,6 +77,8 @@ class histo_sink_f(gr.hier_block2): msg_key=MSG_KEY, ) common.register_access_methods(self, self.win) + #connect + self.wxgui_connect(self, histo) # ---------------------------------------------------------------- # Standalone test app diff --git a/gr-wxgui/src/python/numbersink2.py b/gr-wxgui/src/python/numbersink2.py index 7f853e6a4..011acdfd5 100644 --- a/gr-wxgui/src/python/numbersink2.py +++ b/gr-wxgui/src/python/numbersink2.py @@ -31,7 +31,7 @@ from constants import * ################################################## # Number sink block (wrapper for old wxgui) ################################################## -class _number_sink_base(gr.hier_block2): +class _number_sink_base(gr.hier_block2, common.wxgui_hb): """ An decimator block with a number window display """ @@ -81,8 +81,6 @@ class _number_sink_base(gr.hier_block2): avg = gr.single_pole_iir_filter_cc(1.0) msgq = gr.msg_queue(2) sink = gr.message_sink(self._item_size, msgq, True) - #connect - self.connect(self, sd, mult, add, avg, sink) #controller self.controller = pubsub() self.controller.subscribe(SAMPLE_RATE_KEY, sd.set_sample_rate) @@ -118,6 +116,8 @@ class _number_sink_base(gr.hier_block2): common.register_access_methods(self, self.controller) #backwards compadibility self.set_show_gauge = self.win.show_gauges + #connect + self.wxgui_connect(self, sd, mult, add, avg, sink) class number_sink_f(_number_sink_base): _item_size = gr.sizeof_float diff --git a/gr-wxgui/src/python/scopesink_gl.py b/gr-wxgui/src/python/scopesink_gl.py index a5e3ca3ce..2882488e3 100644 --- a/gr-wxgui/src/python/scopesink_gl.py +++ b/gr-wxgui/src/python/scopesink_gl.py @@ -34,7 +34,7 @@ class ac_couple_block(gr.hier_block2): Mute the low pass filter to disable ac coupling. """ - def __init__(self, controller, ac_couple_key, ac_couple, sample_rate_key): + def __init__(self, controller, ac_couple_key, sample_rate_key): gr.hier_block2.__init__( self, "ac_couple", @@ -52,13 +52,13 @@ class ac_couple_block(gr.hier_block2): controller.subscribe(ac_couple_key, lambda x: mute.set_mute(not x)) controller.subscribe(sample_rate_key, lambda x: lpf.set_taps(0.05)) #initialize - controller[ac_couple_key] = ac_couple + controller[ac_couple_key] = controller[ac_couple_key] controller[sample_rate_key] = controller[sample_rate_key] ################################################## # Scope sink block (wrapper for old wxgui) ################################################## -class _scope_sink_base(gr.hier_block2): +class _scope_sink_base(gr.hier_block2, common.wxgui_hb): """ A scope block with a gui window. """ @@ -102,25 +102,10 @@ class _scope_sink_base(gr.hier_block2): self.controller.publish(TRIGGER_SLOPE_KEY, scope.get_trigger_slope) self.controller.subscribe(TRIGGER_CHANNEL_KEY, scope.set_trigger_channel) self.controller.publish(TRIGGER_CHANNEL_KEY, scope.get_trigger_channel) - #connect - if self._real: - for i in range(num_inputs): - self.connect( - (self, i), - ac_couple_block(self.controller, common.index_key(AC_COUPLE_KEY, i), ac_couple, SAMPLE_RATE_KEY), - (scope, i), - ) - else: - for i in range(num_inputs): - c2f = gr.complex_to_float() - self.connect((self, i), c2f) - for j in range(2): - self.connect( - (c2f, j), - ac_couple_block(self.controller, common.index_key(AC_COUPLE_KEY, 2*i+j), ac_couple, SAMPLE_RATE_KEY), - (scope, 2*i+j), - ) - num_inputs *= 2 + actual_num_inputs = self._real and num_inputs or num_inputs*2 + #init ac couple + for i in range(actual_num_inputs): + self.controller[common.index_key(AC_COUPLE_KEY, i)] = ac_couple #start input watcher common.input_watcher(msgq, self.controller, MSG_KEY) #create window @@ -130,7 +115,7 @@ class _scope_sink_base(gr.hier_block2): size=size, title=title, frame_rate=frame_rate, - num_inputs=num_inputs, + num_inputs=actual_num_inputs, sample_rate_key=SAMPLE_RATE_KEY, t_scale=t_scale, v_scale=v_scale, @@ -144,6 +129,24 @@ class _scope_sink_base(gr.hier_block2): msg_key=MSG_KEY, ) common.register_access_methods(self, self.win) + #connect + if self._real: + for i in range(num_inputs): + self.wxgui_connect( + (self, i), + ac_couple_block(self.controller, common.index_key(AC_COUPLE_KEY, i), SAMPLE_RATE_KEY), + (scope, i), + ) + else: + for i in range(num_inputs): + c2f = gr.complex_to_float() + self.wxgui_connect((self, i), c2f) + for j in range(2): + self.connect( + (c2f, j), + ac_couple_block(self.controller, common.index_key(AC_COUPLE_KEY, 2*i+j), SAMPLE_RATE_KEY), + (scope, 2*i+j), + ) class scope_sink_f(_scope_sink_base): _item_size = gr.sizeof_float diff --git a/gr-wxgui/src/python/waterfallsink_gl.py b/gr-wxgui/src/python/waterfallsink_gl.py index 2d4c959f8..37844399e 100644 --- a/gr-wxgui/src/python/waterfallsink_gl.py +++ b/gr-wxgui/src/python/waterfallsink_gl.py @@ -31,7 +31,7 @@ from constants import * ################################################## # Waterfall sink block (wrapper for old wxgui) ################################################## -class _waterfall_sink_base(gr.hier_block2): +class _waterfall_sink_base(gr.hier_block2, common.wxgui_hb): """ An fft block with real/complex inputs and a gui window. """ @@ -73,8 +73,6 @@ class _waterfall_sink_base(gr.hier_block2): ) msgq = gr.msg_queue(2) sink = gr.message_sink(gr.sizeof_float*fft_size, msgq, True) - #connect - self.connect(self, fft, sink) #controller self.controller = pubsub() self.controller.subscribe(AVERAGE_KEY, fft.set_average) @@ -110,6 +108,8 @@ class _waterfall_sink_base(gr.hier_block2): ) common.register_access_methods(self, self.win) setattr(self.win, 'set_baseband_freq', getattr(self, 'set_baseband_freq')) #BACKWARDS + #connect + self.wxgui_connect(self, fft, sink) class waterfall_sink_f(_waterfall_sink_base): _fft_chain = blks2.logpwrfft_f -- cgit From 1e8aefecdc607de260c1797aba27eb1598b9e7b8 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 7 Oct 2009 11:52:33 -0700 Subject: making use of update ui event --- gr-wxgui/src/python/common.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/gr-wxgui/src/python/common.py b/gr-wxgui/src/python/common.py index dca41c9a3..04875e7f2 100644 --- a/gr-wxgui/src/python/common.py +++ b/gr-wxgui/src/python/common.py @@ -28,7 +28,7 @@ def bind_to_visible_event(win, callback): """ Bind a callback to a window when its visibility changes. Specifically, callback when the window changes visibility - when a notebook tab event in one of the parents occurs. + when a update ui event in the window occurs. @param win the wx window @param callback a 1 param function """ @@ -45,23 +45,18 @@ def bind_to_visible_event(win, callback): return lambda *args: my_callback(is_wx_window_visible(my_win)) handler = callback_factory(win, callback) #bind the handler to all the parent notebooks - while win: - if isinstance(win, wx.Notebook): - win.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, handler) - if not win.GetParent(): - win.Bind(wx.EVT_ACTIVATE, handler) - win = win.GetParent() + win.Bind(wx.EVT_UPDATE_UI, handler) from gnuradio import gr -def conditional_connect(source, sink, hb, win, size): +def conditional_connect_callback_factory(source, sink, hb, win, size): nulls = list() cache = [None] def callback(visible, init=False): if visible == cache[0]: return cache[0] = visible if not init: hb.lock() - print 'visible', visible, source, sink + #print 'visible', visible, source, sink if visible: if not init: hb.disconnect(source, nulls[0]) @@ -75,8 +70,12 @@ def conditional_connect(source, sink, hb, win, size): hb.connect(source, nulls[0]) hb.connect(nulls[1], nulls[2], sink) if not init: hb.unlock() - callback(False, init=True) #initially connect - bind_to_visible_event(win, callback) + return callback + +def conditional_connect(source, sink, hb, win, size): + handler = conditional_connect_callback_factory(source, sink, hb, win, size) + handler(False, init=True) #initially connect + bind_to_visible_event(win, handler) class wxgui_hb(object): def wxgui_connect(self, *points): -- cgit From 64a5167c53eeb2d2a657507397b402abe22f67b6 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 7 Oct 2009 18:01:56 -0700 Subject: moved the wxgui connect helper functions into the wrapper class --- gr-wxgui/src/python/common.py | 137 ++++++++++++++++++++++++------------------ 1 file changed, 80 insertions(+), 57 deletions(-) diff --git a/gr-wxgui/src/python/common.py b/gr-wxgui/src/python/common.py index 04875e7f2..aae4d63cf 100644 --- a/gr-wxgui/src/python/common.py +++ b/gr-wxgui/src/python/common.py @@ -23,78 +23,101 @@ # conditional disconnections of wx flow graph ################################################## import wx - -def bind_to_visible_event(win, callback): - """ - Bind a callback to a window when its visibility changes. - Specifically, callback when the window changes visibility - when a update ui event in the window occurs. - @param win the wx window - @param callback a 1 param function - """ - #is the window visible in the hierarchy - def is_wx_window_visible(my_win): - while True: - parent = my_win.GetParent() - if not parent: return True #reached the top of the hierarchy - #if we are hidden, then finish, otherwise keep traversing up - if isinstance(parent, wx.Notebook) and parent.GetCurrentPage() != my_win: return False - my_win = parent - #call the callback, the arg is shown or not - def callback_factory(my_win, my_callback): - return lambda *args: my_callback(is_wx_window_visible(my_win)) - handler = callback_factory(win, callback) - #bind the handler to all the parent notebooks - win.Bind(wx.EVT_UPDATE_UI, handler) - from gnuradio import gr -def conditional_connect_callback_factory(source, sink, hb, win, size): - nulls = list() - cache = [None] - def callback(visible, init=False): - if visible == cache[0]: return - cache[0] = visible - if not init: hb.lock() - #print 'visible', visible, source, sink - if visible: - if not init: - hb.disconnect(source, nulls[0]) - hb.disconnect(nulls[1], nulls[2]) - hb.disconnect(nulls[2], sink) - while nulls: nulls.pop() - hb.connect(source, sink) - else: - if not init: hb.disconnect(source, sink) - nulls.extend([gr.null_sink(size), gr.null_source(size), gr.head(size, 0)]) - hb.connect(source, nulls[0]) - hb.connect(nulls[1], nulls[2], sink) - if not init: hb.unlock() - return callback - -def conditional_connect(source, sink, hb, win, size): - handler = conditional_connect_callback_factory(source, sink, hb, win, size) - handler(False, init=True) #initially connect - bind_to_visible_event(win, handler) - class wxgui_hb(object): + """ + The wxgui hier block helper/wrapper class: + A hier block should inherit from this class to make use of the wxgui connect method. + To use, call wxgui_connect in place of regular connect; self.win must be defined. + The implementation will conditionally connect or disconnect the self (source) of the hb. + This condition depends on weather or not the window is visible with the parent notebooks. + This condition will be re-checked on every ui update event. + """ + def wxgui_connect(self, *points): """ Use wxgui connect when the first point is the self source of the hb. The win property of this object should be set to the wx window. When this method tries to connect self to the next point, it will conditionally make this connection based on the visibility state. + All other points will be connected normally. """ try: assert points[0] == self or points[0][0] == self - conditional_connect( - points[0], points[1], - win=self.win, hb=self, - size=self._hb.input_signature().sizeof_stream_item(0), - ) + self._conditional_connect(points[0], points[1]) if len(points[1:]) > 1: self.connect(*points[1:]) except (AssertionError, IndexError): self.connect(*points) + def _conditional_connect(self, source, sink): + """ + Create a handler for visibility changes. + Initially call the handler to setup the fg. + Bind the handler to the visibility meta event. + """ + handler = self._conditional_connect_handler_factory( + source=source, sink=sink, win=self.win, hb=self, + size=self._hb.input_signature().sizeof_stream_item(0), + ) + handler(False, init=True) #initially connect + self._bind_to_visible_event(win=self.win, handler=handler) + + @staticmethod + def _conditional_connect_handler_factory(source, sink, hb, win, size): + """ + Create a function that will handle the re-connections based on a flag. + The current state of the connection is stored in the namespace. + """ + nulls = list() + cache = [None] + def callback(visible, init=False): + if visible == cache[0]: return + cache[0] = visible + if not init: hb.lock() + #print 'visible', visible, source, sink + if visible: + if not init: + hb.disconnect(source, nulls[0]) + hb.disconnect(nulls[1], nulls[2]) + hb.disconnect(nulls[2], sink) + while nulls: nulls.pop() + hb.connect(source, sink) + else: + if not init: hb.disconnect(source, sink) + nulls.extend([gr.null_sink(size), gr.null_source(size), gr.head(size, 0)]) + hb.connect(source, nulls[0]) + hb.connect(nulls[1], nulls[2], sink) + if not init: hb.unlock() + return callback + + @staticmethod + def _bind_to_visible_event(win, handler): + """ + Bind a handler to a window when its visibility changes. + Specifically, call the handler when the window visibility changes. + This condition is checked on every update ui event. + @param win the wx window + @param handler a function of 1 param + """ + #is the window visible in the hierarchy + def is_wx_window_visible(my_win): + while True: + parent = my_win.GetParent() + if not parent: return True #reached the top of the hierarchy + #if we are hidden, then finish, otherwise keep traversing up + if isinstance(parent, wx.Notebook) and parent.GetCurrentPage() != my_win: return False + my_win = parent + #call the handler, the arg is shown or not + def handler_factory(my_win, my_handler): + return lambda *args: my_handler(is_wx_window_visible(my_win)) + handler = handler_factory(win, handler) + #bind the handler to all the parent notebooks + win.Bind(wx.EVT_UPDATE_UI, handler) + +################################################## +# Helpful Functions +################################################## + #A macro to apply an index to a key index_key = lambda key, i: "%s_%d"%(key, i+1) -- cgit From dfa5e0a5bccb6b3539c1230281b5bec60196f8a2 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 7 Oct 2009 18:47:21 -0700 Subject: simplify some params --- gr-wxgui/src/python/common.py | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/gr-wxgui/src/python/common.py b/gr-wxgui/src/python/common.py index aae4d63cf..9bf3094f2 100644 --- a/gr-wxgui/src/python/common.py +++ b/gr-wxgui/src/python/common.py @@ -55,39 +55,37 @@ class wxgui_hb(object): Initially call the handler to setup the fg. Bind the handler to the visibility meta event. """ - handler = self._conditional_connect_handler_factory( - source=source, sink=sink, win=self.win, hb=self, - size=self._hb.input_signature().sizeof_stream_item(0), - ) + handler = self._conditional_connect_handler_factory(source=source, sink=sink) handler(False, init=True) #initially connect self._bind_to_visible_event(win=self.win, handler=handler) - @staticmethod - def _conditional_connect_handler_factory(source, sink, hb, win, size): + def _conditional_connect_handler_factory(self, source, sink): """ Create a function that will handle the re-connections based on a flag. The current state of the connection is stored in the namespace. + !!!#TODO This entire method could be replaced with a mute block that starves the stream. """ nulls = list() cache = [None] + size = self._hb.input_signature().sizeof_stream_item(0) def callback(visible, init=False): if visible == cache[0]: return cache[0] = visible - if not init: hb.lock() + if not init: self.lock() #print 'visible', visible, source, sink if visible: if not init: - hb.disconnect(source, nulls[0]) - hb.disconnect(nulls[1], nulls[2]) - hb.disconnect(nulls[2], sink) + self.disconnect(source, nulls[0]) + self.disconnect(nulls[1], nulls[2]) + self.disconnect(nulls[2], sink) while nulls: nulls.pop() - hb.connect(source, sink) + self.connect(source, sink) else: - if not init: hb.disconnect(source, sink) + if not init: self.disconnect(source, sink) nulls.extend([gr.null_sink(size), gr.null_source(size), gr.head(size, 0)]) - hb.connect(source, nulls[0]) - hb.connect(nulls[1], nulls[2], sink) - if not init: hb.unlock() + self.connect(source, nulls[0]) + self.connect(nulls[1], nulls[2], sink) + if not init: self.unlock() return callback @staticmethod -- cgit From 23fa9183aca592865c0652f87709950af5ccd011 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 8 Oct 2009 20:12:34 -0700 Subject: point label transpareny, horizontal offset, and toggle on/off capability --- gr-wxgui/src/python/plotter/common.py | 1 + gr-wxgui/src/python/plotter/grid_plotter_base.py | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/gr-wxgui/src/python/plotter/common.py b/gr-wxgui/src/python/plotter/common.py index 7699986aa..4c50cd787 100644 --- a/gr-wxgui/src/python/plotter/common.py +++ b/gr-wxgui/src/python/plotter/common.py @@ -102,6 +102,7 @@ class point_label_thread(threading.Thread, mutex): #bind plotter mouse events self._plotter.Bind(wx.EVT_MOTION, lambda evt: self.enqueue(evt.GetPosition())) self._plotter.Bind(wx.EVT_LEAVE_WINDOW, lambda evt: self.enqueue(None)) + self._plotter.Bind(wx.EVT_RIGHT_DOWN, lambda evt: plotter.enable_point_label(not plotter.enable_point_label())) #start the thread threading.Thread.__init__(self) self.start() diff --git a/gr-wxgui/src/python/plotter/grid_plotter_base.py b/gr-wxgui/src/python/plotter/grid_plotter_base.py index 39bed1811..a9bd02731 100644 --- a/gr-wxgui/src/python/plotter/grid_plotter_base.py +++ b/gr-wxgui/src/python/plotter/grid_plotter_base.py @@ -36,8 +36,9 @@ AXIS_LABEL_PADDING = 5 TICK_LABEL_PADDING = 5 TITLE_LABEL_PADDING = 7 POINT_LABEL_FONT_SIZE = 8 -POINT_LABEL_COLOR_SPEC = (1, 1, .5) +POINT_LABEL_COLOR_SPEC = (1, 1, 0.5, 0.75) POINT_LABEL_PADDING = 3 +POINT_LABEL_OFFSET = 10 GRID_LINE_DASH_LEN = 4 ################################################## @@ -395,8 +396,12 @@ class grid_plotter_base(plotter_base): if not label_str: return txt = gltext.Text(label_str, font_size=POINT_LABEL_FONT_SIZE) w, h = txt.get_size() + #enable transparency + GL.glEnable(GL.GL_BLEND) + GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA) #draw rect + text - GL.glColor3f(*POINT_LABEL_COLOR_SPEC) - if x > self.width/2: x -= w+2*POINT_LABEL_PADDING + GL.glColor4f(*POINT_LABEL_COLOR_SPEC) + if x > self.width/2: x -= w+2*POINT_LABEL_PADDING + POINT_LABEL_OFFSET + else: x += POINT_LABEL_OFFSET self._draw_rect(x, y-h-2*POINT_LABEL_PADDING, w+2*POINT_LABEL_PADDING, h+2*POINT_LABEL_PADDING) txt.draw_text(wx.Point(x+POINT_LABEL_PADDING, y-h-POINT_LABEL_PADDING)) -- cgit From 075cdb9903a47bec0695e996e44e017a7d3720e7 Mon Sep 17 00:00:00 2001 From: Johnathan Corgan Date: Thu, 8 Oct 2009 20:53:16 -0700 Subject: Added gr.copy(itemsize) block set_enabled(bool) will either copy from input to output (True) or drop the input on the floor (False). --- gnuradio-core/src/lib/general/Makefile.am | 3 + gnuradio-core/src/lib/general/general.i | 5 +- gnuradio-core/src/lib/general/gr_copy.cc | 71 ++++++++++++++++++++++++ gnuradio-core/src/lib/general/gr_copy.h | 62 +++++++++++++++++++++ gnuradio-core/src/lib/general/gr_copy.i | 36 ++++++++++++ gnuradio-core/src/python/gnuradio/gr/Makefile.am | 1 + gnuradio-core/src/python/gnuradio/gr/qa_copy.py | 58 +++++++++++++++++++ 7 files changed, 234 insertions(+), 2 deletions(-) create mode 100644 gnuradio-core/src/lib/general/gr_copy.cc create mode 100644 gnuradio-core/src/lib/general/gr_copy.h create mode 100644 gnuradio-core/src/lib/general/gr_copy.i create mode 100755 gnuradio-core/src/python/gnuradio/gr/qa_copy.py diff --git a/gnuradio-core/src/lib/general/Makefile.am b/gnuradio-core/src/lib/general/Makefile.am index 9b070b865..cf6ff1e65 100644 --- a/gnuradio-core/src/lib/general/Makefile.am +++ b/gnuradio-core/src/lib/general/Makefile.am @@ -51,6 +51,7 @@ libgeneral_la_SOURCES = \ gr_complex_to_interleaved_short.cc \ gr_complex_to_xxx.cc \ gr_conjugate_cc.cc \ + gr_copy.cc \ gr_constellation_decoder_cb.cc \ gr_correlate_access_code_bb.cc \ gr_costas_loop_cc.cc \ @@ -204,6 +205,7 @@ grinclude_HEADERS = \ gr_complex_to_xxx.h \ gr_conjugate_cc.h \ gr_constellation_decoder_cb.h \ + gr_copy.h \ gr_correlate_access_code_bb.h \ gr_costas_loop_cc.h \ gr_count_bits.h \ @@ -373,6 +375,7 @@ swiginclude_HEADERS = \ gr_complex_to_xxx.i \ gr_conjugate_cc.i \ gr_constellation_decoder_cb.i \ + gr_copy.i \ gr_correlate_access_code_bb.i \ gr_costas_loop_cc.i \ gr_cpfsk_bc.i \ diff --git a/gnuradio-core/src/lib/general/general.i b/gnuradio-core/src/lib/general/general.i index 0684e63a5..e1161c8eb 100644 --- a/gnuradio-core/src/lib/general/general.i +++ b/gnuradio-core/src/lib/general/general.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * Copyright 2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -139,7 +139,7 @@ #include #include #include - +#include %} %include "gr_nop.i" @@ -259,3 +259,4 @@ %include "gr_stretch_ff.i" %include "gr_wavelet_ff.i" %include "gr_wvps_ff.i" +%include "gr_copy.i" diff --git a/gnuradio-core/src/lib/general/gr_copy.cc b/gnuradio-core/src/lib/general/gr_copy.cc new file mode 100644 index 000000000..c6564c231 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_copy.cc @@ -0,0 +1,71 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2009 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +gr_copy_sptr +gr_make_copy(size_t itemsize) +{ + return gnuradio::get_initial_sptr(new gr_copy(itemsize)); +} + +gr_copy::gr_copy(size_t itemsize) + : gr_block ("copy", + gr_make_io_signature (1, 1, itemsize), + gr_make_io_signature (1, 1, itemsize)), + d_itemsize(itemsize), + d_enabled(true) +{ +} + +bool +gr_copy::check_topology(int ninputs, int noutputs) +{ + return ninputs == noutputs; +} + +int +gr_copy::general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const uint8_t *in = (const uint8_t *) input_items[0]; + uint8_t *out = (uint8_t *) output_items[0]; + + int n = std::min(ninput_items[0], noutput_items); + int j = 0; + + if (d_enabled) { + memcpy(out, in, n*d_itemsize); + j = n; + } + + consume_each(n); + return j; +} diff --git a/gnuradio-core/src/lib/general/gr_copy.h b/gnuradio-core/src/lib/general/gr_copy.h new file mode 100644 index 000000000..d99aef8b7 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_copy.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2009 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_COPY_H +#define INCLUDED_GR_COPY_H + +#include + +class gr_copy; +typedef boost::shared_ptr gr_copy_sptr; + +gr_copy_sptr gr_make_copy(size_t itemsize); + +/*! + * \brief output[i] = input[i] + * \ingroup misc_blk + * + * When enabled (default), this block copies its input to its output. + * When disabled, this block drops its input on the floor. + * + */ +class gr_copy : public gr_block +{ + size_t d_itemsize; + bool d_enabled; + + friend gr_copy_sptr gr_make_copy(size_t itemsize); + gr_copy(size_t itemsize); + + public: + + bool check_topology(int ninputs, int noutputs); + + void set_enabled(bool enable) { d_enabled = enable; } + bool enabled() const { return d_enabled;} + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif diff --git a/gnuradio-core/src/lib/general/gr_copy.i b/gnuradio-core/src/lib/general/gr_copy.i new file mode 100644 index 000000000..e260d8e84 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_copy.i @@ -0,0 +1,36 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2009 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +GR_SWIG_BLOCK_MAGIC(gr,copy) + +gr_copy_sptr gr_make_copy(size_t itemsize); + +class gr_copy : public gr_block +{ + private: + gr_copy(size_t itemsize); + +public: + + void set_enabled(bool enabled); + bool enabled(); +}; diff --git a/gnuradio-core/src/python/gnuradio/gr/Makefile.am b/gnuradio-core/src/python/gnuradio/gr/Makefile.am index 41ef52240..3aff89ee7 100644 --- a/gnuradio-core/src/python/gnuradio/gr/Makefile.am +++ b/gnuradio-core/src/python/gnuradio/gr/Makefile.am @@ -54,6 +54,7 @@ noinst_PYTHON = \ qa_cma_equalizer.py \ qa_complex_to_xxx.py \ qa_constellation_decoder_cb.py \ + qa_copy.py \ qa_correlate_access_code.py \ qa_delay.py \ qa_diff_encoder.py \ diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_copy.py b/gnuradio-core/src/python/gnuradio/gr/qa_copy.py new file mode 100755 index 000000000..7f9f72a7b --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/gr/qa_copy.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python +# +# Copyright 2009 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest + +class test_copy(gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_copy (self): + src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + expected_result = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + src = gr.vector_source_b(src_data) + op = gr.copy(gr.sizeof_char) + dst = gr.vector_sink_b() + self.tb.connect(src, op, dst) + self.tb.run() + dst_data = dst.data() + self.assertEqual(expected_result, dst_data) + + def test_copy_drop (self): + src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + expected_result = () + src = gr.vector_source_b(src_data) + op = gr.copy(gr.sizeof_char) + op.set_enabled(False) + dst = gr.vector_sink_b() + self.tb.connect(src, op, dst) + self.tb.run() + dst_data = dst.data() + self.assertEqual(expected_result, dst_data) + + +if __name__ == '__main__': + gr_unittest.main () -- cgit From 38d5389f3054164a2f04d6e4e8fe381aa5ee03fc Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 8 Oct 2009 21:46:53 -0700 Subject: using gr copy in the wxgui connect, added gr copy to grc xml --- gr-wxgui/src/python/common.py | 56 ++++++++++++------------------------ grc/blocks/Makefile.am | 1 + grc/blocks/block_tree.xml | 1 + grc/blocks/gr_copy.xml | 67 +++++++++++++++++++++++++++++++++++++++++++ grc/blocks/gr_kludge_copy.xml | 11 ++++++- grc/blocks/gr_nop.xml | 9 ++++++ 6 files changed, 107 insertions(+), 38 deletions(-) create mode 100644 grc/blocks/gr_copy.xml diff --git a/gr-wxgui/src/python/common.py b/gr-wxgui/src/python/common.py index 9bf3094f2..fa11b3152 100644 --- a/gr-wxgui/src/python/common.py +++ b/gr-wxgui/src/python/common.py @@ -30,7 +30,7 @@ class wxgui_hb(object): The wxgui hier block helper/wrapper class: A hier block should inherit from this class to make use of the wxgui connect method. To use, call wxgui_connect in place of regular connect; self.win must be defined. - The implementation will conditionally connect or disconnect the self (source) of the hb. + The implementation will conditionally enable the copy block after the source (self). This condition depends on weather or not the window is visible with the parent notebooks. This condition will be re-checked on every ui update event. """ @@ -45,47 +45,29 @@ class wxgui_hb(object): """ try: assert points[0] == self or points[0][0] == self - self._conditional_connect(points[0], points[1]) - if len(points[1:]) > 1: self.connect(*points[1:]) - except (AssertionError, IndexError): self.connect(*points) + copy = gr.copy(self._hb.input_signature().sizeof_stream_item(0)) + handler = self._handler_factory(copy.set_enabled) + handler(False) #initially disable the copy block + self._bind_to_visible_event(win=self.win, handler=handler) + points = list(points) + points.insert(1, copy) #insert the copy block into the chain + except (AssertionError, IndexError): pass + self.connect(*points) #actually connect the blocks - def _conditional_connect(self, source, sink): - """ - Create a handler for visibility changes. - Initially call the handler to setup the fg. - Bind the handler to the visibility meta event. - """ - handler = self._conditional_connect_handler_factory(source=source, sink=sink) - handler(False, init=True) #initially connect - self._bind_to_visible_event(win=self.win, handler=handler) - - def _conditional_connect_handler_factory(self, source, sink): + @staticmethod + def _handler_factory(handler): """ - Create a function that will handle the re-connections based on a flag. - The current state of the connection is stored in the namespace. - !!!#TODO This entire method could be replaced with a mute block that starves the stream. + Create a function that will cache the visibility flag, + and only call the handler when that flag changes. + @param handler the function to call on a change + @return a function of 1 argument """ - nulls = list() cache = [None] - size = self._hb.input_signature().sizeof_stream_item(0) - def callback(visible, init=False): - if visible == cache[0]: return + def callback(visible): + if cache[0] == visible: return cache[0] = visible - if not init: self.lock() - #print 'visible', visible, source, sink - if visible: - if not init: - self.disconnect(source, nulls[0]) - self.disconnect(nulls[1], nulls[2]) - self.disconnect(nulls[2], sink) - while nulls: nulls.pop() - self.connect(source, sink) - else: - if not init: self.disconnect(source, sink) - nulls.extend([gr.null_sink(size), gr.null_source(size), gr.head(size, 0)]) - self.connect(source, nulls[0]) - self.connect(nulls[1], nulls[2], sink) - if not init: self.unlock() + #print visible, handler + handler(visible) return callback @staticmethod diff --git a/grc/blocks/Makefile.am b/grc/blocks/Makefile.am index 617a3bf60..df3479761 100644 --- a/grc/blocks/Makefile.am +++ b/grc/blocks/Makefile.am @@ -84,6 +84,7 @@ dist_ourdata_DATA = \ gr_complex_to_real.xml \ gr_conjugate_cc.xml \ gr_constellation_decoder_cb.xml \ + gr_copy.xml \ gr_correlate_access_code_bb.xml \ gr_costas_loop_cc.xml \ gr_cpfsk_bc.xml \ diff --git a/grc/blocks/block_tree.xml b/grc/blocks/block_tree.xml index 296f0ee91..6fec0be67 100644 --- a/grc/blocks/block_tree.xml +++ b/grc/blocks/block_tree.xml @@ -300,6 +300,7 @@ gr_skiphead gr_kludge_copy + gr_copy gr_nop xmlrpc_server diff --git a/grc/blocks/gr_copy.xml b/grc/blocks/gr_copy.xml new file mode 100644 index 000000000..757f14303 --- /dev/null +++ b/grc/blocks/gr_copy.xml @@ -0,0 +1,67 @@ + + + + Copy + gr_copy + from gnuradio import gr + gr.copy($type.size*$vlen) +self.$(id).set_enabled($enabled) + set_enabled($enabled) + + Type + type + enum + + + + + + + + Enabled + enabled + True + bool + + + Vec Length + vlen + 1 + int + + $vlen > 0 + + in + $type + $vlen + + + out + $type + $vlen + + diff --git a/grc/blocks/gr_kludge_copy.xml b/grc/blocks/gr_kludge_copy.xml index 3c817c572..8058b082d 100644 --- a/grc/blocks/gr_kludge_copy.xml +++ b/grc/blocks/gr_kludge_copy.xml @@ -5,7 +5,7 @@ ################################################### --> - Copy + Kludge Copy gr_kludge_copy from gnuradio import gr gr.kludge_copy($type.size*$vlen) @@ -39,21 +39,30 @@ size:gr.sizeof_char + + Num Ports + num_ports + 1 + int + Vec Length vlen 1 int + $num_ports > 0 $vlen > 0 in $type $vlen + $num_ports out $type $vlen + $num_ports diff --git a/grc/blocks/gr_nop.xml b/grc/blocks/gr_nop.xml index 127a78a55..bd884d6b8 100644 --- a/grc/blocks/gr_nop.xml +++ b/grc/blocks/gr_nop.xml @@ -39,21 +39,30 @@ size:gr.sizeof_char + + Num Ports + num_ports + 1 + int + Vec Length vlen 1 int + $num_ports > 0 $vlen > 0 in $type $vlen + $num_ports out $type $vlen + $num_ports -- cgit