[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] r8808 - in grc/trunk/src: grc grc/elements grc/gui grc
From: |
jblum |
Subject: |
[Commit-gnuradio] r8808 - in grc/trunk/src: grc grc/elements grc/gui grc/gui/elements grc_gnuradio |
Date: |
Sat, 5 Jul 2008 23:28:13 -0600 (MDT) |
Author: jblum
Date: 2008-07-05 23:28:12 -0600 (Sat, 05 Jul 2008)
New Revision: 8808
Modified:
grc/trunk/src/grc/ActionHandler.py
grc/trunk/src/grc/Actions.py
grc/trunk/src/grc/elements/Block.py
grc/trunk/src/grc/elements/Connection.py
grc/trunk/src/grc/elements/Param.py
grc/trunk/src/grc/gui/Bars.py
grc/trunk/src/grc/gui/Dialogs.py
grc/trunk/src/grc/gui/SignalBlockParamsDialog.py
grc/trunk/src/grc/gui/elements/Block.py
grc/trunk/src/grc/gui/elements/Colors.py
grc/trunk/src/grc/gui/elements/Connection.py
grc/trunk/src/grc/gui/elements/Element.py
grc/trunk/src/grc/gui/elements/FlowGraph.py
grc/trunk/src/grc_gnuradio/Generator.py
grc/trunk/src/grc_gnuradio/Param.py
Log:
support for disable/enable blocks in flowgraph
Modified: grc/trunk/src/grc/ActionHandler.py
===================================================================
--- grc/trunk/src/grc/ActionHandler.py 2008-07-06 02:38:05 UTC (rev 8807)
+++ grc/trunk/src/grc/ActionHandler.py 2008-07-06 05:28:12 UTC (rev 8808)
@@ -17,7 +17,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
"""
address@hidden ActionHandler
-#ActionHandler builds the interface and handles most of the user inputs.
+#ActionHandler builds the interface and handles most of the user inputs.
address@hidden Josh Blum
import os, sys, signal
@@ -39,16 +39,16 @@
The action handler will setup all the major window components,
and handle button presses and flow graph operations from the GUI.
"""
-
- def __init__(self, file_paths, platform):
+
+ def __init__(self, file_paths, platform):
"""!
ActionHandler constructor.
- Create the main window, setup the message handler, import the
preferences,
+ Create the main window, setup the message handler, import the
preferences,
and connect all of the action handlers. Finally, enter the gtk
main loop and block.
@param file_paths a list of flow graph file passed from command
line
@param platform platform module
"""
- platform = Platform(platform)
+ platform = Platform(platform)
if PY_GTK_ICON:
gtk.window_set_default_icon_from_file(PY_GTK_ICON)
for action in ACTIONS_LIST: action.connect('activate',
self._handle_actions)
#setup the main window
@@ -65,14 +65,14 @@
#initialize
self.init_file_paths = file_paths
self.handle_states(APPLICATION_INITIALIZE)
- #enter the mainloop
+ #enter the mainloop
gtk.gdk.threads_init()
- gtk.main()
-
+ gtk.main()
+
def _handle_key_press(self, widget, event):
"""
- Handle key presses from the keyboard.
- Translate key combos into actions.
+ Handle key presses from the keyboard.
+ Translate key combos into actions.
Key combinations that do not include special keys, such as ctrl
or Fcn*,
Also, require that the flow graph has mouse focus when choosing
to handle keys.
@return true if the flow graph is in active use
@@ -82,7 +82,7 @@
ctrl = event.state & gtk.gdk.CONTROL_MASK
alt = event.state & gtk.gdk.MOD1_MASK
shift = event.state & gtk.gdk.SHIFT_MASK
- #################### save/open/new/close
###############################
+ #################### save/open/new/close
###############################
if ctrl and keyname == 's':
self.handle_states(FLOW_GRAPH_SAVE)
elif ctrl and keyname == 'o':
@@ -107,16 +107,21 @@
self.handle_states(BLOCK_ROTATE_RIGHT)
elif self.get_focus_flag() and keyname == 'Left': #mouse focus
self.handle_states(BLOCK_ROTATE_LEFT)
+ #################### Enable/Disable
###############################
+ elif self.get_focus_flag() and keyname == 'e': #mouse focus
+ self.handle_states(BLOCK_ENABLE)
+ elif self.get_focus_flag() and keyname == 'd': #mouse focus
+ self.handle_states(BLOCK_DISABLE)
#################### Data Type
###############################
elif self.get_focus_flag() and keyname == 'Down': #mouse focus
self.handle_states(BLOCK_INC_TYPE)
elif self.get_focus_flag() and keyname == 'Up': #mouse focus
self.handle_states(BLOCK_DEC_TYPE)
- #################### Port Controllers
###############################
+ #################### Port Controllers
###############################
elif self.get_focus_flag() and keyname in ('equal','plus',
'KP_Add'): #mouse focus
self.handle_states(PORT_CONTROLLER_INC)
elif self.get_focus_flag() and keyname in ('minus',
'KP_Subtract'): #mouse focus
- self.handle_states(PORT_CONTROLLER_DEC)
+ self.handle_states(PORT_CONTROLLER_DEC)
#################### Gen/Exec/Stop/Print
###############################
elif keyname == 'F5':
self.handle_states(FLOW_GRAPH_GEN)
@@ -128,31 +133,31 @@
self.handle_states(FLOW_GRAPH_SCREEN_CAPTURE)
#propagate this if the fg is not in focus or nothing is selected
return self.get_focus_flag() and
self.get_flow_graph().is_selected()
-
+
def _quit(self, window, event):
"""!
Handle the delete event from the main window.
- Generated by pressing X to close, alt+f4, or right click+close.
+ Generated by pressing X to close, alt+f4, or right click+close.
This method in turns calls the state handler to quit.
- @return true
+ @return true
"""
self.handle_states(APPLICATION_QUIT)
- return True
-
- def _handle_actions(self, event):
+ return True
+
+ def _handle_actions(self, event):
"""
- Handle all of the activate signals from the gtk actions.
- The action signals derive from clicking on a toolbar or menu
bar button.
+ Handle all of the activate signals from the gtk actions.
+ The action signals derive from clicking on a toolbar or menu
bar button.
Forward the action to the state handler.
"""
- self.handle_states(event.get_name())
-
+ self.handle_states(event.get_name())
+
def handle_states(self, state=''):
"""!
- Handle the state changes in the GUI.
- Handle all of the state changes that arise from the action
handler or other gui and
- inputs in the application. The state passed to the
handle_states method is a string descriping
- the change. A series of if/elif statements handle the state by
greying out action buttons, causing
+ Handle the state changes in the GUI.
+ Handle all of the state changes that arise from the action
handler or other gui and
+ inputs in the application. The state passed to the
handle_states method is a string descriping
+ the change. A series of if/elif statements handle the state by
greying out action buttons, causing
changes in the flow graph, saving/opening files... The
handle_states method is passed to the
contructors of many of the classes used in this application
enabling them to report any state change.
@param state a string describing the state change
@@ -161,17 +166,17 @@
##############################################################################################
# Initalize/Quit
##############################################################################################
- if state == APPLICATION_INITIALIZE:
+ if state == APPLICATION_INITIALIZE:
for action in ACTIONS_LIST: action.set_sensitive(False)
#set all actions disabled
- # enable a select few actions
+ # enable a select few actions
for action in (
APPLICATION_QUIT, FLOW_GRAPH_NEW,
FLOW_GRAPH_OPEN, FLOW_GRAPH_SAVE_AS, FLOW_GRAPH_CLOSE,
ABOUT_WINDOW_DISPLAY, HOTKEYS_WINDOW_DISPLAY,
PREFS_WINDOW_DISPLAY, FLOW_GRAPH_SCREEN_CAPTURE,
- ): get_action_from_name(action).set_sensitive(True)
+ ): get_action_from_name(action).set_sensitive(True)
if not self.init_file_paths and
Preferences.restore_files(): self.init_file_paths = Preferences.files_open()
if not self.init_file_paths: self.init_file_paths = ['']
- for file_path in self.init_file_paths:
+ for file_path in self.init_file_paths:
if file_path:
self.main_window.new_page(file_path) #load pages from file paths
if Preferences.file_open() in self.init_file_paths:
self.main_window.new_page(Preferences.file_open(), show=True)
if not self.get_page(): self.main_window.new_page()
#ensure that at least a blank page exists
@@ -183,55 +188,66 @@
# Selections
##############################################################################################
elif state == BLOCK_SELECT or state == PORT_SELECT:
- for action in (ELEMENT_REMOVE, BLOCK_PARAM_MODIFY,
BLOCK_ROTATE_RIGHT, BLOCK_ROTATE_LEFT):
+ for action in (ELEMENT_REMOVE, BLOCK_PARAM_MODIFY,
BLOCK_ROTATE_RIGHT, BLOCK_ROTATE_LEFT):
get_action_from_name(action).set_sensitive(True)
elif state == CONNECTION_SELECT:
get_action_from_name(ELEMENT_REMOVE).set_sensitive(True)
- for action in (BLOCK_PARAM_MODIFY, BLOCK_ROTATE_RIGHT,
BLOCK_ROTATE_LEFT):
+ for action in (BLOCK_PARAM_MODIFY, BLOCK_ROTATE_RIGHT,
BLOCK_ROTATE_LEFT):
get_action_from_name(action).set_sensitive(False)
elif state == NOTHING_SELECT:
- for action in (ELEMENT_REMOVE, BLOCK_PARAM_MODIFY,
BLOCK_ROTATE_RIGHT, BLOCK_ROTATE_LEFT):
+ for action in (ELEMENT_REMOVE, BLOCK_PARAM_MODIFY,
BLOCK_ROTATE_RIGHT, BLOCK_ROTATE_LEFT):
get_action_from_name(action).set_sensitive(False)
self.get_flow_graph().unselect()
##############################################################################################
+ # Enable/Disable
+
##############################################################################################
+ elif state == BLOCK_ENABLE:
+ self.get_flow_graph().enable_selected(True)
+
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
+ self.get_page().set_saved(False)
+ elif state == BLOCK_DISABLE:
+ self.get_flow_graph().enable_selected(False)
+
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
+ self.get_page().set_saved(False)
+
##############################################################################################
# Move/Rotate/Delete/Create
-
##############################################################################################
- elif state == BLOCK_MOVE:
+
##############################################################################################
+ elif state == BLOCK_MOVE:
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
self.get_page().set_saved(False)
elif state == BLOCK_ROTATE_LEFT:
- if self.get_flow_graph().rotate_selected(DIR_LEFT):
-
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
- self.get_page().set_saved(False)
+ if self.get_flow_graph().rotate_selected(DIR_LEFT):
+
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
+ self.get_page().set_saved(False)
elif state == BLOCK_ROTATE_RIGHT:
- if self.get_flow_graph().rotate_selected(DIR_RIGHT):
-
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
- self.get_page().set_saved(False)
+ if self.get_flow_graph().rotate_selected(DIR_RIGHT):
+
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
+ self.get_page().set_saved(False)
elif state == ELEMENT_REMOVE:
- if self.get_flow_graph().remove_selected():
-
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
+ if self.get_flow_graph().remove_selected():
+
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
self.handle_states(NOTHING_SELECT)
self.get_page().set_saved(False)
- elif state == CONNECTION_CREATE or state == BLOCK_CREATE:
+ elif state == CONNECTION_CREATE or state == BLOCK_CREATE:
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
- self.handle_states(NOTHING_SELECT)
+ self.handle_states(NOTHING_SELECT)
self.get_page().set_saved(False)
elif state == BLOCK_INC_TYPE:
if
self.get_flow_graph().type_controller_modify_selected(1):
-
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
+
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
self.get_page().set_saved(False)
elif state == BLOCK_DEC_TYPE:
if
self.get_flow_graph().type_controller_modify_selected(-1):
-
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
- self.get_page().set_saved(False)
+
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
+ self.get_page().set_saved(False)
elif state == PORT_CONTROLLER_INC:
if
self.get_flow_graph().port_controller_modify_selected(1):
-
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
+
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
self.get_page().set_saved(False)
elif state == PORT_CONTROLLER_DEC:
if
self.get_flow_graph().port_controller_modify_selected(-1):
-
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
- self.get_page().set_saved(False)
+
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
+ self.get_page().set_saved(False)
##############################################################################################
# Window stuff
##############################################################################################
@@ -247,21 +263,21 @@
##############################################################################################
elif state == BLOCK_PARAM_MODIFY:
if self.get_flow_graph().param_modify_selected():
-
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
+
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
self.get_page().set_saved(False)
##############################################################################################
# Undo/Redo
##############################################################################################
- elif state == FLOW_GRAPH_UNDO:
+ elif state == FLOW_GRAPH_UNDO:
n = self.get_page().get_state_cache().get_prev_state()
- if n:
+ if n:
self.handle_states(NOTHING_SELECT)
self.get_flow_graph().import_data(n)
self.get_flow_graph().update()
self.get_page().set_saved(False)
- elif state == FLOW_GRAPH_REDO:
+ elif state == FLOW_GRAPH_REDO:
n = self.get_page().get_state_cache().get_next_state()
- if n:
+ if n:
self.handle_states(NOTHING_SELECT)
self.get_flow_graph().import_data(n)
self.get_flow_graph().update()
@@ -277,50 +293,50 @@
for i,file_path in enumerate(file_paths):
self.main_window.new_page(file_path,
show=(i==0))
elif state == FLOW_GRAPH_CLOSE:
- self.main_window.close_page()
+ self.main_window.close_page()
elif state == FLOW_GRAPH_SAVE:
if not self.get_page().get_file_path():
self.handle_states(FLOW_GRAPH_SAVE_AS)
else:
try:
ParseXML.to_file(self.get_flow_graph().export_data(),
self.get_page().get_file_path())
- self.get_page().set_saved(True)
- except IOError:
+ self.get_page().set_saved(True)
+ except IOError:
Messages.send_fail_save(self.get_page().get_file_path())
self.get_page().set_saved(False)
elif state == FLOW_GRAPH_SAVE_AS:
file_path =
gui.SaveFlowGraphFileDialog(self.get_page().get_file_path()).run()
- if file_path != None:
+ if file_path != None:
self.get_page().set_file_path(file_path)
- self.handle_states(FLOW_GRAPH_SAVE)
+ self.handle_states(FLOW_GRAPH_SAVE)
elif state == FLOW_GRAPH_SCREEN_CAPTURE:
file_path =
gui.SaveImageFileDialog(self.get_page().get_file_path()).run()
- if file_path != None:
+ if file_path != None:
pixmap =
self.get_flow_graph().get_drawing_area().pixmap
width, height = pixmap.get_size()
pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB,
0, 8, width, height)
pixbuf.get_from_drawable(pixmap,
pixmap.get_colormap(), 0, 0, 0, 0, width, height)
- pixbuf.save(file_path,
IMAGE_FILE_EXTENSION[1:])
+ pixbuf.save(file_path, IMAGE_FILE_EXTENSION[1:])
##############################################################################################
# Gen/Exec/Stop
-
##############################################################################################
+
##############################################################################################
elif state == FLOW_GRAPH_GEN:
if not self.get_page().get_pid():
- if not self.get_page().get_saved() or not
self.get_page().get_file_path():
+ if not self.get_page().get_saved() or not
self.get_page().get_file_path():
self.handle_states(FLOW_GRAPH_SAVE)
#only save if file path missing or not saved
- if self.get_page().get_saved() and
self.get_page().get_file_path():
+ if self.get_page().get_saved() and
self.get_page().get_file_path():
generator =
self.get_page().get_generator()
- try:
+ try:
Messages.send_start_gen(generator.get_file_path())
generator.write()
except Exception,e:
Messages.send_fail_gen(e)
- else: self.generator = None
+ else: self.generator = None
elif state == FLOW_GRAPH_EXEC:
if not self.get_page().get_pid():
self.handle_states(FLOW_GRAPH_GEN)
if self.get_page().get_saved() and
self.get_page().get_file_path():
ExecFlowGraphThread(self)
elif state == FLOW_GRAPH_KILL:
- if self.get_page().get_pid():
+ if self.get_page().get_pid():
try: os.kill(self.get_page().get_pid(),
signal.SIGKILL)
except: print "could not kill pid:
%s"%self.get_page().get_pid()
elif state == '': #pass and run the global actions
@@ -329,11 +345,18 @@
##############################################################################################
# Global Actions for all States
##############################################################################################
+ #update enable/disable
+ get_action_from_name(BLOCK_ENABLE).set_sensitive(bool(
+ self.get_flow_graph().get_selected_block() and not
self.get_flow_graph().get_selected_block().get_enabled()
+ ))
+ get_action_from_name(BLOCK_DISABLE).set_sensitive(bool(
+ self.get_flow_graph().get_selected_block() and
self.get_flow_graph().get_selected_block().get_enabled()
+ ))
#set the exec and stop buttons
self.update_exec_stop()
- #saved status
+ #saved status
get_action_from_name(FLOW_GRAPH_SAVE).set_sensitive(not
self.get_page().get_saved())
- self.main_window.update()
+ self.main_window.update()
def update_exec_stop(self):
"""
@@ -343,8 +366,8 @@
sensitive = self.get_flow_graph().is_valid() and not
self.get_page().get_pid()
get_action_from_name(FLOW_GRAPH_GEN).set_sensitive(sensitive)
get_action_from_name(FLOW_GRAPH_EXEC).set_sensitive(sensitive)
-
get_action_from_name(FLOW_GRAPH_KILL).set_sensitive(self.get_page().get_pid()
!= None)
-
+
get_action_from_name(FLOW_GRAPH_KILL).set_sensitive(self.get_page().get_pid()
!= None)
+
class ExecFlowGraphThread(Thread):
"""Execute the flow graph as a new process and wait on it to finish."""
def __init__ (self, action_handler):
@@ -359,7 +382,7 @@
self.page = action_handler.get_page()
Messages.send_start_exec(self.page.get_generator().get_file_path())
#get the popen
- try:
+ try:
self.p = self.page.get_generator().get_popen()
self.page.set_pid(self.p.pid)
#update
@@ -367,20 +390,20 @@
self.start()
except Exception, e:
Messages.send_verbose_exec(str(e))
- Messages.send_end_exec()
-
- def run(self):
- """Wait on the flow graph."""
+ Messages.send_end_exec()
+
+ def run(self):
+ """Wait on the flow graph."""
#handle completion
r = "\n"
- while(r):
+ while(r):
gtk.gdk.threads_enter()
Messages.send_verbose_exec(r)
gtk.gdk.threads_leave()
r = os.read(self.p.stdout.fileno(), 1024)
- gtk.gdk.threads_enter()
- Messages.send_end_exec()
+ gtk.gdk.threads_enter()
+ Messages.send_end_exec()
self.page.set_pid(None)
self.update_exec_stop()
gtk.gdk.threads_leave()
-
+
Modified: grc/trunk/src/grc/Actions.py
===================================================================
--- grc/trunk/src/grc/Actions.py 2008-07-06 02:38:05 UTC (rev 8807)
+++ grc/trunk/src/grc/Actions.py 2008-07-06 05:28:12 UTC (rev 8808)
@@ -17,8 +17,8 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
"""
address@hidden Actions
-#Global actions for gui elements to communicate state changes to the action
handler.
-#Use gtk.stock_list_ids() to get a list of possible stock ids (for
toolbar/menu icons)
+#Global actions for gui elements to communicate state changes to the action
handler.
+#Use gtk.stock_list_ids() to get a list of possible stock ids (for
toolbar/menu icons)
address@hidden Josh Blum
import pygtk
@@ -46,6 +46,8 @@
BLOCK_PARAM_MODIFY = 'block param modify'
BLOCK_INC_TYPE = 'block increment type'
BLOCK_DEC_TYPE = 'block decrement type'
+BLOCK_ENABLE = 'block enable'
+BLOCK_DISABLE = 'block disable'
PORT_CONTROLLER_INC = 'port controller increment'
PORT_CONTROLLER_DEC = 'port controller decrement'
@@ -87,6 +89,8 @@
gtk.Action(BLOCK_ROTATE_LEFT, 'Rotate _Left', 'Rotate the block 90
degrees', 'gtk-go-back'),
gtk.Action(BLOCK_ROTATE_RIGHT, 'Rotate _Right', 'Rotate the block -90
degrees', 'gtk-go-forward'),
gtk.Action(BLOCK_PARAM_MODIFY, '_Properties', 'Modify params for the
selected block', 'gtk-properties'),
+ gtk.Action(BLOCK_ENABLE, 'E_nable', 'Enable the block', 'gtk-connect'),
+ gtk.Action(BLOCK_DISABLE, 'D_isable', 'Disable the block',
'gtk-disconnect'),
gtk.Action(PREFS_WINDOW_DISPLAY, '_Preferences', 'Configure
Preferences', 'gtk-preferences'),
gtk.Action(ABOUT_WINDOW_DISPLAY, '_About', 'About this program',
'gtk-about'),
gtk.Action(HOTKEYS_WINDOW_DISPLAY, '_HotKeys', 'Hot Keys', 'gtk-info'),
@@ -97,15 +101,15 @@
)
ACTIONS_DICT = dict((action.get_name(), action) for action in ACTIONS_LIST)
-
-def get_action_from_name(action_name):
+
+def get_action_from_name(action_name):
"""!
Retrieve the action from the action list.
Search the list and find an action with said name.
@param action_name the action name(string)
@throw KeyError bad action name
@return a gtk action object
- """
+ """
if ACTIONS_DICT.has_key(action_name): return ACTIONS_DICT[action_name]
raise KeyError('Action Name: "%s" does not exist'%action_name)
Modified: grc/trunk/src/grc/elements/Block.py
===================================================================
--- grc/trunk/src/grc/elements/Block.py 2008-07-06 02:38:05 UTC (rev 8807)
+++ grc/trunk/src/grc/elements/Block.py 2008-07-06 05:28:12 UTC (rev 8808)
@@ -36,23 +36,23 @@
The use of this class as a dictionary (enum only) will reveal the enum
opts.
The eval method can return the param evaluated to a raw python data
type.
"""
-
+
def __init__(self, param):
UserDict.__init__(self)
self._param = param
if param.is_enum():
for key in param.get_opt_keys():
self[key] = str(param.get_opt(key))
-
+
def __str__(self):
return str(self._param.to_code())
-
+
def eval(self):
return self._param.evaluate()
-
+
class Block(Element):
-
+
def __init__(self, flow_graph, n):
"""
Make a new block from nested data.
@@ -68,7 +68,7 @@
sources = Utils.listify(n, 'source')
sinks = Utils.listify(n, 'sink')
#build the block
- Element.__init__(self, flow_graph)
+ Element.__init__(self, flow_graph)
#store the data
self._name = name
self._key = key
@@ -76,13 +76,22 @@
self._params = odict()
#add the id param
self._params['id'] = self.get_parent().get_parent().Param(
- self,
+ self,
{
- 'name': 'ID',
- 'key': 'id',
+ 'name': 'ID',
+ 'key': 'id',
'type': 'id',
}
)
+ self._params['_enabled'] = self.get_parent().get_parent().Param(
+ self,
+ {
+ 'name': 'Enabled',
+ 'key': '_enabled',
+ 'type': 'raw',
+ 'value': 'True',
+ }
+ )
for param in map(lambda n:
self.get_parent().get_parent().Param(self, n), params):
key = param.get_key()
#test against repeated keys
@@ -91,7 +100,7 @@
#store the param
self._params[key] = param
#store the checks
- self._checks = checks
+ self._checks = checks
#create the source objects
self._sources = odict()
for source in map(lambda n:
self.get_parent().get_parent().Source(self, n), sources):
@@ -118,64 +127,80 @@
Call test on all children.
"""
map(lambda c: c.test(), self.get_params() + self.get_sinks() +
self.get_sources())
-
+
+ def get_enabled(self):
+ """!
+ Get the enabled state of the block.
+ @return true for enabled
+ """
+ try: return eval(self.get_param('_enabled').get_value())
+ except: return True
+
+ def set_enabled(self, enabled):
+ """!
+ Set the enabled state of the block.
+ @param enabled true for enabled
+ """
+ self.get_param('_enabled').set_value(str(enabled))
+
def validate(self):
"""
Validate the block.
All ports and params must be valid.
All checks must evaluate to true.
"""
+ if not self.get_enabled(): return
for c in self.get_params() + self.get_sinks() +
self.get_sources():
try: assert(c.is_valid())
- except AssertionError:
+ except AssertionError:
for msg in c.get_error_messages():
self._add_error_message('%s: %s'%(c,
msg))
for check in self._checks:
check_res = self.resolve_dependencies(check)
- try:
+ try:
check_eval =
self.get_parent().evaluate(check_res)
try: assert(check_eval)
except AssertionError:
self._add_error_message('Check "%s" failed.'%check)
except: self._add_error_message('Check "%s" did not
evaluate.'%check)
-
+
def __str__(self): return 'Block - %s - %s(%s)'%(self.get_id(),
self.get_name(), self.get_key())
-
- def get_id(self): return self.get_param('id').get_value()
-
+
+ def get_id(self): return self.get_param('id').get_value()
+
def is_block(self): return True
-
+
def get_doc(self): return self._doc
-
+
def get_name(self): return self._name
-
+
def get_key(self): return self._key
-
+
def get_doc(self): return ''
-
+
##############################################
# Access Params
##############################################
- def get_param_keys(self): return self._params.keys()
+ def get_param_keys(self): return self._params.keys()
def get_param(self, key): return self._params[key]
def get_params(self): return self._params.values()
-
+
##############################################
# Access Sinks
##############################################
- def get_sink_keys(self): return self._sinks.keys()
+ def get_sink_keys(self): return self._sinks.keys()
def get_sink(self, key): return self._sinks[key]
def get_sinks(self): return self._sinks.values()
-
+
##############################################
# Access Sources
##############################################
- def get_source_keys(self): return self._sources.keys()
+ def get_source_keys(self): return self._sources.keys()
def get_source(self, key): return self._sources[key]
def get_sources(self): return self._sources.values()
-
+
def get_connections(self):
return sum([port.get_connections() for port in
self.get_sources() + self.get_sinks()], [])
-
+
def resolve_dependencies(self, tmpl):
"""
Resolve a paramater dependency with cheetah templates.
@@ -187,10 +212,10 @@
n = dict((p.get_key(), TemplateArg(p)) for p in
self.get_params())
try: return str(Template(tmpl, n))
except Exception, e: return "-------->\n%s: %s\n<--------"%(e,
tmpl)
-
+
##############################################
## Import/Export Methods
- ##############################################
+ ##############################################
def export_data(self):
"""
Export this block's params to nested data.
@@ -199,8 +224,8 @@
n = odict()
n['key'] = self.get_key()
n['param'] = map(lambda p: p.export_data(), self.get_params())
- return n
-
+ return n
+
def import_data(self, n):
"""
Import this block's params from nested data.
Modified: grc/trunk/src/grc/elements/Connection.py
===================================================================
--- grc/trunk/src/grc/elements/Connection.py 2008-07-06 02:38:05 UTC (rev
8807)
+++ grc/trunk/src/grc/elements/Connection.py 2008-07-06 05:28:12 UTC (rev
8808)
@@ -27,10 +27,10 @@
from grc.Utils import odict
class Connection(Element):
-
+
def __init__(self, flow_graph, porta, portb):
"""!
- Make a new connection given the parent and 2 ports.
+ Make a new connection given the parent and 2 ports.
@param flow_graph the parent of this element
@param porta a port (any direction)
@param portb a port (any direction)
@@ -48,12 +48,12 @@
assert(not source.is_full())
assert(not sink.is_full())
self._source = source
- self._sink = sink
-
+ self._sink = sink
+
def __str__(self): return 'Connection (%s -> %s)'%(self.get_source(),
self.get_sink())
-
+
def is_connection(self): return True
-
+
def validate(self):
"""
Validate the connections.
@@ -61,18 +61,22 @@
"""
source_type = self.get_source().get_type()
sink_type = self.get_sink().get_type()
- try: assert(source_type == sink_type)
+ try: assert source_type == sink_type
except AssertionError: self._add_error_message('Source type
"%s" does not match sink type "%s".'%(source_type, sink_type))
-
+ try: assert self.get_source().get_parent().get_enabled()
+ except AssertionError: self._add_error_message('Source is
disabled.')
+ try: assert self.get_sink().get_parent().get_enabled()
+ except AssertionError: self._add_error_message('Sink is
disabled.')
+
#############################
# Access Ports
#############################
def get_sink(self): return self._sink
def get_source(self): return self._source
-
+
##############################################
## Import/Export Methods
- ##############################################
+ ##############################################
def export_data(self):
"""
Export this connection's info.
@@ -83,4 +87,4 @@
n['sink_block_id'] =
self.get_sink().get_parent().get_param('id').get_value()
n['source_key'] = self.get_source().get_key()
n['sink_key'] = self.get_sink().get_key()
- return n
+ return n
Modified: grc/trunk/src/grc/elements/Param.py
===================================================================
--- grc/trunk/src/grc/elements/Param.py 2008-07-06 02:38:05 UTC (rev 8807)
+++ grc/trunk/src/grc/elements/Param.py 2008-07-06 05:28:12 UTC (rev 8808)
@@ -26,7 +26,7 @@
from grc.elements.Element import Element
class Option(Element):
-
+
def __init__(self, param, name, key, opts):
Element.__init__(self, param)
self._name = name
@@ -41,20 +41,20 @@
except AssertionError: self._exit_with_error('Key "%s"
already exists in option'%key)
#store the option
self._opts[key] = value
-
+
def __str__(self): return 'Option %s(%s)'%(self.get_name(),
self.get_key())
-
+
def get_name(self): return self._name
-
+
def get_key(self): return self._key
-
+
##############################################
# Access Opts
##############################################
- def get_opt_keys(self): return self._opts.keys()
+ def get_opt_keys(self): return self._opts.keys()
def get_opt(self, key): return self._opts[key]
def get_opts(self): return self._opts.values()
-
+
##############################################
## Static Make Methods
##############################################
@@ -79,10 +79,10 @@
make_option_from_n = staticmethod(make_option_from_n)
class Param(Element):
-
+
##possible param types
TYPES = ['enum', 'raw']
-
+
def __init__(self, block, n):
"""
Make a new param from nested data.
@@ -104,14 +104,14 @@
self._type = type
#create the Option objects from the n data
self._options = odict()
- for option in map(lambda o: Option.make_option_from_n(self, o),
options):
+ for option in map(lambda o: Option.make_option_from_n(self, o),
options):
key = option.get_key()
#test against repeated keys
try: assert(key not in self.get_option_keys())
except AssertionError: self._exit_with_error('Key "%s"
already exists in options'%key)
#store the option
self._options[key] = option
- #test the enum options
+ #test the enum options
if self._options or self.is_enum():
#test against bad combos of type and enum
try: assert(self._options)
@@ -130,84 +130,84 @@
self._value = value or self.get_option_keys()[0]
try: assert(self.get_value() in self.get_option_keys())
except AssertionError: self._exit_with_error('The value
"%s" is not in the possible values of "%s".'%(self.get_value(),
self.get_option_keys()))
- else: self._value = value or ''
-
+ else: self._value = value or ''
+
def test(self):
"""
call test on all children
"""
map(lambda c: c.test(), self.get_options())
-
+
def validate(self):
"""
Validate the param.
The value must be evaluated and type must a possible type.
"""
- try:
+ try:
assert(self.get_type() in self.TYPES)
try: self.evaluate()
except:
#if the evaluate failed but added no error
messages, add the generic one below
if not self.get_error_messages():
- self._add_error_message('Value "%s"
cannot be evaluated.'%self.get_value())
- except AssertionError: self._add_error_message('Type "%s" is
not a possible type.'%self.get_type())
-
+ self._add_error_message('Value "%s"
cannot be evaluated.'%self.get_value())
+ except AssertionError: self._add_error_message('Type "%s" is
not a possible type.'%self.get_type())
+
def evaluate(self):
"""!
Evaluate the value of this param.
@throw NotImplementedError
"""
- raise NotImplementedError
-
+ raise NotImplementedError
+
def to_code(self):
"""!
Convert the value to code.
@throw NotImplementedError
"""
raise NotImplementedError
-
+
def __str__(self): return 'Param - %s(%s)'%(self.get_name(),
self.get_key())
-
+
def is_param(self): return True
-
+
def get_name(self): return self._name
-
+
def get_key(self): return self._key
- def get_value(self):
+ def get_value(self):
value = self._value
if self.is_enum() and value not in self.get_option_keys():
value = self.get_option_keys()[0]
self.set_value(value)
return value
-
- def set_value(self, value):
+
+ def set_value(self, value):
self.flag()
self._value = str(value) #must be a string
-
+
def get_type(self): return
self.get_parent().resolve_dependencies(self._type)
-
+
def is_enum(self): return self._type == 'enum'
-
+
def is_type_dependent(self): return '$' in self._type
-
+
##############################################
# Access Options
##############################################
def get_option_keys(self): return self._options.keys()
def get_option(self, key): return self._options[key]
def get_options(self): return self._options.values()
-
+
##############################################
# Access Opts
##############################################
def get_opt_keys(self): return
self._options[self.get_value()].get_opt_keys()
def get_opt(self, key): return
self._options[self.get_value()].get_opt(key)
def get_opts(self): return self._options[self.get_value()].get_opts()
-
+
##############################################
## Import/Export Methods
- ##############################################
+ ##############################################
def export_data(self):
"""
Export this param's key/value.
@@ -216,4 +216,4 @@
n = odict()
n['key'] = self.get_key()
n['value'] = self.get_value()
- return n
+ return n
Modified: grc/trunk/src/grc/gui/Bars.py
===================================================================
--- grc/trunk/src/grc/gui/Bars.py 2008-07-06 02:38:05 UTC (rev 8807)
+++ grc/trunk/src/grc/gui/Bars.py 2008-07-06 05:28:12 UTC (rev 8808)
@@ -24,7 +24,7 @@
import pygtk
pygtk.require('2.0')
import gtk
-
+
##The list of actions for the toolbar.
TOOLBAR_LIST = (
FLOW_GRAPH_NEW,
@@ -42,10 +42,13 @@
None,
ELEMENT_REMOVE,
BLOCK_ROTATE_LEFT,
- BLOCK_ROTATE_RIGHT,
+ BLOCK_ROTATE_RIGHT,
+ None,
+ BLOCK_ENABLE,
+ BLOCK_DISABLE,
)
-##The list of actions and categories for the menu bar.
+##The list of actions and categories for the menu bar.
MENU_BAR_LIST = (
(gtk.Action('File', '_File', None, None), [
FLOW_GRAPH_NEW,
@@ -67,6 +70,9 @@
BLOCK_ROTATE_LEFT,
BLOCK_ROTATE_RIGHT,
BLOCK_PARAM_MODIFY,
+ None,
+ BLOCK_ENABLE,
+ BLOCK_DISABLE,
]),
(gtk.Action('Build', '_Build', None, None), [
FLOW_GRAPH_GEN,
@@ -74,55 +80,55 @@
FLOW_GRAPH_KILL,
]),
(gtk.Action('Options', '_Options', None, None), [
- PREFS_WINDOW_DISPLAY,
+ PREFS_WINDOW_DISPLAY,
]),
(gtk.Action('Help', '_Help', None, None), [
ABOUT_WINDOW_DISPLAY,
- HOTKEYS_WINDOW_DISPLAY,
- ]),
+ HOTKEYS_WINDOW_DISPLAY,
+ ]),
)
class Toolbar(gtk.Toolbar):
- """The gtk toolbar with actions added from the toolbar list."""
-
+ """The gtk toolbar with actions added from the toolbar list."""
+
def __init__(self):
"""
- Parse the list of action names in the toolbar list.
+ Parse the list of action names in the toolbar list.
Look up the action for each name in the action list and
add it to the toolbar.
- """
- gtk.Toolbar.__init__(self)
- self.set_style(gtk.TOOLBAR_ICONS)
+ """
+ gtk.Toolbar.__init__(self)
+ self.set_style(gtk.TOOLBAR_ICONS)
for action_name in TOOLBAR_LIST:
if action_name: #add a tool item
action = get_action_from_name(action_name)
- self.add(action.create_tool_item())
+ self.add(action.create_tool_item())
#this reset of the tooltip property is required
(after creating the tool item) for the tooltip to show
- action.set_property('tooltip',
action.get_property('tooltip'))
+ action.set_property('tooltip',
action.get_property('tooltip'))
else: self.add(gtk.SeparatorToolItem())
-
+
class MenuBar(gtk.MenuBar):
- """The gtk menu bar with actions added from the menu bar list."""
-
+ """The gtk menu bar with actions added from the menu bar list."""
+
def __init__(self):
"""
- Parse the list of submenus from the menubar list.
+ Parse the list of submenus from the menubar list.
For each submenu, get a list of action names.
- Look up the action for each name in the action list and add it
to the submenu.
+ Look up the action for each name in the action list and add it
to the submenu.
Add the submenu to the menu bar.
"""
gtk.MenuBar.__init__(self)
for main_action,action_names in MENU_BAR_LIST:
#create the main menu item
main_menu_item = main_action.create_menu_item()
- self.append(main_menu_item)
+ self.append(main_menu_item)
#create the menu
main_menu = gtk.Menu()
- main_menu_item.set_submenu(main_menu)
+ main_menu_item.set_submenu(main_menu)
for action_name in action_names:
- if action_name: #append a menu item
+ if action_name: #append a menu item
action =
get_action_from_name(action_name)
main_menu.append(action.create_menu_item())
else: main_menu.append(gtk.SeparatorMenuItem())
main_menu.show_all() #this show all is required for the
separators to show
-
-
+
+
Modified: grc/trunk/src/grc/gui/Dialogs.py
===================================================================
--- grc/trunk/src/grc/gui/Dialogs.py 2008-07-06 02:38:05 UTC (rev 8807)
+++ grc/trunk/src/grc/gui/Dialogs.py 2008-07-06 05:28:12 UTC (rev 8808)
@@ -27,15 +27,15 @@
class TextDisplay(gtk.TextView):
"""A non editable gtk text view."""
-
+
def __init__(self, text=''):
"""!
TextDisplay constructor.
@param text the text to display (string)
"""
text_buffer = gtk.TextBuffer()
- text_buffer.set_text(text)
- self.set_text = text_buffer.set_text
+ text_buffer.set_text(text)
+ self.set_text = text_buffer.set_text
self.insert = lambda line:
text_buffer.insert(text_buffer.get_end_iter(), line)
gtk.TextView.__init__(self, text_buffer)
self.set_editable(False)
@@ -45,21 +45,21 @@
######################################################################################################
class PreferencesDialog(gtk.Dialog):
"""A dialog box to display the preferences."""
-
+
def __init__(self):
"""PreferencesDialog constructor."""
from grc import Preferences
gtk.Dialog.__init__(self, buttons=('gtk-close',
gtk.RESPONSE_CLOSE))
- self.set_title("Preferences")
+ self.set_title("Preferences")
self.set_size_request(MIN_DIALOG_WIDTH, MIN_DIALOG_HEIGHT)
notebook = gtk.Notebook()
- for title,desc,params in Preferences.PREFERENCES:
+ for title,desc,params in Preferences.PREFERENCES:
vbox = gtk.VBox()
vbox.pack_start(gtk.Label(''), False) #blank label for
spacing
- for param in params:
vbox.pack_start(param.get_input_object(), False)
+ for param in params:
vbox.pack_start(param.get_input_object(), False)
desc = desc.strip('\n')
if desc: vbox.pack_start(TextDisplay(desc), False,
padding=5)
- notebook.append_page(vbox, gtk.Label(title))
+ notebook.append_page(vbox, gtk.Label(title))
self.vbox.pack_start(notebook, True)
self.show_all()
self.run()
@@ -81,16 +81,16 @@
response = message_dialog.run()
message_dialog.destroy()
return response
-
+
######################################################################################################
class AboutDialog(gtk.AboutDialog):
"""A cute little about dialog."""
-
+
def __init__(self):
"""AboutDialog constructor."""
gtk.AboutDialog.__init__(self)
self.set_version(VERSION)
- self.set_name(MAIN_WINDOW_PREFIX)
+ self.set_name(MAIN_WINDOW_PREFIX)
self.set_license(__doc__)
self.set_copyright('Copyright 2007 Free Software Foundation,
Inc.')
self.set_website('http://gnuradio.org/trac/wiki/GNURadioCompanion')
@@ -106,11 +106,11 @@
--""")
self.run()
self.destroy()
-
-######################################################################################################
+
+######################################################################################################
class HotKeysDialog(gtk.Dialog):
"""Display each action with the associated hotkey."""
-
+
def __init__(self):
"""HotKeysDialog constructor."""
gtk.Dialog.__init__(self, buttons=('gtk-close',
gtk.RESPONSE_CLOSE))
@@ -127,6 +127,8 @@
('Modify Parameters', 'Enter'),
('Rotate Block', 'Right'),
('Rotate Block', 'Left'),
+ ('Enable Block', 'e'),
+ ('Disable Block', 'd'),
('Modify Data Type', 'Up'),
('Modify Data Type', 'Down'),
('Add a Port', '+'),
@@ -137,8 +139,8 @@
('Screen Shot', 'PrintScreen'),
): markup = '%s\n<b>%s:</b>%s'%(markup, action,
hotkey.rjust(25-len(action), ' '))
label = gtk.Label()
- label.set_markup('<tt>%s</tt>\n'%markup) #append newline
+ label.set_markup('<tt>%s</tt>\n'%markup) #append newline
self.vbox.pack_start(label, False)
self.show_all()
self.run()
- self.destroy()
+ self.destroy()
Modified: grc/trunk/src/grc/gui/SignalBlockParamsDialog.py
===================================================================
--- grc/trunk/src/grc/gui/SignalBlockParamsDialog.py 2008-07-06 02:38:05 UTC
(rev 8807)
+++ grc/trunk/src/grc/gui/SignalBlockParamsDialog.py 2008-07-06 05:28:12 UTC
(rev 8808)
@@ -37,12 +37,12 @@
label = gtk.Label()
label.set_markup('\n<b><span underline="low">%s</span>:</b>\n'%title)
hbox = gtk.HBox()
- hbox.pack_start(label, False, False, padding=11)
+ hbox.pack_start(label, False, False, padding=11)
return hbox
class SignalBlockParamsDialog(gtk.Dialog):
"""A dialog box to set signal block parameters."""
-
+
def __init__(self, block):
"""!
SignalBlockParamsDialog contructor.
@@ -53,7 +53,7 @@
self.set_title('Properties: %s'%block.get_name())
self.set_size_request(MIN_DIALOG_WIDTH, MIN_DIALOG_HEIGHT)
vbox = gtk.VBox()
- #Add the title label
+ #Add the title label
vbox.pack_start(get_title_label('Parameters'), False)
#Create the scrolled window to hold all the parameters
scrolled_window = gtk.ScrolledWindow()
@@ -65,12 +65,12 @@
self._error_messages_text_display = TextDisplay('')
err_box.pack_start(gtk.Label(''), False, False, 7) #spacing
err_box.pack_start(get_title_label('Error Messages'), False)
- err_box.pack_start(self._error_messages_text_display, False)
+ err_box.pack_start(self._error_messages_text_display, False)
#Add all the parameters
- for param in filter(lambda p: p.get_key() not in
('gui_coordinate', 'gui_rotation'), self.block.get_params()):
-
vbox.pack_start(param.get_input_object(self._handle_changed), False)
+ for param in filter(lambda p: not
(p.get_key().startswith('gui_') or p.get_key().startswith('_')),
self.block.get_params()):
+
vbox.pack_start(param.get_input_object(self._handle_changed), False)
vbox.pack_start(err_box, False)
- #Done adding parameters
+ #Done adding parameters
if self.block.get_doc():
vbox.pack_start(gtk.Label(''), False, False, 7) #spacing
vbox.pack_start(get_title_label('Documentation'), False)
@@ -79,33 +79,33 @@
self.connect('key_press_event', self._handle_key_press)
self.show_all()
self._update_error_messages()
-
+
def _update_error_messages(self):
"""
Update the error messages in the error messages box.
Hide the box if there are no errors.
- """
+ """
if self.block.is_valid(): self._error_messages_box.hide()
else: self._error_messages_box.show()
messages = '\n'.join(self.block.get_error_messages())
self._error_messages_text_display.set_text(messages)
-
+
def _handle_key_press(self, widget, event):
"""!
Handle key presses from the keyboard.
- Call the ok response when enter is pressed.
+ Call the ok response when enter is pressed.
@return false to forward the keypress
"""
keyname = gtk.gdk.keyval_name(event.keyval)
- if keyname == 'Return': self.response(gtk.RESPONSE_OK)
+ if keyname == 'Return': self.response(gtk.RESPONSE_OK)
return False #forward the keypress
-
+
def _handle_changed(self, param):
"""!
A change occured, update any dependent parameters:
- The enum inside the variable type may have changed and,
+ The enum inside the variable type may have changed and,
the variable param will need an external update.
- @param param the graphical parameter that initiated the
callback
+ @param param the graphical parameter that initiated the callback
"""
self._update_error_messages()
#update dependent params
@@ -113,7 +113,7 @@
for other_param in param.get_parent().get_params():
if param.get_key() in other_param._type:
other_param.update()
return True
-
+
def run(self):
"""!
Call run().
@@ -122,10 +122,10 @@
original_data = list()
for param in self.block.get_params():
original_data.append(param.get_value())
- gtk.Dialog.run(self)
+ gtk.Dialog.run(self)
self.destroy()
new_data = list()
for param in self.block.get_params():
new_data.append(param.get_value())
return original_data != new_data
-
+
Modified: grc/trunk/src/grc/gui/elements/Block.py
===================================================================
--- grc/trunk/src/grc/gui/elements/Block.py 2008-07-06 02:38:05 UTC (rev
8807)
+++ grc/trunk/src/grc/gui/elements/Block.py 2008-07-06 05:28:12 UTC (rev
8808)
@@ -31,36 +31,38 @@
class Block(Element):
"""The graphical signal block."""
-
+
def __init__(self, *args, **kwargs):
"""!
Block contructor.
Add graphics related params to the block.
- """
+ """
#add the position param
self._params['gui_coordinate'] =
self.get_parent().get_parent().Param(
- self,
+ self,
{
- 'name': 'GUI Coordinate',
- 'key': 'gui_coordinate',
+ 'name': 'GUI Coordinate',
+ 'key': 'gui_coordinate',
'type': 'raw',
+ 'value': '(0, 0)',
}
)
self._params['gui_rotation'] =
self.get_parent().get_parent().Param(
- self,
+ self,
{
- 'name': 'GUI Rotation',
- 'key': 'gui_rotation',
+ 'name': 'GUI Rotation',
+ 'key': 'gui_rotation',
'type': 'raw',
+ 'value': '0',
}
)
Element.__init__(self)
-
+
def get_coordinate(self):
"""!
Get the coordinate from the position param.
@return the coordinate tuple (x, y) or (0, 0) if failure
- """
+ """
try: #should evaluate to tuple
coor =
eval(self.get_param('gui_coordinate').get_value())
x, y = map(int, coor)
@@ -68,53 +70,54 @@
if x <= 0:
x = 0
elif x >= fgW - BORDER_PROXIMITY_SENSITIVITY:
- x = fgW - BORDER_PROXIMITY_SENSITIVITY
+ x = fgW - BORDER_PROXIMITY_SENSITIVITY
if y <= 0:
y = 0
- elif y >= fgH - BORDER_PROXIMITY_SENSITIVITY:
- y = fgH - BORDER_PROXIMITY_SENSITIVITY
+ elif y >= fgH - BORDER_PROXIMITY_SENSITIVITY:
+ y = fgH - BORDER_PROXIMITY_SENSITIVITY
return (x, y)
- except:
+ except:
self.set_coordinate((0, 0))
return (0, 0)
-
+
def set_coordinate(self, coor):
"""!
Set the coordinate into the position param.
@param coor the coordinate tuple (x, y)
"""
self.get_param('gui_coordinate').set_value(str(coor))
-
+
def get_rotation(self):
"""!
Get the rotation from the position param.
@return the rotation in degrees or 0 if failure
- """
+ """
try: #should evaluate to dict
rotation =
eval(self.get_param('gui_rotation').get_value())
return int(rotation)
- except:
+ except:
self.set_rotation(POSSIBLE_ROTATIONS[0])
return POSSIBLE_ROTATIONS[0]
-
+
def set_rotation(self, rot):
"""!
Set the rotation into the position param.
@param rot the rotation in degrees
"""
self.get_param('gui_rotation').set_value(str(rot))
-
+
def update(self):
"""Update the block, parameters, and ports when a change
occurs."""
- self.clear()
- self._create_labels()
+ self.bg_color = self.get_enabled() and Colors.BG_COLOR or
Colors.DISABLED_BG_COLOR
+ self.clear()
+ self._create_labels()
self.W = self.label_width + 2*LABEL_PADDING_WIDTH
max_ports = max(len(self.get_sinks()), len(self.get_sources()),
1)
- self.H = max(self.label_height+2*LABEL_PADDING_HEIGHT,
2*PORT_BORDER_SEPARATION + max_ports*PORT_HEIGHT +
(max_ports-1)*PORT_SEPARATION)
+ self.H = max(self.label_height+2*LABEL_PADDING_HEIGHT,
2*PORT_BORDER_SEPARATION + max_ports*PORT_HEIGHT +
(max_ports-1)*PORT_SEPARATION)
if self.is_horizontal(): self.add_area((0,0),(self.W,self.H))
- elif self.is_vertical(): self.add_area((0,0),(self.H,self.W))
+ elif self.is_vertical(): self.add_area((0,0),(self.H,self.W))
map(lambda p: p.update(), self.get_sinks() + self.get_sources())
-
+
def _create_labels(self):
"""Create the labels for the signal block."""
layouts = list()
@@ -124,14 +127,13 @@
if self.is_valid():
layout.set_markup('<b>'+Utils.xml_encode(self.get_name())+'</b>')
else: layout.set_markup('<span
foreground="red"><b>'+Utils.xml_encode(self.get_name())+'</b></span>')
desc = pango.FontDescription(BLOCK_FONT)
- layout.set_font_description(desc)
- self.label_width,self.label_height = layout.get_pixel_size()
+ layout.set_font_description(desc)
+ self.label_width,self.label_height = layout.get_pixel_size()
#display the params (except for the special params id and
position)
from grc import Preferences
if Preferences.show_params():
- hidden_prefs = ['gui_coordinate', 'gui_rotation']
if not Preferences.show_id(): hidden_prefs.append('id')
- for param in filter(lambda p: p.get_key() not in
hidden_prefs, self.get_params()):
+ for param in filter(lambda p: not
(p.get_key().startswith('gui_') or p.get_key().startswith('_')),
self.get_params()):
layout = param.get_layout()
layouts.append(layout)
w,h = layout.get_pixel_size()
@@ -142,10 +144,10 @@
#setup the pixmap
pixmap = gtk.gdk.Pixmap(self.get_parent().get_window(), width,
height, -1)
gc = pixmap.new_gc()
- gc.foreground = Colors.BG_COLOR
+ gc.foreground = self.bg_color
pixmap.draw_rectangle(gc, True, 0, 0, width, height)
gc.foreground = Colors.TXT_COLOR
- #draw the layouts
+ #draw the layouts
h_off = 0
for i,layout in enumerate(layouts):
w,h = layout.get_pixel_size()
@@ -153,36 +155,36 @@
else: w_off = 0
pixmap.draw_layout(gc, w_off, h_off, layout)
h_off = h + h_off + LABEL_SEPARATION
- #create vertical and horizontal images
+ #create vertical and horizontal images
self.horizontal_label = image = pixmap.get_image(0, 0, width,
height)
if self.is_vertical():
self.vertical_label = vimage =
gtk.gdk.Image(gtk.gdk.IMAGE_NORMAL, pixmap.get_visual(), height, width)
for i in range(width):
for j in range(height): vimage.put_pixel(j,
width-i-1, image.get_pixel(i, j))
-
+
def draw(self, window):
"""!
Draw the signal block with label and inputs/outputs.
@param window the gtk window to draw on
"""
- Element.draw(self, window)
- gc = self.get_gc()
+ Element.draw(self, window, BG_color=self.bg_color)
+ gc = self.get_gc()
gc.foreground = Colors.TXT_COLOR
- X,Y = self.get_coordinate()
+ X,Y = self.get_coordinate()
if self.is_horizontal():
window.draw_image(gc, self.horizontal_label, 0, 0,
X+LABEL_PADDING_WIDTH, Y+(self.H-self.label_height)/2, -1, -1)
elif self.is_vertical():
window.draw_image(gc, self.vertical_label, 0, 0,
X+(self.H-self.label_height)/2, Y+LABEL_PADDING_WIDTH, -1, -1)
map(lambda p: p.draw(window), self.get_sources() +
self.get_sinks())
-
- def what_is_selected(self, coor):
+
+ def what_is_selected(self, coor):
"""!
Get the element that is selected.
@param coor the (x,y) tuple
@return this signal block, a port, or None
"""
- for port in self.get_sources() + self.get_sinks():
+ for port in self.get_sources() + self.get_sinks():
if port.what_is_selected(coor):
- return port.what_is_selected(coor)
+ return port.what_is_selected(coor)
return Element.what_is_selected(self, coor)
Modified: grc/trunk/src/grc/gui/elements/Colors.py
===================================================================
--- grc/trunk/src/grc/gui/elements/Colors.py 2008-07-06 02:38:05 UTC (rev
8807)
+++ grc/trunk/src/grc/gui/elements/Colors.py 2008-07-06 05:28:12 UTC (rev
8808)
@@ -24,12 +24,13 @@
pygtk.require('2.0')
import gtk
-COLORMAP = gtk.gdk.colormap_get_system() #create all of the colors
+COLORMAP = gtk.gdk.colormap_get_system() #create all of the colors
def get_color(color_code): return COLORMAP.alloc_color(color_code, True, True)
-BACKGROUND_COLOR = get_color('#FFF9FF') #main window background
-FG_COLOR = get_color('black') #normal border color
-BG_COLOR = get_color('#F1ECFF') #default background
-H_COLOR = get_color('#00FFFF') #Highlight border color
-TXT_COLOR = get_color('black') #text color
-ERROR_COLOR = get_color('red') #error color
+BACKGROUND_COLOR = get_color('#FFF9FF') #main window background
+FG_COLOR = get_color('black') #normal border color
+BG_COLOR = get_color('#F1ECFF') #default background
+DISABLED_BG_COLOR = get_color('#CCCCCC') #disabled background
+H_COLOR = get_color('#00FFFF') #Highlight border color
+TXT_COLOR = get_color('black') #text color
+ERROR_COLOR = get_color('red') #error color
Modified: grc/trunk/src/grc/gui/elements/Connection.py
===================================================================
--- grc/trunk/src/grc/gui/elements/Connection.py 2008-07-06 02:38:05 UTC
(rev 8807)
+++ grc/trunk/src/grc/gui/elements/Connection.py 2008-07-06 05:28:12 UTC
(rev 8808)
@@ -26,8 +26,8 @@
from grc.Constants import CONNECTOR_ARROW_BASE,CONNECTOR_ARROW_HEIGHT
class Connection(Element):
- """A graphical connection for ports."""
-
+ """A graphical connection for ports."""
+
def get_coordinate(self):
"""!
Get the 0,0 coordinate.
@@ -35,25 +35,25 @@
@return 0, 0
"""
return (0, 0)
-
+
def get_rotation(self):
"""!
Get the 0 degree rotation.
Rotations are irrelevant in connection.
@return 0
"""
- return 0
-
+ return 0
+
def update(self):
- """Precalculate relative coordinates."""
+ """Precalculate relative coordinates."""
self._sink_rot = None
self._source_rot = None
self._sink_coor = None
self._source_coor = None
-
+
sink = self.get_sink()
source = self.get_source()
-
+
#get the source coordinate
x1, y1 = 0, 0
connector_length = source.get_connector_length()
@@ -66,8 +66,8 @@
elif source.get_rotation() == 270:
y1 = 0 + connector_length
self.x1, self.y1 = x1, y1
-
- #get the sink coordinate
+
+ #get the sink coordinate
x2, y2 = 0, 0
connector_length = sink.get_connector_length() +
CONNECTOR_ARROW_HEIGHT
if sink.get_rotation() == 0:
@@ -77,9 +77,9 @@
elif sink.get_rotation() == 180:
x2 = 0 + connector_length
elif sink.get_rotation() == 270:
- y2 = 0 - connector_length
+ y2 = 0 - connector_length
self.x2, self.y2 = x2, y2
-
+
#build the arrow
if sink.get_rotation() == 0:
self.arrow = [(0, 0), (0-CONNECTOR_ARROW_HEIGHT,
0-CONNECTOR_ARROW_BASE/2), (0-CONNECTOR_ARROW_HEIGHT, 0+CONNECTOR_ARROW_BASE/2)]
@@ -89,29 +89,29 @@
self.arrow = [(0, 0), (0+CONNECTOR_ARROW_HEIGHT,
0-CONNECTOR_ARROW_BASE/2), (0+CONNECTOR_ARROW_HEIGHT, 0+CONNECTOR_ARROW_BASE/2)]
elif sink.get_rotation() == 270:
self.arrow = [(0, 0), (0-CONNECTOR_ARROW_BASE/2,
0-CONNECTOR_ARROW_HEIGHT), (0+CONNECTOR_ARROW_BASE/2, 0-CONNECTOR_ARROW_HEIGHT)]
-
- self._update_after_move()
+ self._update_after_move()
+
def _update_after_move(self):
- """Calculate coordinates."""
+ """Calculate coordinates."""
- self.clear()
-
+ self.clear()
+
#source connector
source = self.get_source()
X, Y = source.get_connector_coordinate()
x1, y1 = self.x1 + X, self.y1 + Y
self.add_line((x1, y1), (X, Y))
-
+
#sink connector
sink = self.get_sink()
X, Y = sink.get_connector_coordinate()
x2, y2 = self.x2 + X, self.y2 + Y
- self.add_line((x2, y2), (X, Y))
-
- #adjust arrow
+ self.add_line((x2, y2), (X, Y))
+
+ #adjust arrow
self._arrow = [(x+X, y+Y) for x,y in self.arrow]
-
+
#add the horizontal and vertical lines in this connection
if abs(source.get_connector_direction() -
sink.get_connector_direction()) == 180:
W = abs(x1 - x2)
@@ -122,12 +122,12 @@
if source.get_connector_direction() == 0: sW = sW * -1
sH = y1 - y2
if source.get_connector_direction() == 270: sH = sH * -1
- if ((W>H or sW<0) and
self.is_horizontal(source.get_connector_direction())) or\
+ if ((W>H or sW<0) and
self.is_horizontal(source.get_connector_direction())) or \
(W>=H and sH>=0 and
self.is_vertical(source.get_connector_direction())):
self.add_line((x1,y1),(x1,midY))
self.add_line((x1,midY),(x2,midY))
self.add_line((x2,y2),(x2,midY))
- elif (H>=W and sW>=0 and
self.is_horizontal(source.get_connector_direction())) or\
+ elif (H>=W and sW>=0 and
self.is_horizontal(source.get_connector_direction())) or \
((H>W or sH<0) and
self.is_vertical(source.get_connector_direction())):
self.add_line((x1,y1),(midX,y1))
self.add_line((midX,y1),(midX,y2))
@@ -135,17 +135,17 @@
else:
p1 = (x1, y2)
p2 = (x2, y1)
- if Utils.get_angle_from_coordinates((x1,y1),p1) ==
(source.get_connector_direction()+180)%360 or\
+ if Utils.get_angle_from_coordinates((x1,y1),p1) ==
(source.get_connector_direction()+180)%360 or \
Utils.get_angle_from_coordinates((x2,y2),p1) ==
(sink.get_connector_direction()+180)%360: p = p2
else: p = p1
self.add_line((x1,y1),p)
self.add_line((x2,y2),p)
-
+
def draw(self, window):
"""!
Draw the connection.
@param window the gtk window to draw on
- """
+ """
sink = self.get_sink()
source = self.get_source()
#check for changes
@@ -157,8 +157,8 @@
self._sink_coor = sink.get_coordinate()
self._source_coor = source.get_coordinate()
#draw
- Element.draw(self, window)
+ Element.draw(self, window)
gc = self.get_gc()
- if not self.is_valid(): gc.foreground = Colors.ERROR_COLOR
- #draw arrow on sink port
+ if not self.is_valid(): gc.foreground = Colors.ERROR_COLOR
+ #draw arrow on sink port
window.draw_polygon(gc, True, self._arrow)
Modified: grc/trunk/src/grc/gui/elements/Element.py
===================================================================
--- grc/trunk/src/grc/gui/elements/Element.py 2008-07-06 02:38:05 UTC (rev
8807)
+++ grc/trunk/src/grc/gui/elements/Element.py 2008-07-06 05:28:12 UTC (rev
8808)
@@ -30,42 +30,42 @@
class Element(object):
"""
- GraphicalElement is the base class for all graphical elements.
- It contains an X,Y coordinate, a list of rectangular areas that the
element occupies,
+ GraphicalElement is the base class for all graphical elements.
+ It contains an X,Y coordinate, a list of rectangular areas that the
element occupies,
and methods to detect selection of those areas.
- """
-
+ """
+
def __init__(self, *args, **kwargs):
"""!
Make a new list of rectangular areas and lines, and set the
coordinate and the rotation.
- """
+ """
self.set_rotation(POSSIBLE_ROTATIONS[0])
- self.set_coordinate((0, 0))
+ self.set_coordinate((0, 0))
self.clear()
self.set_highlighted(False)
-
+
def is_horizontal(self, rotation=None):
"""!
Is this element horizontal?
If rotation is None, use this element's rotation.
- @param rotation the optional rotation
+ @param rotation the optional rotation
@return true if rotation is horizontal
"""
rotation = rotation or self.get_rotation()
return rotation in (0, 180)
-
+
def is_vertical(self, rotation=None):
"""!
Is this element vertical?
If rotation is None, use this element's rotation.
- @param rotation the optional rotation
+ @param rotation the optional rotation
@return true if rotation is vertical
"""
rotation = rotation or self.get_rotation()
return rotation in (90, 270)
-
- def get_gc(self): return self._gc
+ def get_gc(self): return self._gc
+
def draw(self, window, BG_color=Colors.BG_COLOR,
FG_color=Colors.FG_COLOR):
"""!
Draw in the given window.
@@ -73,12 +73,12 @@
@param BG_color the background color
@param FG_color the foreground color
"""
- gc = self.get_parent().get_gc()
+ gc = self.get_parent().get_gc()
self._gc = gc
X,Y = self.get_coordinate()
for (rX,rY),(W,H) in self.areas_dict[self.get_rotation()]:
aX = X + rX
- aY = Y + rY
+ aY = Y + rY
gc.foreground = BG_color
window.draw_rectangle(gc, True, aX, aY, W, H)
gc.foreground = self.is_highlighted() and
Colors.H_COLOR or FG_color
@@ -86,69 +86,69 @@
for (x1, y1),(x2, y2) in self.lines_dict[self.get_rotation()]:
gc.foreground = self.is_highlighted() and
Colors.H_COLOR or FG_color
window.draw_line(gc, X+x1, Y+y1, X+x2, Y+y2)
-
+
def rotate(self, direction):
"""!
Rotate all of the areas by 90 degrees.
@param direction DIR_RIGHT or DIR_LEFT
"""
if direction == DIR_LEFT: delta_rotation = 90
- elif direction == DIR_RIGHT: delta_rotation = 270
+ elif direction == DIR_RIGHT: delta_rotation = 270
self.set_rotation((self.get_rotation() + delta_rotation)%360)
- self.update()
-
+ self.update()
+
def clear(self):
"""Empty the lines and areas."""
self.areas_dict = dict((rotation, list()) for rotation in
POSSIBLE_ROTATIONS)
self.lines_dict = dict((rotation, list()) for rotation in
POSSIBLE_ROTATIONS)
-
+
def set_coordinate(self, coor):
"""!
Set the reference coordinate.
@param coor the coordinate tuple (x,y)
"""
self.coor = coor
-
+
def get_parent(self):
"""!
Get the parent of this element.
@return the parent
- """
+ """
return self.parent
-
+
def set_highlighted(self, highlighted):
"""!
Set the highlight status.
@param highlighted true to enable highlighting
"""
- self.highlighted = highlighted
-
+ self.highlighted = highlighted
+
def is_highlighted(self):
"""!
Get the highlight status.
@return true if highlighted
"""
return self.highlighted
-
+
def get_coordinate(self):
"""!Get the coordinate.
@return the coordinate tuple (x,y)
"""
return self.coor
-
+
def move(self, delta_coor):
"""!
Move the element by adding the delta_coor to the current
coordinate.
@param delta_coor (delta_x,delta_y) tuple
"""
deltaX, deltaY = delta_coor
- X, Y = self.get_coordinate()
- self.set_coordinate((X+deltaX, Y+deltaY))
-
+ X, Y = self.get_coordinate()
+ self.set_coordinate((X+deltaX, Y+deltaY))
+
def add_area(self, rel_coor, area, rotation=None):
"""!
- Add an area to the area list.
- An area is actually a coordinate relative to the main
coordinate with a width/height pair relative to the area coordinate.
+ Add an area to the area list.
+ An area is actually a coordinate relative to the main
coordinate with a width/height pair relative to the area coordinate.
A positive width is to the right of the coordinate. A positive
height is above the coordinate.
The area is associated with a rotation. If rotation is not
specified, the element's current rotation is used.
@param rel_coor (x,y) offset from this element's coordinate
@@ -157,10 +157,10 @@
"""
if rotation == None: rotation = self.get_rotation()
self.areas_dict[rotation].append((rel_coor, area))
-
+
def add_line(self, rel_coor1, rel_coor2, rotation=None):
"""!
- Add a line to the line list.
+ Add a line to the line list.
A line is defined by 2 relative coordinates. Lines must be
horizontal or vertical.
The line is associated with a rotation. If rotation is not
specified, the element's current rotation is used.
@param rel_coor1 relative (x1,y1) tuple
@@ -168,12 +168,12 @@
@param rotation rotation in degrees
"""
if rotation == None: rotation = self.get_rotation()
- self.lines_dict[rotation].append((rel_coor1, rel_coor2))
-
+ self.lines_dict[rotation].append((rel_coor1, rel_coor2))
+
def what_is_selected(self, coor):
"""!
Is this Element selected at given coordinate/is the coordinate
encompassed by one of the areas or lines?
- @return self if one of the areas/lines encompasses coor, else
None.
+ @return self if one of the areas/lines encompasses coor, else
None.
"""
in_between = lambda p, a, b: p >= min(a, b) and p <= max(a, b)
x,y = [a-b for a,b in zip(coor, self.get_coordinate())]
@@ -183,25 +183,25 @@
if x1 == x2: x1, x2 = x1-CONNECTION_SELECT_SENSITIVITY,
x2+CONNECTION_SELECT_SENSITIVITY
if y1 == y2: y1, y2 = y1-CONNECTION_SELECT_SENSITIVITY,
y2+CONNECTION_SELECT_SENSITIVITY
if in_between(x, x1, x2) and in_between(y, y1, y2):
return self
- return None
-
+ return None
+
def get_rotation(self):
"""!
Get the rotation in degrees.
@return the rotation
"""
- return self.rotation
-
+ return self.rotation
+
def set_rotation(self, rotation):
"""!
Set the rotation in degrees.
@param rotation the rotation"""
if rotation not in POSSIBLE_ROTATIONS:
raise Exception('"%s" is not one of the possible
rotations: (%s)'%(rotation,POSSIBLE_ROTATIONS))
- self.rotation = rotation
-
- def update(self):
+ self.rotation = rotation
+
+ def update(self):
"""Do nothing for the update. Dummy method."""
pass
-
+
Modified: grc/trunk/src/grc/gui/elements/FlowGraph.py
===================================================================
--- grc/trunk/src/grc/gui/elements/FlowGraph.py 2008-07-06 02:38:05 UTC (rev
8807)
+++ grc/trunk/src/grc/gui/elements/FlowGraph.py 2008-07-06 05:28:12 UTC (rev
8808)
@@ -37,16 +37,16 @@
class FlowGraph(Element):
"""
- FlowGraph is the data structure to store graphical signal blocks,
- graphical inputs and outputs,
+ FlowGraph is the data structure to store graphical signal blocks,
+ graphical inputs and outputs,
and the connections between inputs and outputs.
- """
-
+ """
+
def __init__(self, *args, **kwargs):
"""!
FlowGraph contructor.
Create a list for signal blocks and connections. Connect mouse
handlers.
- """
+ """
Element.__init__(self)
#important vars dealing with mouse event tracking
self.has_moved = False
@@ -54,26 +54,26 @@
self.selected_element = None
self.is_selected = lambda: bool(self.selected_element)
self.time = 0
-
- def get_drawing_area(self): return self.drawing_area
-
+
+ def get_drawing_area(self): return self.drawing_area
+
def get_gc(self): return self.get_drawing_area().gc
-
+
def get_pixmap(self): return self.get_drawing_area().pixmap
-
+
def get_size(self): return self.get_drawing_area().get_size_request()
-
+
def set_size(self, *args):
self.get_drawing_area().set_size_request(*args)
-
+
def get_window(self): return self.get_drawing_area().window
-
+
def get_scroll_pane(self): return self.drawing_area.get_parent()
-
+
###########################################################################
# Flow Graph Access Methods
-###########################################################################
-
- def add_new_block(self, key):
+###########################################################################
+
+ def add_new_block(self, key):
"""!
Add a block of the given key to this flow graph.
@param key the block key
@@ -81,76 +81,70 @@
index = -1
while True:
id = (index < 0) and key or '%s%d'%(key, index)
- index = index + 1
+ index = index + 1
#make sure that the id is not used by another block
- if not filter(lambda e: e.is_block() and e.get_id() ==
id, self.get_elements()):
+ if not filter(lambda e: e.is_block() and e.get_id() ==
id, self.get_elements()):
vAdj =
self.get_scroll_pane().get_vadjustment().get_value()
hAdj =
self.get_scroll_pane().get_hadjustment().get_value()
- x = random.randint(100,200)+int(hAdj)
- y = random.randint(100,200)+int(vAdj)
+ x = random.randint(100,200)+int(hAdj)
+ y = random.randint(100,200)+int(vAdj)
#get the new block
block = self.get_new_block(key)
block.set_coordinate((x, y))
- block.set_rotation(0)
- block.get_param('id').set_value(id)
- #handle new state
- self.handle_states(BLOCK_CREATE)
+ block.set_rotation(0)
+ block.get_param('id').set_value(id)
+ #handle new state
+ self.handle_states(BLOCK_CREATE)
self.update()
- return
-
+ return
+
def type_controller_modify_selected(self, direction):
"""
!Change the registered type controller for the selected signal
block.
@param direction +1 or -1
@return true for success
"""
- if not self.selected_element: return False
- if self.selected_element.is_source() or
self.selected_element.is_sink():
- self.selected_element =
self.selected_element.get_parent()
- if self.selected_element.is_block():
- for child in self.selected_element.get_params() + \
- self.selected_element.get_sources() + \
- self.selected_element.get_sinks():
+ if self.get_selected_block():
+ for child in self.get_selected_block().get_params() + \
+ self.get_selected_block().get_sources() + \
+ self.get_selected_block().get_sinks():
#find a param that controls a type
type_param = None
- for param in self.selected_element.get_params():
+ for param in
self.get_selected_block().get_params():
if not type_param and param.is_enum():
type_param = param
if param.is_enum() and param.get_key()
in child._type: type_param = param
- if type_param:
+ if type_param:
#try to increment the enum by direction
- try:
+ try:
keys =
type_param.get_option_keys()
- old_index =
keys.index(type_param.get_value())
+ old_index =
keys.index(type_param.get_value())
new_index = (old_index +
direction + len(keys))%len(keys)
type_param.set_value(keys[new_index])
- self.update()
+ self.update()
return True
except: return False
- return False
-
+ return False
+
def port_controller_modify_selected(self, direction):
"""!
Change port controller for the selected signal block.
@param direction +1 or -1
@return true for success
"""
- if not self.selected_element: return False
- if self.selected_element.is_source() or
self.selected_element.is_sink():
- self.selected_element =
self.selected_element.get_parent()
- if self.selected_element.is_block():
+ if self.get_selected_block():
for get_ports_attr in ('get_sources', 'get_sinks'):
ports = getattr(self.selected_element,
get_ports_attr)()
if ports and hasattr(ports[0], 'get_nports')
and ports[0].get_nports():
#find the param that controls port0
- for param in
self.selected_element.get_params():
+ for param in
self.get_selected_block().get_params():
if param.get_key() in
ports[0]._nports:
#try to increment the
port controller by direction
- try:
+ try:
value =
param.evaluate()
value = value +
direction
assert(0 <
value <= MAX_NUM_PORTS)
-
param.set_value(value)
- self.update()
+
param.set_value(value)
+ self.update()
return True
except: return False
return False
@@ -160,102 +154,119 @@
Create and show a param modification dialog for the selected
element (port and signal block only).
@return true if parameters were changed
"""
- if not self.selected_element: return False
- if self.selected_element.is_source() or
self.selected_element.is_sink():
- self.selected_element =
self.selected_element.get_parent()
- if self.selected_element.is_block():
- signal_block_params_dialog =
SignalBlockParamsDialog(self.selected_element)
- changed = signal_block_params_dialog.run()
- self.update()
+ if self.get_selected_block():
+ signal_block_params_dialog =
SignalBlockParamsDialog(self.get_selected_block())
+ changed = signal_block_params_dialog.run()
+ self.update()
return changed #changes were made?
- return False
-
+ return False
+
+ def enable_selected(self, enable):
+ """!
+ Enable/disable the selected block.
+ @param enable true to enable
+ """
+ if self.get_selected_block():
+ self.get_selected_block().set_enabled(enable)
+ self.update()
+
def move_selected(self, delta_coordinate):
"""!
Move the element and by the change in coordinates.
@param delta_coordinate the change in coordinates
"""
- if self.selected_element:
- self.selected_element.move(delta_coordinate)
- self.has_moved = True
+ if self.selected_element:
+ self.selected_element.move(delta_coordinate)
+ self.has_moved = True
self.draw()
-
+
def rotate_selected(self, direction):
"""!
Rotate the selected element by 90 degrees. Only rotate
SignalBlocks and Sockets.
@param direction DIR_LEFT or DIR_RIGHT
- @return true if rotated, otherwise false.
+ @return true if rotated, otherwise false.
"""
if self.selected_element and (self.selected_element.is_block()
or \
- self.selected_element.is_source() or
self.selected_element.is_sink()):
- self.selected_element.rotate(direction)
+ self.selected_element.is_source() or
self.selected_element.is_sink()):
+ self.selected_element.rotate(direction)
self.draw()
return True
- return False
-
+ return False
+
def remove_selected(self):
"""!
If an element is selected, remove it and its attached parts
from the element list.
@return true if the element was deleted, otherwise false.
"""
if self.selected_element:
- self.remove_element(self.selected_element)
- self.selected_element = None
- self.update()
+ self.remove_element(self.selected_element)
+ self.unselect()
return True
return False
-
+
def unselect(self):
"""If an element is selected, un-highlight it and set selected
to None."""
- if self.selected_element:
- self.selected_element.set_highlighted(False)
- self.selected_element = None
- self.update()
-
- def what_is_selected(self, coor):
+ if self.selected_element:
+ self.selected_element.set_highlighted(False)
+ self.selected_element = None
+ self.update()
+
+ def what_is_selected(self, coor):
"""!
What is selected?
- At the given coordinate, return the first element found to be
selected
- - iterate though the elements backwards since top elements are
at the end of the list
- - if an element is selected, place it at the end of the list so
that is is drawn last,
+ At the given coordinate, return the first element found to be
selected
+ - iterate though the elements backwards since top elements are
at the end of the list
+ - if an element is selected, place it at the end of the list so
that is is drawn last,
and hence on top.
@param coor the coordinate of the mouse click
@return the selected element or None
- """
- #check the elements
+ """
+ #check the elements
for element in reversed(self.get_elements()):
if element.what_is_selected(coor):
self.get_elements().remove(element)
self.get_elements().append(element)
- return element.what_is_selected(coor)
+ return element.what_is_selected(coor)
return None
- def draw(self):
- """Draw the background and then all of the Elements in this
FlowGraph on the pixmap,
+ def get_selected_block(self):
+ """!
+ Get the selected block when a block or port is selected.
+ @return a block or None
+ """
+ #determine the selected block or None
+ if self.selected_element and self.selected_element.is_block():
+ return self.selected_element
+ elif self.selected_element and
(self.selected_element.is_source() or self.selected_element.is_sink()):
+ return self.selected_element.get_parent()
+ else: return None
+
+ def draw(self):
+ """Draw the background and then all of the Elements in this
FlowGraph on the pixmap,
then draw the pixmap to the drawable window of this
FlowGraph."""
- if self.get_gc():
+ if self.get_gc():
W,H = self.get_size()
- #draw the background
+ #draw the background
self.get_gc().foreground = BACKGROUND_COLOR
- self.get_pixmap().draw_rectangle(self.get_gc(), True,
0, 0, W, H)
+ self.get_pixmap().draw_rectangle(self.get_gc(), True,
0, 0, W, H)
#draw grid (depends on prefs)
from grc import Preferences
if Preferences.show_grid():
- grid_size = Preferences.get_grid_size()
+ grid_size = Preferences.get_grid_size()
points = list()
for i in range(W/grid_size):
- for j in range(H/grid_size):
- points.append((i*grid_size,
j*grid_size))
- self.get_gc().foreground = TXT_COLOR
+ for j in range(H/grid_size):
+ points.append((i*grid_size,
j*grid_size))
+ self.get_gc().foreground = TXT_COLOR
self.get_pixmap().draw_points(self.get_gc(),
points)
- #draw signal blocks first, then connections on the top
- for element in self.get_blocks() +
self.get_connections():
- element.draw(self.get_pixmap())
+ #draw signal blocks first, then connections on the top
+ for element in self.get_blocks() +
self.get_connections():
+ element.draw(self.get_pixmap())
#draw any selected element as the topmost
if self.mouse_pressed and self.selected_element:
self.selected_element.draw(self.get_pixmap())
self.get_drawing_area().draw()
-
+
def update(self):
"""Call update on all elements."""
map(lambda e: e.update(), self.get_elements())
@@ -266,16 +277,16 @@
if new_x != old_x or new_y != old_y: self.set_size(new_x, new_y)
#draw the flow graph
self.draw()
-
+
##########################################################################
## Handlers
-
##########################################################################
-
+
##########################################################################
+
def handle_mouse_button_press(self, left_click, double_click,
coordinate):
"""!
A mouse button is pressed. Record the state of the mouse, find
the selected element,
set the Element highlighted, handle the state change, and
redraw the FlowGraph.
- """
+ """
self.set_coordinate(coordinate)
if left_click:
if self.selected_element:
self.selected_element.set_highlighted(False)
@@ -284,30 +295,30 @@
old_selection = self.selected_element
self.selected_element =
self.what_is_selected(self.get_coordinate())
#handle the state change with the new selection
- if not self.selected_element:
+ if not self.selected_element:
self.handle_states(NOTHING_SELECT)
- elif self.selected_element.is_connection():
- self.handle_states(CONNECTION_SELECT)
- elif self.selected_element.is_source() or
self.selected_element.is_sink():
- self.handle_states(PORT_SELECT)
- elif self.selected_element.is_block():
- self.handle_states(BLOCK_SELECT)
+ elif self.selected_element.is_connection():
+ self.handle_states(CONNECTION_SELECT)
+ elif self.selected_element.is_source() or
self.selected_element.is_sink():
+ self.handle_states(PORT_SELECT)
+ elif self.selected_element.is_block():
+ self.handle_states(BLOCK_SELECT)
#this selection and the last were ports, try to connect
them
if old_selection and self.selected_element and
old_selection is not self.selected_element and\
(self.selected_element.is_source() or
self.selected_element.is_sink()) and\
(old_selection.is_source() or
old_selection.is_sink()):
- try:
+ try:
self.connect(old_selection,
self.selected_element)
self.update()
self.handle_states(CONNECTION_CREATE)
- except: Messages.send_fail_connection()
- if self.selected_element:
self.selected_element.set_highlighted(True)
+ except: Messages.send_fail_connection()
+ if self.selected_element:
self.selected_element.set_highlighted(True)
#double click detected, bring up params dialog if
possible
- if double_click and self.selected_element and
self.selected_element.is_block():
+ if double_click and self.get_selected_block():
self.mouse_pressed = False
- self.handle_states(BLOCK_PARAM_MODIFY)
+ self.handle_states(BLOCK_PARAM_MODIFY)
self.draw()
-
+
def handle_mouse_button_release(self, left_click, coordinate):
"""!
A mouse button is released, record the state.
@@ -329,41 +340,41 @@
self.move_selected((deltaX, deltaY))
self.handle_states(BLOCK_MOVE)
self.has_moved = False
-
- def handle_mouse_motion(self, coordinate):
+
+ def handle_mouse_motion(self, coordinate):
"""!
- The mouse has moved. If mouse_pressed is true, react to the
motions:
+ The mouse has moved. If mouse_pressed is true, react to the
motions:
If an Element is highlighted, this will move the Element by
redrawing it at the new position.
- """
+ """
#to perform a movement, the mouse must be pressed, an element
selected, timediff large enough.
- if time.time() - self.time >=
MOTION_DETECT_REDRAWING_SENSITIVITY and\
+ if time.time() - self.time >=
MOTION_DETECT_REDRAWING_SENSITIVITY and \
self.mouse_pressed and\
self.selected_element:
#The event coordinates must be within BPS pixels away
from the bounds of the flow graph.
fgW,fgH = self.get_size()
- x,y = coordinate
- #get the change in coordinates
+ x,y = coordinate
+ #get the change in coordinates
X,Y = self.get_coordinate()
deltaX = int(x - X)
- deltaY = int(y - Y)
+ deltaY = int(y - Y)
vAdj =
self.get_scroll_pane().get_vadjustment().get_value()
hAdj =
self.get_scroll_pane().get_hadjustment().get_value()
width =
self.get_scroll_pane().get_hadjustment().page_size
height =
self.get_scroll_pane().get_vadjustment().page_size
#scroll horizontal if we moved near the border
- if x-hAdj > width-SCROLL_PROXIMITY_SENSITIVITY and\
+ if x-hAdj > width-SCROLL_PROXIMITY_SENSITIVITY and \
hAdj+SCROLL_DISTANCE < fgW - width:
self.get_scroll_pane().get_hadjustment().set_value(hAdj+SCROLL_DISTANCE)
elif x-hAdj < SCROLL_PROXIMITY_SENSITIVITY:
self.get_scroll_pane().get_hadjustment().set_value(hAdj-SCROLL_DISTANCE)
#scroll vertical if we moved near the border
- if y-vAdj > height-SCROLL_PROXIMITY_SENSITIVITY and\
+ if y-vAdj > height-SCROLL_PROXIMITY_SENSITIVITY and \
vAdj+SCROLL_DISTANCE < fgH - height:
self.get_scroll_pane().get_vadjustment().set_value(vAdj+SCROLL_DISTANCE)
elif y-vAdj < SCROLL_PROXIMITY_SENSITIVITY:
self.get_scroll_pane().get_vadjustment().set_value(vAdj-SCROLL_DISTANCE)
- #move the selected element and record the new
coordinate
- self.move_selected((deltaX, deltaY))
+ #move the selected element and record the new coordinate
+ self.move_selected((deltaX, deltaY))
self.set_coordinate((x, y))
#update time
self.time = time.time()
Modified: grc/trunk/src/grc_gnuradio/Generator.py
===================================================================
--- grc/trunk/src/grc_gnuradio/Generator.py 2008-07-06 02:38:05 UTC (rev
8807)
+++ grc/trunk/src/grc_gnuradio/Generator.py 2008-07-06 05:28:12 UTC (rev
8808)
@@ -72,7 +72,7 @@
imports = self._flow_graph.get_imports()
variables = self._flow_graph.get_variables()
blocks = sorted(self._flow_graph.get_blocks(), lambda x, y:
cmp(x.get_id(), y.get_id()))
- blocks = filter(lambda b: b not in (imports + variables),
blocks)
+ blocks = filter(lambda b: b not in (imports + variables) and
b.get_enabled(), blocks)
namespace = {
'imports': imports,
'flow_graph': self._flow_graph,
Modified: grc/trunk/src/grc_gnuradio/Param.py
===================================================================
--- grc/trunk/src/grc_gnuradio/Param.py 2008-07-06 02:38:05 UTC (rev 8807)
+++ grc/trunk/src/grc_gnuradio/Param.py 2008-07-06 05:28:12 UTC (rev 8808)
@@ -24,10 +24,10 @@
import os
class Param(_Param):
-
+
##possible param types
TYPES = _Param.TYPES + [
- 'complex', 'real', 'int',
+ 'complex', 'real', 'int',
'complex_vector', 'real_vector', 'int_vector',
'hex', 'string',
'file_open', 'file_save',
@@ -35,21 +35,21 @@
'source_pad_key', 'sink_pad_key',
'grid_pos', 'import',
]
-
+
def evaluate(self):
"""!
Evaluate the value.
@return evaluated type
- """
+ """
self._lisitify_flag = False
self._stringify_flag = False
-
+
def eval_string(v):
- try:
+ try:
e = self.get_parent().get_parent().evaluate(v)
assert(isinstance(e, str))
return e
- except:
+ except:
self._stringify_flag = True
return v
t = self.get_type()
@@ -61,30 +61,30 @@
try: e = self.get_parent().get_parent().evaluate(v)
except:
self._add_error_message('Value "%s" cannot be
evaluated.'%v)
- raise Exception
+ raise Exception
#raise an exception if the data is invalid
- if t == 'raw':
+ if t == 'raw':
return e
elif t == 'complex':
try: assert(isinstance(e, (complex, float, int,
long)))
except AssertionError:
self._add_error_message('Expression
"%s" is invalid for type complex.'%str(e))
- raise Exception
+ raise Exception
return e
elif t == 'real':
try: assert(isinstance(e, (float, int, long)))
except AssertionError:
self._add_error_message('Expression
"%s" is invalid for type real.'%str(e))
- raise Exception
+ raise Exception
return e
elif t == 'int':
try: assert(isinstance(e, (int, long)))
except AssertionError:
self._add_error_message('Expression
"%s" is invalid for type integer.'%str(e))
- raise Exception
+ raise Exception
return e
elif t == 'complex_vector':
- if not isinstance(e, (tuple, list, set)):
+ if not isinstance(e, (tuple, list, set)):
self._lisitify_flag = True
e = [e]
try:
@@ -92,10 +92,10 @@
assert(isinstance(ei, (complex,
float, int, long)))
except AssertionError:
self._add_error_message('Expression
"%s" is invalid for type complex vector.'%str(e))
- raise Exception
+ raise Exception
return e
elif t == 'real_vector':
- if not isinstance(e, (tuple, list, set)):
+ if not isinstance(e, (tuple, list, set)):
self._lisitify_flag = True
e = [e]
try:
@@ -103,10 +103,10 @@
assert(isinstance(ei, (float,
int, long)))
except AssertionError:
self._add_error_message('Expression
"%s" is invalid for type real vector.'%str(e))
- raise Exception
+ raise Exception
return e
elif t == 'int_vector':
- if not isinstance(e, (tuple, list, set)):
+ if not isinstance(e, (tuple, list, set)):
self._lisitify_flag = True
e = [e]
try:
@@ -114,7 +114,7 @@
assert(isinstance(ei, (int,
long)))
except AssertionError:
self._add_error_message('Expression
"%s" is invalid for type integer vector.'%str(e))
- raise Exception
+ raise Exception
return e
elif t == 'hex':
return hex(e)
@@ -122,17 +122,17 @@
elif t == 'string':
e = eval_string(v)
return str(e)
- elif t == 'file_open':
+ elif t == 'file_open':
e = eval_string(v)
- e = str(e)
+ e = str(e)
assert(os.path.isfile(e))
return e
elif t == 'file_save':
e = eval_string(v)
- e = str(e)
+ e = str(e)
assert(os.path.exists(os.path.dirname(e)))
assert(not os.path.isdir(e))
- assert(os.path.basename(e))
+ assert(os.path.basename(e))
return e
elif t == 'id':
#can python use this as a variable?
@@ -140,22 +140,22 @@
assert(len(v) > 0)
assert(v[0].isalpha())
for c in v: assert(c.isalnum() or c in ('_',))
- except AssertionError:
+ except AssertionError:
self._add_error_message('ID "%s" must be
alpha-numeric or underscored, and begin with a letter.'%v)
- raise Exception
+ raise Exception
params = self.get_all_params('id')
keys = [param.get_value() for param in params]
try: assert(len(keys) == len(set(keys)))
except:
self._add_error_message('ID "%s" is not
unique.'%v)
- raise Exception
+ raise Exception
return v
elif t == 'source_pad_key':
#should be an integer
try: e = int(v)
except:
self._add_error_message('Source Pad Key "%s" is
not an integer.'%v)
- raise Exception
+ raise Exception
params = filter(lambda p: p.is_valid(),
self.get_all_params('source_pad_key'))
keys = [int(param.get_value()) for param in params]
try: assert(len(keys) == len(set(keys)))
@@ -168,7 +168,7 @@
try: e = int(v)
except:
self._add_error_message('Sink Pad Key "%s" is
not an integer.'%v)
- raise Exception
+ raise Exception
params = filter(lambda p: p.is_valid(),
self.get_all_params('sink_pad_key'))
keys = [int(param.get_value()) for param in params]
try: assert(len(keys) == len(set(keys)))
@@ -180,7 +180,7 @@
self._hostage_cells = list()
if not v: return '' #allow for empty grid pos
e = self.get_parent().get_parent().evaluate(v)
- try:
+ try:
assert(isinstance(e, (list, tuple)) and len(e)
== 4)
for ei in e: assert(isinstance(ei, int))
except AssertionError:
@@ -201,7 +201,7 @@
for r in range(row_span):
for c in range(col_span):
self._hostage_cells.append((row+r,
col+c))
- #avoid collisions
+ #avoid collisions
params = filter(lambda p: p is not self,
self.get_all_params('grid_pos'))
for param in params:
for cell in param._hostage_cells:
@@ -212,7 +212,7 @@
elif t == 'import':
n = dict() #new namespace
try: exec v in n
- except ImportError:
+ except ImportError:
self._add_error_message('Import "%s" failed.'%v)
raise Exception
except Exception:
@@ -220,12 +220,12 @@
raise Exception
return filter(lambda k: str(k) != '__builtins__',
n.keys())
else: raise TypeError, 'Type "%s" not handled'%t
-
+
def to_code(self):
"""!
Convert the value to code.
@return a string representing the code
- """
+ """
v = self.get_value()
t = self.get_type()
if t in ('string', 'file_open', 'file_save'): #string types
@@ -239,8 +239,8 @@
else:
return '(%s)'%v
else:
- return v
-
+ return v
+
def get_all_params(self, type):
"""!
Get all the params from the flowgraph that have the given type.
@@ -248,4 +248,4 @@
@return a list of params
"""
return sum([filter(lambda p: p.get_type() == type,
block.get_params()) for block in self.get_parent().get_parent().get_blocks()],
[])
-
+
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r8808 - in grc/trunk/src: grc grc/elements grc/gui grc/gui/elements grc_gnuradio,
jblum <=