diff options
Diffstat (limited to 'grc/python')
-rw-r--r-- | grc/python/Block.py | 43 | ||||
-rw-r--r-- | grc/python/Constants.py | 66 | ||||
-rw-r--r-- | grc/python/FlowGraph.py | 1 | ||||
-rw-r--r-- | grc/python/Generator.py | 39 | ||||
-rw-r--r-- | grc/python/Port.py | 13 | ||||
-rw-r--r-- | grc/python/block.dtd | 5 | ||||
-rw-r--r-- | grc/python/default_flow_graph.grc | 4 | ||||
-rw-r--r-- | grc/python/flow_graph.tmpl | 33 |
8 files changed, 142 insertions, 62 deletions
diff --git a/grc/python/Block.py b/grc/python/Block.py index 48b827792e..303aa85ed5 100644 --- a/grc/python/Block.py +++ b/grc/python/Block.py @@ -17,22 +17,18 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA """ -from collections import defaultdict +import itertools +import collections +from .. base.Constants import BLOCK_FLAG_NEED_QT_GUI, BLOCK_FLAG_NEED_WX_GUI from .. base.Block import Block as _Block from .. gui.Block import Block as _GUIBlock + from . FlowGraph import _variable_matcher import extract_docs -class Block(_Block, _GUIBlock): - - def is_virtual_sink(self): return self.get_key() == 'virtual_sink' - def is_virtual_source(self): return self.get_key() == 'virtual_source' - ##for make source to keep track of indexes - _source_count = 0 - ##for make sink to keep track of indexes - _sink_count = 0 +class Block(_Block, _GUIBlock): def __init__(self, flow_graph, n): """ @@ -52,9 +48,9 @@ class Block(_Block, _GUIBlock): self._var_make = n.find('var_make') self._checks = n.findall('check') self._callbacks = n.findall('callback') - self._throttle = n.find('throttle') or '' self._bus_structure_source = n.find('bus_structure_source') or '' self._bus_structure_sink = n.find('bus_structure_sink') or '' + self.port_counters = [itertools.count(), itertools.count()] #build the block _Block.__init__( self, @@ -78,8 +74,6 @@ class Block(_Block, _GUIBlock): except: return '' - def throttle(self): return bool(self._throttle) - def validate(self): """ Validate this block. @@ -102,13 +96,22 @@ class Block(_Block, _GUIBlock): self.get_parent().evaluate(value) except Exception as err: self.add_error_message('Value "%s" cannot be evaluated:\n%s' % (value, err)) + # check if this is a GUI block and matches the selected generate option current_generate_option = self.get_parent().get_option('generate_options') - for label, option in (('WX GUI', 'wx_gui'), ('QT GUI', 'qt_gui')): - if self.get_name().startswith(label) and current_generate_option != option: + + def check_generate_mode(label, flag, valid_options): + block_requires_mode = ( + flag in self.get_flags() or + self.get_name().upper().startswith(label) + ) + if block_requires_mode and current_generate_option not in valid_options: self.add_error_message("Can't generate this block in mode " + repr(current_generate_option)) + check_generate_mode('WX GUI', BLOCK_FLAG_NEED_WX_GUI, ('wx_gui',)) + check_generate_mode('QT GUI', BLOCK_FLAG_NEED_QT_GUI, ('qt_gui', 'hb_qt_gui')) + def rewrite(self): """ Add and remove ports to adjust for the nports. @@ -130,13 +133,13 @@ class Block(_Block, _GUIBlock): master_port.remove_clone(port) ports.remove(port) # add more cloned ports - for i in range(num_ports, nports): + for j in range(num_ports, nports): port = master_port.add_clone() - ports.insert(ports.index(master_port) + i, port) + ports.insert(ports.index(master_port) + j, port) self.back_ofthe_bus(ports) # renumber non-message/-msg ports - domain_specific_port_index = defaultdict(int) + domain_specific_port_index = collections.defaultdict(int) for port in filter(lambda p: p.get_key().isdigit(), ports): domain = port.get_domain() port._key = str(domain_specific_port_index[domain]) @@ -204,3 +207,9 @@ class Block(_Block, _GUIBlock): if 'self.' in callback: return callback return 'self.%s.%s'%(self.get_id(), callback) return map(make_callback, self._callbacks) + + def is_virtual_sink(self): + return self.get_key() == 'virtual_sink' + + def is_virtual_source(self): + return self.get_key() == 'virtual_source' diff --git a/grc/python/Constants.py b/grc/python/Constants.py index 79ff8bab35..1df1fc492b 100644 --- a/grc/python/Constants.py +++ b/grc/python/Constants.py @@ -50,31 +50,55 @@ FLOW_GRAPH_TEMPLATE = os.path.join(DATA_DIR, 'flow_graph.tmpl') BLOCK_DTD = os.path.join(DATA_DIR, 'block.dtd') DEFAULT_FLOW_GRAPH = os.path.join(DATA_DIR, 'default_flow_graph.grc') + +# Updating colors. Using the standard color pallette from: +# http://www.google.com/design/spec/style/color.html#color-color-palette +# Most are based on the main, primary color standard. Some are within +# that color's spectrum when it was deemed necessary. +GRC_COLOR_BROWN = '#795548' +GRC_COLOR_BLUE = '#2196F3' +GRC_COLOR_LIGHT_GREEN = '#8BC34A' +GRC_COLOR_GREEN = '#4CAF50' +GRC_COLOR_AMBER = '#FFC107' +GRC_COLOR_PURPLE = '#9C27B0' +GRC_COLOR_CYAN = '#00BCD4' +GRC_COLOR_GR_ORANGE = '#FF6905' +GRC_COLOR_ORANGE = '#F57C00' +GRC_COLOR_LIME = '#CDDC39' +GRC_COLOR_TEAL = '#009688' +GRC_COLOR_YELLOW = '#FFEB3B' +GRC_COLOR_PINK = '#F50057' +GRC_COLOR_LIGHT_PURPLE = '#E040FB' +GRC_COLOR_DARK_GREY = '#72706F' +GRC_COLOR_GREY = '#BDBDBD' +GRC_COLOR_WHITE = '#FFFFFF' + + CORE_TYPES = ( #name, key, sizeof, color - ('Complex Float 64', 'fc64', 16, '#CC8C69'), - ('Complex Float 32', 'fc32', 8, '#3399FF'), - ('Complex Integer 64', 'sc64', 16, '#66CC00'), - ('Complex Integer 32', 'sc32', 8, '#33cc66'), - ('Complex Integer 16', 'sc16', 4, '#cccc00'), - ('Complex Integer 8', 'sc8', 2, '#cc00cc'), - ('Float 64', 'f64', 8, '#66CCCC'), - ('Float 32', 'f32', 4, '#FF8C69'), - ('Integer 64', 's64', 8, '#99FF33'), - ('Integer 32', 's32', 4, '#00FF99'), - ('Integer 16', 's16', 2, '#FFFF66'), - ('Integer 8', 's8', 1, '#FF66FF'), - ('Message Queue', 'msg', 0, '#777777'), - ('Async Message', 'message', 0, '#C0C0C0'), - ('Bus Connection', 'bus', 0, '#FFFFFF'), - ('Wildcard', '', 0, '#FFFFFF'), + ('Complex Float 64', 'fc64', 16, GRC_COLOR_BROWN), + ('Complex Float 32', 'fc32', 8, GRC_COLOR_BLUE), + ('Complex Integer 64', 'sc64', 16, GRC_COLOR_LIGHT_GREEN), + ('Complex Integer 32', 'sc32', 8, GRC_COLOR_GREEN), + ('Complex Integer 16', 'sc16', 4, GRC_COLOR_AMBER), + ('Complex Integer 8', 'sc8', 2, GRC_COLOR_PURPLE), + ('Float 64', 'f64', 8, GRC_COLOR_CYAN), + ('Float 32', 'f32', 4, GRC_COLOR_ORANGE), + ('Integer 64', 's64', 8, GRC_COLOR_LIME), + ('Integer 32', 's32', 4, GRC_COLOR_TEAL), + ('Integer 16', 's16', 2, GRC_COLOR_YELLOW), + ('Integer 8', 's8', 1, GRC_COLOR_LIGHT_PURPLE), + ('Message Queue', 'msg', 0, GRC_COLOR_DARK_GREY), + ('Async Message', 'message', 0, GRC_COLOR_GREY), + ('Bus Connection', 'bus', 0, GRC_COLOR_WHITE), + ('Wildcard', '', 0, GRC_COLOR_WHITE), ) ALIAS_TYPES = { - 'complex' : (8, '#3399FF'), - 'float' : (4, '#FF8C69'), - 'int' : (4, '#00FF99'), - 'short' : (2, '#FFFF66'), - 'byte' : (1, '#FF66FF'), + 'complex' : (8, GRC_COLOR_BLUE), + 'float' : (4, GRC_COLOR_ORANGE), + 'int' : (4, GRC_COLOR_TEAL), + 'short' : (2, GRC_COLOR_YELLOW), + 'byte' : (1, GRC_COLOR_LIGHT_PURPLE), } TYPE_TO_COLOR = dict() diff --git a/grc/python/FlowGraph.py b/grc/python/FlowGraph.py index d7337b8a96..49530af8a3 100644 --- a/grc/python/FlowGraph.py +++ b/grc/python/FlowGraph.py @@ -20,7 +20,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA import expr_utils from .. base.FlowGraph import FlowGraph as _FlowGraph from .. gui.FlowGraph import FlowGraph as _GUIFlowGraph -from .. base.odict import odict import re _variable_matcher = re.compile('^(variable\w*)$') diff --git a/grc/python/Generator.py b/grc/python/Generator.py index a3f9f10fc1..98b671dde5 100644 --- a/grc/python/Generator.py +++ b/grc/python/Generator.py @@ -27,6 +27,7 @@ from Cheetah.Template import Template from .. gui import Messages from .. base import ParseXML from .. base import odict +from .. base.Constants import BLOCK_FLAG_NEED_QT_GUI from . Constants import TOP_BLOCK_FILE_MODE, FLOW_GRAPH_TEMPLATE, \ XTERM_EXECUTABLE, HIER_BLOCK_FILE_MODE, HIER_BLOCKS_LIB_DIR, BLOCK_DTD @@ -47,9 +48,13 @@ class Generator(object): """ self._generate_options = flow_graph.get_option('generate_options') if self._generate_options == 'hb': - self._generator = HierBlockGenerator(flow_graph, file_path) + generator_cls = HierBlockGenerator + elif self._generate_options == 'hb_qt_gui': + generator_cls = QtHierBlockGenerator else: - self._generator = TopBlockGenerator(flow_graph, file_path) + generator_cls = TopBlockGenerator + + self._generator = generator_cls(flow_graph, file_path) def get_generate_options(self): return self._generate_options @@ -86,8 +91,8 @@ class TopBlockGenerator(object): def write(self): """generate output and write it to files""" # do throttle warning - throttling_blocks = filter(lambda b: b.throttle(), self._flow_graph.get_enabled_blocks()) - if not throttling_blocks and self._generate_options != 'hb': + throttling_blocks = filter(lambda b: b.throtteling(), self._flow_graph.get_enabled_blocks()) + if not throttling_blocks and not self._generate_options.startswith('hb'): Messages.send_warning("This flow graph may not have flow control: " "no audio or RF hardware blocks found. " "Add a Misc->Throttle block to your flow " @@ -325,3 +330,29 @@ class HierBlockGenerator(TopBlockGenerator): n = {'block': block_n} return n + + +class QtHierBlockGenerator(HierBlockGenerator): + + def _build_block_n_from_flow_graph_io(self): + n = HierBlockGenerator._build_block_n_from_flow_graph_io(self) + block_n = n['block'] + + if not block_n['name'].upper().startswith('QT GUI'): + block_n['name'] = 'QT GUI ' + block_n['name'] + + block_n.insert_after('category', 'flags', BLOCK_FLAG_NEED_QT_GUI) + + gui_hint_param = odict() + gui_hint_param['name'] = 'GUI Hint' + gui_hint_param['key'] = 'gui_hint' + gui_hint_param['value'] = '' + gui_hint_param['type'] = 'gui_hint' + gui_hint_param['hide'] = 'part' + block_n['param'].append(gui_hint_param) + + block_n['make'] += ( + "\n#set $win = 'self.%s' % $id" + "\n${gui_hint()($win)}" + ) + return n diff --git a/grc/python/Port.py b/grc/python/Port.py index 765e1d7423..249d7aed71 100644 --- a/grc/python/Port.py +++ b/grc/python/Port.py @@ -100,14 +100,11 @@ class Port(_Port, _GUIPort): elif n['domain'] == GR_MESSAGE_DOMAIN: n['key'] = n['name'] n['type'] = 'message' # for port color - if n['type'] == 'msg': n['key'] = 'msg' - if dir == 'source' and not n.find('key'): - n['key'] = str(block._source_count) - block._source_count += 1 - if dir == 'sink' and not n.find('key'): - n['key'] = str(block._sink_count) - block._sink_count += 1 - #build the port + if n['type'] == 'msg': + n['key'] = 'msg' + if not n.find('key'): + n['key'] = str(next(block.port_counters[dir == 'source'])) + # build the port _Port.__init__( self, block=block, diff --git a/grc/python/block.dtd b/grc/python/block.dtd index 8cfd3dd392..145f4d8610 100644 --- a/grc/python/block.dtd +++ b/grc/python/block.dtd @@ -25,7 +25,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA Top level element. A block contains a name, ...parameters list, and list of IO ports. --> -<!ELEMENT block (name, key, category?, throttle?, import*, var_make?, var_value?, make, callback*, param_tab_order?, param*, bus_sink?, bus_source?, check*, sink*, source*, bus_structure_sink?, bus_structure_source?, doc?, grc_source?)> +<!ELEMENT block (name, key, category?, throttle?, flags?, import*, var_make?, var_value?, + make, callback*, param_tab_order?, param*, bus_sink?, bus_source?, check*, + sink*, source*, bus_structure_sink?, bus_structure_source?, doc?, grc_source?)> <!-- Sub level elements. --> @@ -64,3 +66,4 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA <!ELEMENT callback (#PCDATA)> <!ELEMENT optional (#PCDATA)> <!ELEMENT throttle (#PCDATA)> +<!ELEMENT flags (#PCDATA)> diff --git a/grc/python/default_flow_graph.grc b/grc/python/default_flow_graph.grc index 53d39e885a..059509d34b 100644 --- a/grc/python/default_flow_graph.grc +++ b/grc/python/default_flow_graph.grc @@ -14,7 +14,7 @@ </param> <param> <key>_coordinate</key> - <value>(10, 10)</value> + <value>(8, 8)</value> </param> <param> <key>_rotation</key> @@ -33,7 +33,7 @@ </param> <param> <key>_coordinate</key> - <value>(10, 170)</value> + <value>(8, 160)</value> </param> <param> <key>_rotation</key> diff --git a/grc/python/flow_graph.tmpl b/grc/python/flow_graph.tmpl index 814b513213..3dd772b6ee 100644 --- a/grc/python/flow_graph.tmpl +++ b/grc/python/flow_graph.tmpl @@ -1,4 +1,4 @@ -#if $generate_options != 'hb' +#if not $generate_options.startswith('hb') #!/usr/bin/env python2 #end if ######################################################## @@ -61,7 +61,8 @@ sys.path.append(os.environ.get('GRC_HIER_PATH', os.path.expanduser('~/.grc_gnura #end if #for $imp in $imports -$(imp.replace(" # grc-generated hier_block", "")) +##$(imp.replace(" # grc-generated hier_block", "")) +$imp #end for ######################################################## @@ -76,6 +77,7 @@ $(imp.replace(" # grc-generated hier_block", "")) #if $generate_options == 'wx_gui' #import gtk #set $icon = gtk.IconTheme().lookup_icon('gnuradio-grc', 32, 0) + class $(class_name)(grc_wxgui.top_block_gui): def __init__($param_str): @@ -85,7 +87,7 @@ class $(class_name)(grc_wxgui.top_block_gui): self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY)) #end if #elif $generate_options == 'qt_gui' -from distutils.version import StrictVersion + class $(class_name)(gr.top_block, Qt.QWidget): def __init__($param_str): @@ -110,16 +112,21 @@ class $(class_name)(gr.top_block, Qt.QWidget): self.settings = Qt.QSettings("GNU Radio", "$class_name") self.restoreGeometry(self.settings.value("geometry").toByteArray()) - #elif $generate_options == 'no_gui' + class $(class_name)(gr.top_block): def __init__($param_str): gr.top_block.__init__(self, "$title") -#elif $generate_options == 'hb' +#elif $generate_options.startswith('hb') #set $in_sigs = $flow_graph.get_hier_block_stream_io('in') #set $out_sigs = $flow_graph.get_hier_block_stream_io('out') + +#if $generate_options == 'hb_qt_gui' +class $(class_name)(gr.hier_block2, Qt.QWidget): +#else class $(class_name)(gr.hier_block2): +#end if #def make_io_sig($io_sigs) #set $size_strs = ['%s*%s'%(io_sig['size'], io_sig['vlen']) for io_sig in $io_sigs] #if len($io_sigs) == 0 @@ -143,6 +150,14 @@ gr.io_signaturev($(len($io_sigs)), $(len($io_sigs)), [$(', '.join($size_strs))]) #for $pad in $flow_graph.get_hier_block_message_io('out') self.message_port_register_hier_in("$pad['label']") #end for + #if $generate_options == 'hb_qt_gui' + + Qt.QWidget.__init__(self) + self.top_layout = Qt.QVBoxLayout() + self.top_grid_layout = Qt.QGridLayout() + self.top_layout.addLayout(self.top_grid_layout) + self.setLayout(self.top_layout) + #end if #end if #if $flow_graph.get_option('thread_safe_setters') @@ -304,7 +319,7 @@ $param.get_make()#slurp #end if $short_id#slurp #end def -#if $generate_options != 'hb' +#if not $generate_options.startswith('hb') if __name__ == '__main__': parser = OptionParser(option_class=eng_option, usage="%prog: [options]") @@ -334,7 +349,8 @@ if __name__ == '__main__': tb.Wait() #end if #elif $generate_options == 'qt_gui' - if(StrictVersion(Qt.qVersion()) >= StrictVersion("4.5.0")): + from distutils.version import StrictVersion + if StrictVersion(Qt.qVersion()) >= StrictVersion("4.5.0"): Qt.QApplication.setGraphicsSystem(gr.prefs().get_string('qtgui','style','raster')) qapp = Qt.QApplication(sys.argv) tb = $(class_name)($(', '.join($params_eq_list))) @@ -346,6 +362,7 @@ if __name__ == '__main__': #end if #end if tb.show() + def quitting(): tb.stop() tb.wait() @@ -358,7 +375,7 @@ if __name__ == '__main__': sys.stderr.write("Monitor '{0}' does not have an enable ('en') parameter.".format("tb.$m.get_id()")) #end for qapp.exec_() - tb = None #to clean up Qt widgets + tb = None # to clean up Qt widgets #elif $generate_options == 'no_gui' tb = $(class_name)($(', '.join($params_eq_list))) #set $run_options = $flow_graph.get_option('run_options') |