From 5d69a524f81f234b3fbc41d49ba18d6f6886baba Mon Sep 17 00:00:00 2001 From: jcorgan Date: Thu, 3 Aug 2006 04:51:51 +0000 Subject: Houston, we have a trunk. git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@3122 221aa14e-8319-0410-a670-987f0aec2ac5 --- gr-wxgui/src/python/form.py | 391 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 391 insertions(+) create mode 100755 gr-wxgui/src/python/form.py (limited to 'gr-wxgui/src/python/form.py') diff --git a/gr-wxgui/src/python/form.py b/gr-wxgui/src/python/form.py new file mode 100755 index 000000000..bb41817ca --- /dev/null +++ b/gr-wxgui/src/python/form.py @@ -0,0 +1,391 @@ +#!/usr/bin/env python +# +# Copyright 2005 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 2, 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., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. +# + +import wx +from gnuradio import eng_notation + +# ---------------------------------------------------------------- +# Wrappers for certain widgets +# ---------------------------------------------------------------- + +def button_with_callback(parent, label, callback): + new_id = wx.NewId() + btn = wx.Button(parent, new_id, label) + wx.EVT_BUTTON(parent, new_id, lambda evt: callback()) + return btn + + +# ---------------------------------------------------------------- +# Format converters +# ---------------------------------------------------------------- + +class abstract_converter(object): + def value_to_prim(self, v): + """ + Convert from user specified value to value acceptable to underlying primitive. + The underlying primitive usually expects strings. + """ + raise NotImplementedError + def prim_to_value(self, s): + """ + Convert from underlying primitive value to user specified value. + The underlying primitive usually expects strings. + """ + raise NotImplementedError + def help(self): + return "Any string is acceptable" + +class identity_converter(abstract_converter): + def value_to_prim(self,v): + return v + def prim_to_value(self, s): + return s + +class int_converter(abstract_converter): + def value_to_prim(self, v): + return str(v) + def prim_to_value(self, s): + return int(s, 0) + def help(self): + return "Enter an integer. Leading 0x indicates hex" + +class float_converter(abstract_converter): + def value_to_prim(self, v): + return eng_notation.num_to_str(v) + def prim_to_value(self, s): + return eng_notation.str_to_num(s) + def help(self): + return "Enter a float with optional scale suffix. E.g., 100.1M" + + +# ---------------------------------------------------------------- +# Various types of data entry fields +# ---------------------------------------------------------------- + +class field(object): + """ + A field in a form. + """ + def __init__(self, converter, value): + self.converter = converter + if value is not None: + self.set_value(value) + + def set_value(self, v): + self._set_prim_value(self.converter.value_to_prim(v)) + + def get_value(self): + return self.converter.prim_to_value(self._get_prim_value()) + + def get_value_with_check(self): + """ + Returns (value, error_msg), where error_msg is not None if there was problem + """ + try: + return (self.get_value(), None) + except: + return (None, self._error_msg()) + + def _set_prim_value(self, v): + raise NotImplementedError + + def _get_prim_value(self): + raise NotImplementedError + + def _pair_with_label(self, widget, parent=None, sizer=None, label=None, weight=1): + self.label = label + if label is None: + sizer.Add (widget, weight, wx.EXPAND) + return widget + elif 0: + hbox = wx.BoxSizer(wx.HORIZONTAL) + label_widget = wx.StaticText(parent, -1, label + ': ') + hbox.Add(label_widget, 0, wx.EXPAND) + hbox.Add(widget, 1, wx.EXPAND) + sizer.Add(hbox, weight, wx.EXPAND) + return widget + else: + label_widget = wx.StaticText(parent, -1, label + ': ') + sizer.Add(label_widget, 0, wx.EXPAND) + sizer.Add(widget, weight, wx.EXPAND) + return widget + + def _error_msg(self): + prefix = '' + if self.label: + prefix = self.label + ': ' + return "%s%s is invalid. %s" % (prefix, self._get_prim_value(), + self.converter.help()) + +# static (display-only) text fields + +class static_text_field(field): + def __init__(self, parent=None, sizer=None, label=None, value=None, + converter=identity_converter(), weight=0): + self.f = self._pair_with_label(wx.StaticText(parent, -1, ""), + parent=parent, sizer=sizer, label=label, weight=weight) + field.__init__(self, converter, value) + + def _get_prim_value(self): + return self.f.GetLabel() + + def _set_prim_value(self, v): + self.f.SetLabel(v) + + +class static_int_field(static_text_field): + def __init__(self, parent=None, sizer=None, label=None, value=None, weight=0): + static_text_field.__init__(self, parent, sizer, label, value, int_converter(), weight) + +class static_float_field(static_text_field): + def __init__(self, parent=None, sizer=None, label=None, value=None, weight=0): + static_text_field.__init__(self, parent, sizer, label, value, float_converter(), weight) + + +# editable text fields + +class text_field(field): + def __init__(self, parent=None, sizer=None, label=None, value=None, + converter=identity_converter(), callback=None, weight=1): + style = 0 + if callback: + style = wx.TE_PROCESS_ENTER + + new_id = wx.NewId() + w = wx.TextCtrl(parent, new_id, "", style=style) + self.f = self._pair_with_label(w, parent=parent, sizer=sizer, label=label, weight=weight) + if callback: + wx.EVT_TEXT_ENTER(w, new_id, lambda evt: callback()) + field.__init__(self, converter, value) + + def _get_prim_value(self): + return self.f.GetValue() + + def _set_prim_value(self, v): + self.f.SetValue(v) + + +class int_field(text_field): + def __init__(self, parent=None, sizer=None, label=None, value=None, + callback=None, weight=1): + text_field.__init__(self, parent, sizer, label, value, int_converter(), callback, weight) + +class float_field(text_field): + def __init__(self, parent=None, sizer=None, label=None, value=None, + callback=None, weight=1): + text_field.__init__(self, parent, sizer, label, value, float_converter(), callback, weight) + +# other fields + +class slider_field(field): + def __init__(self, parent=None, sizer=None, label=None, value=None, + converter=identity_converter(), callback=None, min=0, max=100, weight=1): + new_id = wx.NewId() + w = wx.Slider(parent, new_id, (max+min)/2, min, max, + size=wx.Size(250, -1), style=wx.SL_HORIZONTAL | wx.SL_LABELS) + self.f = self._pair_with_label(w, parent=parent, sizer=sizer, label=label, weight=weight) + if callback: + wx.EVT_COMMAND_SCROLL(w, new_id, lambda evt: callback(evt.GetInt())) + field.__init__(self, converter, value) + + def _get_prim_value(self): + return self.f.GetValue() + + def _set_prim_value(self, v): + self.f.SetValue(int(v)) + +class quantized_slider_field(field): + def __init__(self, parent=None, sizer=None, label=None, value=None, + converter=identity_converter(), callback=None, range=None, weight=1): + if not isinstance(range, (tuple, list)) or len(range) != 3: + raise ValueError, range + + self.min = range[0] + self.max = range[1] + self.step_size = float(range[2]) + nsteps = int((self.max-self.min)/self.step_size) + + new_id = wx.NewId() + w = wx.Slider(parent, new_id, 0, 0, nsteps, + size=wx.Size(250, -1), style=wx.SL_HORIZONTAL) + self.f = self._pair_with_label(w, parent=parent, sizer=sizer, label=label, weight=weight) + if callback: + wx.EVT_COMMAND_SCROLL(w, new_id, + lambda evt: callback(self._map_out(evt.GetInt()))) + field.__init__(self, converter, value) + + def _get_prim_value(self): + return self._map_out(self.f.GetValue()) + + def _set_prim_value(self, v): + self.f.SetValue(self._map_in(v)) + + def _map_in(self, x): + return int((x-self.min) / self.step_size) + + def _map_out(self, x): + return x * self.step_size + self.min + +class checkbox_field(field): + def __init__(self, parent=None, sizer=None, label=None, value=None, + converter=identity_converter(), callback=None, weight=1): + new_id = wx.NewId() + w = wx.CheckBox(parent, new_id, label, style=wx.CHK_2STATE) + self.f = self._pair_with_label(w, parent=parent, sizer=sizer, label=None, weight=weight) + if callback: + wx.EVT_CHECKBOX(w, new_id, lambda evt: callback(evt.GetInt())) + field.__init__(self, converter, value) + + def _get_prim_value(self): + return self.f.GetValue() + + def _set_prim_value(self, v): + self.f.SetValue(int(v)) + + +class radiobox_field(field): + def __init__(self, parent=None, sizer=None, label="", value=None, + converter=identity_converter(), callback=None, weight=1, + choices=None, major_dimension=1, specify_rows=False): + new_id = wx.NewId() + + if specify_rows: + style=wx.RA_SPECIFY_ROWS | wx.RA_HORIZONTAL + else: + style=wx.RA_SPECIFY_COLS | wx.RA_HORIZONTAL + + w = wx.RadioBox(parent, new_id, label, style=style, majorDimension=major_dimension, + choices=choices) + self.f = self._pair_with_label(w, parent=parent, sizer=sizer, label=label, weight=weight) + if callback: + wx.EVT_RADIOBOX(w, new_id, lambda evt: callback(evt.GetString())) + field.__init__(self, converter, value) + + def _get_prim_value(self): + return self.f.GetStringSelection() + + def _set_prim_value(self, v): + self.f.SetStringSelection(str(v)) + +# ---------------------------------------------------------------- +# the form class +# ---------------------------------------------------------------- + +class form(dict): + def __init__(self): + dict.__init__(self) + + def check_input_for_errors(self): + """ + Returns list of error messages if there's trouble, + else empty list. + """ + vals = [f.get_value_with_check() for f in self.values()] + return [t[1] for t in vals if t[1] is not None] + + def get_key_vals(self): + d = {} + for (key, f) in self.items(): + d[key] = f.get_value() + return d + + + def _nop(*args): pass + + def check_input_and_call(self, callback, status_handler=_nop): + """ + Return a function that checks the form for errors, and then if it's OK, + invokes the user specified callback, passing it the form key/value dictionary. + status_handler is called with a string indicating results. + """ + def doit_callback(*ignore): + errors = self.check_input_for_errors() + if errors: + status_handler(errors[0]) + #print '\n'.join(tuple(errors)) + else: + kv = self.get_key_vals() + if callback(kv): + status_handler("OK") + else: + status_handler("Failed") + + return doit_callback + + + +# ---------------------------------------------------------------- +# Stand-alone example code +# ---------------------------------------------------------------- + +import sys +from gnuradio.wxgui import stdgui + +class demo_app_flow_graph (stdgui.gui_flow_graph): + def __init__(self, frame, panel, vbox, argv): + stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv) + + self.frame = frame + self.panel = panel + + def _print_kv(kv): + print "kv =", kv + return True + + self.form = form() + + self.form['static1'] = \ + static_text_field(parent=panel, sizer=vbox, + label="Static Text", + value="The Static Value") + + self.form['text1'] = \ + text_field(parent=panel, sizer=vbox, + label="TextCtrl", + value="The Editable Value") + + self.form['int1'] = \ + int_field(parent=panel, sizer=vbox, + label="Int Field", + value=1234) + + self.form['float1'] = \ + float_field(parent=panel, sizer=vbox, + label="Float Field", + value=3.14159) + + self.doit = button_with_callback( + panel, "Do It!", + self.form.check_input_and_call(_print_kv, self._set_status_msg)) + + vbox.Add(self.doit, 0, wx.CENTER) + + def _set_status_msg(self, msg): + self.frame.GetStatusBar().SetStatusText(msg, 0) + + +def main (): + app = stdgui.stdapp (demo_app_flow_graph, "wxgui form demo", nstatus=1) + app.MainLoop () + +if __name__ == '__main__': + main () -- cgit From 86f5c92427b3f4bb30536d76cf63c3fca388fb2f Mon Sep 17 00:00:00 2001 From: eb Date: Wed, 13 Sep 2006 21:30:04 +0000 Subject: Updated FSF address in all files. Fixes ticket:51 git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@3534 221aa14e-8319-0410-a670-987f0aec2ac5 --- gr-wxgui/src/python/form.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gr-wxgui/src/python/form.py') diff --git a/gr-wxgui/src/python/form.py b/gr-wxgui/src/python/form.py index bb41817ca..ea9a8dc9a 100755 --- a/gr-wxgui/src/python/form.py +++ b/gr-wxgui/src/python/form.py @@ -16,8 +16,8 @@ # # 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., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. # import wx -- cgit From 937b719d2e57d0497293d603da10cac2532346f6 Mon Sep 17 00:00:00 2001 From: eb Date: Sat, 21 Jul 2007 03:44:38 +0000 Subject: Updated license from GPL version 2 or later to GPL version 3 or later. git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@6044 221aa14e-8319-0410-a670-987f0aec2ac5 --- gr-wxgui/src/python/form.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gr-wxgui/src/python/form.py') diff --git a/gr-wxgui/src/python/form.py b/gr-wxgui/src/python/form.py index ea9a8dc9a..5ca661836 100755 --- a/gr-wxgui/src/python/form.py +++ b/gr-wxgui/src/python/form.py @@ -6,7 +6,7 @@ # # 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 2, or (at your option) +# 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, -- cgit From 6bf2c048d94e1c673c06c058b23213cd28292520 Mon Sep 17 00:00:00 2001 From: jcorgan Date: Fri, 8 Feb 2008 18:45:33 +0000 Subject: Fixed missed conversion that prevented gr.wxgui from importing correctly. git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@7610 221aa14e-8319-0410-a670-987f0aec2ac5 --- gr-wxgui/src/python/form.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'gr-wxgui/src/python/form.py') diff --git a/gr-wxgui/src/python/form.py b/gr-wxgui/src/python/form.py index 5ca661836..3e303554d 100755 --- a/gr-wxgui/src/python/form.py +++ b/gr-wxgui/src/python/form.py @@ -338,11 +338,11 @@ class form(dict): # ---------------------------------------------------------------- import sys -from gnuradio.wxgui import stdgui +from gnuradio.wxgui import stdgui2 -class demo_app_flow_graph (stdgui.gui_flow_graph): +class demo_app_flow_graph (stdgui2.std_top_block): def __init__(self, frame, panel, vbox, argv): - stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv) + stdgui2.std_top_block.__init__ (self, frame, panel, vbox, argv) self.frame = frame self.panel = panel @@ -384,7 +384,7 @@ class demo_app_flow_graph (stdgui.gui_flow_graph): def main (): - app = stdgui.stdapp (demo_app_flow_graph, "wxgui form demo", nstatus=1) + app = stdgui2.stdapp(demo_app_flow_graph, "wxgui form demo", nstatus=1) app.MainLoop () if __name__ == '__main__': -- cgit From 36649d4e472172fe840444ac0268c7b6b4da94b4 Mon Sep 17 00:00:00 2001 From: jcorgan Date: Thu, 14 Aug 2008 18:43:15 +0000 Subject: Merged changeset r9241:9289 from jblum/glwxgui into trunk. Adds OpenGL versions of fftsink, waterfallsink, and scopesink, and new constsink. See README.gl for use. (Josh Blum) git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@9290 221aa14e-8319-0410-a670-987f0aec2ac5 --- gr-wxgui/src/python/form.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 gr-wxgui/src/python/form.py (limited to 'gr-wxgui/src/python/form.py') diff --git a/gr-wxgui/src/python/form.py b/gr-wxgui/src/python/form.py old mode 100755 new mode 100644 -- cgit From f92986d6ff10330ee4608510f7baaa895e6772e0 Mon Sep 17 00:00:00 2001 From: jcorgan Date: Sun, 22 Feb 2009 20:20:34 +0000 Subject: Adds new simple gui class to gr-wxgui. Apps using it to come. git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@10474 221aa14e-8319-0410-a670-987f0aec2ac5 --- gr-wxgui/src/python/form.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gr-wxgui/src/python/form.py') diff --git a/gr-wxgui/src/python/form.py b/gr-wxgui/src/python/form.py index 3e303554d..e635c5461 100644 --- a/gr-wxgui/src/python/form.py +++ b/gr-wxgui/src/python/form.py @@ -273,7 +273,7 @@ class radiobox_field(field): else: style=wx.RA_SPECIFY_COLS | wx.RA_HORIZONTAL - w = wx.RadioBox(parent, new_id, label, style=style, majorDimension=major_dimension, + w = wx.RadioBox(parent, new_id, label="", style=style, majorDimension=major_dimension, choices=choices) self.f = self._pair_with_label(w, parent=parent, sizer=sizer, label=label, weight=weight) if callback: -- cgit From 1df84e329951c51ce7fedd5eb3a2bd1e4bb8ad3d Mon Sep 17 00:00:00 2001 From: jcorgan Date: Sun, 8 Mar 2009 02:38:18 +0000 Subject: Fix radiobox label git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@10574 221aa14e-8319-0410-a670-987f0aec2ac5 --- gr-wxgui/src/python/form.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'gr-wxgui/src/python/form.py') diff --git a/gr-wxgui/src/python/form.py b/gr-wxgui/src/python/form.py index e635c5461..b55b04d73 100644 --- a/gr-wxgui/src/python/form.py +++ b/gr-wxgui/src/python/form.py @@ -263,7 +263,7 @@ class checkbox_field(field): class radiobox_field(field): - def __init__(self, parent=None, sizer=None, label="", value=None, + def __init__(self, parent=None, sizer=None, label=None, value=None, converter=identity_converter(), callback=None, weight=1, choices=None, major_dimension=1, specify_rows=False): new_id = wx.NewId() @@ -273,9 +273,9 @@ class radiobox_field(field): else: style=wx.RA_SPECIFY_COLS | wx.RA_HORIZONTAL - w = wx.RadioBox(parent, new_id, label="", style=style, majorDimension=major_dimension, + w = wx.RadioBox(parent, new_id, label=label, style=style, majorDimension=major_dimension, choices=choices) - self.f = self._pair_with_label(w, parent=parent, sizer=sizer, label=label, weight=weight) + self.f = self._pair_with_label(w, parent=parent, sizer=sizer, label=None, weight=weight) if callback: wx.EVT_RADIOBOX(w, new_id, lambda evt: callback(evt.GetString())) field.__init__(self, converter, value) -- cgit From f919f9dcbb54a08e6e26d6c229ce92fb784fa1b2 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Fri, 13 Apr 2012 18:36:53 -0400 Subject: Removed whitespace and added dtools/bin/remove-whitespace as a tool to do this in the future. The sed script was provided by Moritz Fischer. --- gr-wxgui/src/python/form.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'gr-wxgui/src/python/form.py') diff --git a/gr-wxgui/src/python/form.py b/gr-wxgui/src/python/form.py index b55b04d73..0442e49c8 100644 --- a/gr-wxgui/src/python/form.py +++ b/gr-wxgui/src/python/form.py @@ -1,24 +1,24 @@ #!/usr/bin/env python # # Copyright 2005 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. -# +# import wx from gnuradio import eng_notation @@ -32,7 +32,7 @@ def button_with_callback(parent, label, callback): btn = wx.Button(parent, new_id, label) wx.EVT_BUTTON(parent, new_id, lambda evt: callback()) return btn - + # ---------------------------------------------------------------- # Format converters @@ -128,7 +128,7 @@ class field(object): sizer.Add(label_widget, 0, wx.EXPAND) sizer.Add(widget, weight, wx.EXPAND) return widget - + def _error_msg(self): prefix = '' if self.label: @@ -223,7 +223,7 @@ class quantized_slider_field(field): self.max = range[1] self.step_size = float(range[2]) nsteps = int((self.max-self.min)/self.step_size) - + new_id = wx.NewId() w = wx.Slider(parent, new_id, 0, 0, nsteps, size=wx.Size(250, -1), style=wx.SL_HORIZONTAL) @@ -272,7 +272,7 @@ class radiobox_field(field): style=wx.RA_SPECIFY_ROWS | wx.RA_HORIZONTAL else: style=wx.RA_SPECIFY_COLS | wx.RA_HORIZONTAL - + w = wx.RadioBox(parent, new_id, label=label, style=style, majorDimension=major_dimension, choices=choices) self.f = self._pair_with_label(w, parent=parent, sizer=sizer, label=None, weight=weight) @@ -301,7 +301,7 @@ class form(dict): """ vals = [f.get_value_with_check() for f in self.values()] return [t[1] for t in vals if t[1] is not None] - + def get_key_vals(self): d = {} for (key, f) in self.items(): @@ -310,7 +310,7 @@ class form(dict): def _nop(*args): pass - + def check_input_and_call(self, callback, status_handler=_nop): """ Return a function that checks the form for errors, and then if it's OK, @@ -352,7 +352,7 @@ class demo_app_flow_graph (stdgui2.std_top_block): return True self.form = form() - + self.form['static1'] = \ static_text_field(parent=panel, sizer=vbox, label="Static Text", @@ -382,7 +382,7 @@ class demo_app_flow_graph (stdgui2.std_top_block): def _set_status_msg(self, msg): self.frame.GetStatusBar().SetStatusText(msg, 0) - + def main (): app = stdgui2.stdapp(demo_app_flow_graph, "wxgui form demo", nstatus=1) app.MainLoop () -- cgit