[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] r7628 - in grc/branches/grc_reloaded/src/grc: . elemen
From: |
jblum |
Subject: |
[Commit-gnuradio] r7628 - in grc/branches/grc_reloaded/src/grc: . elements gui gui/elements |
Date: |
Sun, 10 Feb 2008 17:04:32 -0700 (MST) |
Author: jblum
Date: 2008-02-10 17:04:31 -0700 (Sun, 10 Feb 2008)
New Revision: 7628
Added:
grc/branches/grc_reloaded/src/grc/gui/elements/Utils.py
Modified:
grc/branches/grc_reloaded/src/grc/ActionHandler.py
grc/branches/grc_reloaded/src/grc/Actions.py
grc/branches/grc_reloaded/src/grc/Messages.py
grc/branches/grc_reloaded/src/grc/StateCache.py
grc/branches/grc_reloaded/src/grc/__init__.py
grc/branches/grc_reloaded/src/grc/elements/Block.py
grc/branches/grc_reloaded/src/grc/elements/Connection.py
grc/branches/grc_reloaded/src/grc/elements/Element.py
grc/branches/grc_reloaded/src/grc/elements/FlowGraph.py
grc/branches/grc_reloaded/src/grc/elements/Param.py
grc/branches/grc_reloaded/src/grc/elements/Platform.py
grc/branches/grc_reloaded/src/grc/gui/Bars.py
grc/branches/grc_reloaded/src/grc/gui/DrawingArea.py
grc/branches/grc_reloaded/src/grc/gui/MainWindow.py
grc/branches/grc_reloaded/src/grc/gui/elements/Block.py
grc/branches/grc_reloaded/src/grc/gui/elements/Element.py
grc/branches/grc_reloaded/src/grc/gui/elements/FlowGraph.py
grc/branches/grc_reloaded/src/grc/gui/elements/Platform.py
Log:
graphics are up, block and flowgraph only
Modified: grc/branches/grc_reloaded/src/grc/ActionHandler.py
===================================================================
--- grc/branches/grc_reloaded/src/grc/ActionHandler.py 2008-02-10 23:37:26 UTC
(rev 7627)
+++ grc/branches/grc_reloaded/src/grc/ActionHandler.py 2008-02-11 00:04:31 UTC
(rev 7628)
@@ -94,22 +94,22 @@
self.handle_states(FLOW_GRAPH_NEW)
#################### Delete ###############################
elif self.get_flow_graph().get_focus_flag() and keyname ==
'Delete': #mouse focus
- self.handle_states(ELEMENT_DELETE)
+ self.handle_states(ELEMENT_REMOVE)
#################### Rotate ###############################
elif self.get_flow_graph().get_focus_flag() and keyname ==
'Right': #mouse focus
- self.handle_states(SIGNAL_BLOCK_ROTATE_RIGHT)
+ self.handle_states(BLOCK_ROTATE_RIGHT)
elif self.get_flow_graph().get_focus_flag() and keyname ==
'Left': #mouse focus
- self.handle_states(SIGNAL_BLOCK_ROTATE_LEFT)
+ self.handle_states(BLOCK_ROTATE_LEFT)
#################### Data Type
###############################
elif self.get_flow_graph().get_focus_flag() and keyname ==
'Down': #mouse focus
- self.handle_states(SIGNAL_BLOCK_INC_TYPE)
+ self.handle_states(BLOCK_INC_TYPE)
elif self.get_flow_graph().get_focus_flag() and keyname ==
'Up': #mouse focus
- self.handle_states(SIGNAL_BLOCK_DEC_TYPE)
+ self.handle_states(BLOCK_DEC_TYPE)
#################### Socket Controllers
###############################
elif self.get_flow_graph().get_focus_flag() and keyname in
('equal','plus', 'KP_Add'): #mouse focus
- self.handle_states(SOCKET_CONTROLLER_INC)
+ self.handle_states(PORT_CONTROLLER_INC)
elif self.get_flow_graph().get_focus_flag() and keyname in
('minus', 'KP_Subtract'): #mouse focus
- self.handle_states(SOCKET_CONTROLLER_DEC)
+ self.handle_states(PORT_CONTROLLER_DEC)
#################### Exec/Stop/Print
###############################
elif keyname == 'F5':
self.handle_states(FLOW_GRAPH_EXEC)
@@ -172,55 +172,55 @@
##############################################################################################
# Selections
##############################################################################################
- elif state == SIGNAL_BLOCK_SELECT or state == SOCKET_SELECT:
- for action in (ELEMENT_DELETE,
SIGNAL_BLOCK_PARAM_MODIFY, SIGNAL_BLOCK_ROTATE_RIGHT,
SIGNAL_BLOCK_ROTATE_LEFT):
+ elif state == BLOCK_SELECT or state == PORT_SELECT:
+ 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_DELETE).set_sensitive(True)
- for action in (SIGNAL_BLOCK_PARAM_MODIFY,
SIGNAL_BLOCK_ROTATE_RIGHT, SIGNAL_BLOCK_ROTATE_LEFT):
+ get_action_from_name(ELEMENT_REMOVE).set_sensitive(True)
+ 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_DELETE,
SIGNAL_BLOCK_PARAM_MODIFY, SIGNAL_BLOCK_ROTATE_RIGHT,
SIGNAL_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()
##############################################################################################
# Move/Rotate/Delete/Create
##############################################################################################
- elif state == SIGNAL_BLOCK_MOVE:
-
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().to_nested_data())
+ 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 == SIGNAL_BLOCK_ROTATE_LEFT:
+ 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().to_nested_data())
+
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
self.get_page().set_saved(False)
- elif state == SIGNAL_BLOCK_ROTATE_RIGHT:
+ 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().to_nested_data())
+
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
self.get_page().set_saved(False)
- elif state == ELEMENT_DELETE:
- if self.get_flow_graph().delete_selected():
-
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().to_nested_data())
+ 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())
self.handle_states(NOTHING_SELECT)
self.get_page().set_saved(False)
- elif state == CONNECTION_CREATE or state ==
SIGNAL_BLOCK_CREATE:
-
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().to_nested_data())
+ 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.get_page().set_saved(False)
- elif state == SIGNAL_BLOCK_INC_TYPE:
+ 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().to_nested_data())
+
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
self.get_page().set_saved(False)
- elif state == SIGNAL_BLOCK_DEC_TYPE:
+ 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().to_nested_data())
+
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
self.get_page().set_saved(False)
- elif state == SOCKET_CONTROLLER_INC:
- if
self.get_flow_graph().socket_controller_modify_selected(1):
-
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().to_nested_data())
+ 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().set_saved(False)
- elif state == SOCKET_CONTROLLER_DEC:
- if
self.get_flow_graph().socket_controller_modify_selected(-1):
-
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().to_nested_data())
+ 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)
##############################################################################################
# Window stuff
@@ -242,36 +242,36 @@
dimensions =
gui.FlowGraphWindowSizeDialog(self.get_flow_graph().get_size_request()).run()
if dimensions:
self.get_flow_graph().set_size_request(*dimensions)
-
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().to_nested_data())
+
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
self.get_page().set_saved(False)
##############################################################################################
# Variable and Param Modifications
##############################################################################################
- elif state == SIGNAL_BLOCK_PARAM_MODIFY:
+ 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().to_nested_data())
+
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
self.get_page().set_saved(False)
elif state == VARIABLE_MODIFY:
-
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().to_nested_data())
+
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
self.get_page().set_saved(False)
self.get_flow_graph().update()
elif state == VARIABLE_REORDER:
-
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().to_nested_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:
- nested_data =
self.get_page().get_state_cache().get_prev_state()
- if nested_data != None:
+ n = self.get_page().get_state_cache().get_prev_state()
+ if n:
self.handle_states(NOTHING_SELECT)
-
self.get_flow_graph().from_nested_data(nested_data)
+ self.get_flow_graph().import_data(n)
self.get_page().set_saved(False)
elif state == FLOW_GRAPH_REDO:
- nested_data =
self.get_page().get_state_cache().get_next_state()
- if nested_data != None:
+ n = self.get_page().get_state_cache().get_next_state()
+ if n:
self.handle_states(NOTHING_SELECT)
-
self.get_flow_graph().from_nested_data(nested_data)
+ self.get_flow_graph().import_data(n)
self.get_page().set_saved(False)
##############################################################################################
# New/Open/Save/Close
@@ -287,7 +287,7 @@
if not self.get_page().get_file_path():
self.handle_states(FLOW_GRAPH_SAVE_AS)
else:
try:
-
ParseXML.to_file(ParseXML.to_xml(self.get_flow_graph().to_nested_data()),
self.get_page().get_file_path())
+
ParseXML.to_file(ParseXML.to_xml(self.get_flow_graph().export_data()),
self.get_page().get_file_path())
self.get_page().set_saved(True)
except IOError:
Messages.send_fail_save(self.get_page().get_file_path())
Modified: grc/branches/grc_reloaded/src/grc/Actions.py
===================================================================
--- grc/branches/grc_reloaded/src/grc/Actions.py 2008-02-10 23:37:26 UTC
(rev 7627)
+++ grc/branches/grc_reloaded/src/grc/Actions.py 2008-02-11 00:04:31 UTC
(rev 7628)
@@ -31,27 +31,27 @@
APPLICATION_INITIALIZE = 'app init'
APPLICATION_QUIT = 'app quit'
-SOCKET_SELECT = 'socket select'
+PORT_SELECT = 'port select'
NOTHING_SELECT = 'nothing select'
PARAM_MODIFY = 'param modify'
-SIGNAL_BLOCK_SELECT = 'signal block select'
-SIGNAL_BLOCK_MOVE = 'signal block move'
-SIGNAL_BLOCK_ROTATE_LEFT = 'signal block rotate left'
-SIGNAL_BLOCK_ROTATE_RIGHT = 'signal block rotate right'
-SIGNAL_BLOCK_CREATE = 'signal block create'
-SIGNAL_BLOCK_PARAM_MODIFY = 'signal block param modify'
-SIGNAL_BLOCK_INC_TYPE = 'signal block increment type'
-SIGNAL_BLOCK_DEC_TYPE = 'signal block decrement type'
+BLOCK_SELECT = 'signal block select'
+BLOCK_MOVE = 'signal block move'
+BLOCK_ROTATE_LEFT = 'signal block rotate left'
+BLOCK_ROTATE_RIGHT = 'signal block rotate right'
+BLOCK_CREATE = 'signal block create'
+BLOCK_PARAM_MODIFY = 'signal block param modify'
+BLOCK_INC_TYPE = 'signal block increment type'
+BLOCK_DEC_TYPE = 'signal block decrement type'
-SOCKET_CONTROLLER_INC = 'socket controller increment'
-SOCKET_CONTROLLER_DEC = 'socket controller decrement'
+PORT_CONTROLLER_INC = 'port controller increment'
+PORT_CONTROLLER_DEC = 'port controller decrement'
CONNECTION_SELECT = 'connection select'
CONNECTION_CREATE = 'conection create'
-ELEMENT_DELETE = 'element delete'
+ELEMENT_REMOVE = 'element remove'
VARIABLE_MODIFY = 'variable modify'
VARIABLE_REORDER = 'variable reorder'
@@ -88,10 +88,10 @@
gtk.Action(APPLICATION_QUIT, '_Quit', 'Quit program', 'gtk-quit'),
gtk.Action(FLOW_GRAPH_UNDO, '_Undo', 'Undo a change to the flow graph',
'gtk-undo'),
gtk.Action(FLOW_GRAPH_REDO, '_Redo', 'Redo a change to the flow graph',
'gtk-redo'),
- gtk.Action(ELEMENT_DELETE, '_Delete', 'Delete the selected signal
block', 'gtk-delete'),
- gtk.Action(SIGNAL_BLOCK_ROTATE_LEFT, 'Rotate _Left', 'Rotate the signal
block 90 degrees', 'gtk-go-back'),
- gtk.Action(SIGNAL_BLOCK_ROTATE_RIGHT, 'Rotate _Right', 'Rotate the
signal block -90 degrees', 'gtk-go-forward'),
- gtk.Action(SIGNAL_BLOCK_PARAM_MODIFY, '_Properties', 'Modify params for
the selected signal block', 'gtk-properties'),
+ gtk.Action(ELEMENT_REMOVE, '_Delete', 'Delete the selected signal
block', 'gtk-delete'),
+ gtk.Action(BLOCK_ROTATE_LEFT, 'Rotate _Left', 'Rotate the signal block
90 degrees', 'gtk-go-back'),
+ gtk.Action(BLOCK_ROTATE_RIGHT, 'Rotate _Right', 'Rotate the signal
block -90 degrees', 'gtk-go-forward'),
+ gtk.Action(BLOCK_PARAM_MODIFY, '_Properties', 'Modify params for the
selected signal block', 'gtk-properties'),
gtk.Action(FLOW_GRAPH_WINDOW_RESIZE, '_Window Size', 'Set the window
size', 'gtk-edit'),
gtk.Action(USRP_DIAGNOSTICS_DISPLAY, '_USRP Diagnostics', 'Analyze the
USRP', 'gtk-dialog-info'),
gtk.Action(PREFS_WINDOW_DISPLAY, '_Preferences', 'Configure
Preferences', 'gtk-preferences'),
@@ -117,4 +117,4 @@
if ACTIONS_DICT.has_key(action_name): return ACTIONS_DICT[action_name]
raise KeyError('Action Name: "%s" does not exist'%action_name)
-
\ No newline at end of file
+
Modified: grc/branches/grc_reloaded/src/grc/Messages.py
===================================================================
--- grc/branches/grc_reloaded/src/grc/Messages.py 2008-02-10 23:37:26 UTC
(rev 7627)
+++ grc/branches/grc_reloaded/src/grc/Messages.py 2008-02-11 00:04:31 UTC
(rev 7628)
@@ -82,7 +82,7 @@
################# functions for connections
########################################
def send_fail_connection():
- send('>>> Warning: A connection can only be created between an output
socket and an unconnected input socket.\n')
+ send('>>> Warning: A connection can only be created between a source
and an unconnected sink.\n')
################# functions for preferences
########################################
def send_fail_load_preferences():
Modified: grc/branches/grc_reloaded/src/grc/StateCache.py
===================================================================
--- grc/branches/grc_reloaded/src/grc/StateCache.py 2008-02-10 23:37:26 UTC
(rev 7627)
+++ grc/branches/grc_reloaded/src/grc/StateCache.py 2008-02-11 00:04:31 UTC
(rev 7628)
@@ -22,7 +22,7 @@
from Actions import FLOW_GRAPH_UNDO, FLOW_GRAPH_REDO, get_action_from_name
-DEFAULT_STATE_CACHE_SIZE = 42
+from Constants import STATE_CACHE_SIZE
class StateCache(object):
"""
@@ -31,12 +31,12 @@
and counters for the range where states are stored.
"""
- def __init__(self, initial_state, size=DEFAULT_STATE_CACHE_SIZE):
+ def __init__(self, initial_state):
"""!
StateCache constructor.
@param initial_state the intial state (nested data)
"""
- self.states = [None] * size #fill states
+ self.states = [None] * STATE_CACHE_SIZE #fill states
self.current_state_index = 0
self.num_prev_states = 0
self.num_next_states = 0
Modified: grc/branches/grc_reloaded/src/grc/__init__.py
===================================================================
--- grc/branches/grc_reloaded/src/grc/__init__.py 2008-02-10 23:37:26 UTC
(rev 7627)
+++ grc/branches/grc_reloaded/src/grc/__init__.py 2008-02-11 00:04:31 UTC
(rev 7628)
@@ -32,5 +32,4 @@
from grc.ActionHandler import ActionHandler
-
ActionHandler([], platform)
Modified: grc/branches/grc_reloaded/src/grc/elements/Block.py
===================================================================
--- grc/branches/grc_reloaded/src/grc/elements/Block.py 2008-02-10 23:37:26 UTC
(rev 7627)
+++ grc/branches/grc_reloaded/src/grc/elements/Block.py 2008-02-11 00:04:31 UTC
(rev 7628)
@@ -179,6 +179,10 @@
Export this block's params to nested data.
@return a nested data odict
"""
+ n = odict()
+ n['key'] = self.get_key()
+ n['param'] = map(lambda p: p.export_data(), self.get_params())
+ return n
def import_data(self, n):
"""
@@ -186,3 +190,8 @@
Any param keys that do not exist will be ignored.
@param n the nested data odict
"""
+ params_n = Utils.listify(n, 'param')
+ for param_n in params_n:
+ key = param_n['key']
+ value = param_n['value']
+ self.get_param(key).set_value(value)
Modified: grc/branches/grc_reloaded/src/grc/elements/Connection.py
===================================================================
--- grc/branches/grc_reloaded/src/grc/elements/Connection.py 2008-02-10
23:37:26 UTC (rev 7627)
+++ grc/branches/grc_reloaded/src/grc/elements/Connection.py 2008-02-11
00:04:31 UTC (rev 7628)
@@ -68,35 +68,17 @@
def get_sink(self): return self._sink
def get_source(self): return self._source
- def make_connection_from_n(flow_graph, n):
- """!
- Make a new connection given the parent and nested data.
- @param flow_graph the parent of this element
- @param n nested data
- @throws Error cannot make connection
- @return a new connection
+ ##############################################
+ ## Import/Export Methods
+ ##############################################
+ def export_data(self):
"""
- #get the block ids
- source_block_id = n['source_block_id']
- sink_block_id = n['sink_block_id']
- #verify the blocks
- assert(source_block_id in flow_graph.get_block_ids())
- assert(sink_block_id in flow_graph.get_block_ids())
- #get the blocks
- source_block = flow_graph.get_block(source_block_id)
- sink_block = flow_graph.get_block(sink_block_id)
- #get the port keys
- source_key = n['source_key']
- sink_key = n['sink_key']
- #verify the ports
- assert(source_key in source_block.get_source_keys())
- assert(sink_key in source_block.get_sink_keys())
- #get the ports
- source = source_block.get_source(source_key)
- sink = sink_block.get_sink(sink_key)
- #build the connection
- return Connection(flow_graph, source, sink)
- make_connection_from_n = staticmethod(make_connection_from_n)
-
-
-
+ Export this connection's info.
+ @return a nested data odict
+ """
+ n = odict()
+ n['source_block_id'] =
self.get_source().get_param('id').get_value()
+ n['sink_block_id'] = self.get_sink().get_param('id').get_value()
+ n['source_key'] = self.get_source().get_key()
+ n['sink_key'] = self.get_sink().get_key()
+ return n
Modified: grc/branches/grc_reloaded/src/grc/elements/Element.py
===================================================================
--- grc/branches/grc_reloaded/src/grc/elements/Element.py 2008-02-10
23:37:26 UTC (rev 7627)
+++ grc/branches/grc_reloaded/src/grc/elements/Element.py 2008-02-11
00:04:31 UTC (rev 7628)
@@ -83,6 +83,8 @@
def is_block(self): return False
- def is_port(self): return False
+ def is_source(self): return False
+ def is_sink(self): return False
+
def is_param(self): return False
Modified: grc/branches/grc_reloaded/src/grc/elements/FlowGraph.py
===================================================================
--- grc/branches/grc_reloaded/src/grc/elements/FlowGraph.py 2008-02-10
23:37:26 UTC (rev 7627)
+++ grc/branches/grc_reloaded/src/grc/elements/FlowGraph.py 2008-02-11
00:04:31 UTC (rev 7628)
@@ -34,11 +34,15 @@
@param platform a platforms with blocks and contrcutors
@return the flow graph object
"""
+ #hold connections and blocks
+ self._elements = list()
+ #initialize
Element.__init__(self, platform)
+ #create option block
self._options_block = self.get_parent().get_new_block(self,
'options')
- self._options_block.get_param('id').set_value('options')
+ self._options_block.get_param('id').set_value('options')
- def __str__(self): return 'FlowGraph: "%s"' + self.get_option('name')
+ def __str__(self): return 'FlowGraph: "%s"'%self.get_option('name')
def get_option(self, key):
"""!
@@ -47,10 +51,60 @@
@param key the param key for the options block
@return the value held by that param
"""
- self._options_block.get_param(key).get_value()
+ return self._options_block.get_param(key).get_value()
def is_flow_graph(self): return True
+ ##############################################
+ ## Access Elements
+ ##############################################
+ def get_elements(self): return self._elements + [self._options_block]
+ def get_blocks(self): return filter(lambda e: e.is_block(),
self.get_elements())
+ def get_connections(self): return filter(lambda e: e.is_connection(),
self.get_elements())
+
+ def get_new_block(self, key):
+ """!
+ Get a new block of the specified key.
+ Add the block to the list of elements.
+ @param key the block key
+ @return the new block or None if not found
+ """
+ #TODO implemnt None for bad key
+ block = self.get_parent().get_new_block(self, key)
+ self.get_elements().append(block)
+ return block
+
+ def connect(self, porta, portb):
+ """!
+ Create a connection between porta and portb.
+ @param porta a port
+ @param portb another port
+ @return the new connection or None for bad connection
+ """
+ #TODO implemnt None for bad connection
+ connection = self.get_parent.Connection(self, porta, portb)
+ self.get_elements().append(connection)
+ return connection
+
+ def remove_element(self, element):
+ """!
+ Remove the element from the list of elements.
+ If the element is a port, remove the whole block.
+ If the element is a block, remove its connections.
+ If the element is a connection, just remove the connection.
+ """
+ if element not in self.get_elements(): return
+ #found a port, set to parent signal block
+ if element.is_source() or element.is_sink():
+ element = element.get_parent()
+ #remove block, remove all involved connections
+ if element.is_block():
+ #TODO
+ pass
+ #remove a connection
+ elif element.is_connection(): pass
+ self.get_elements().remove(element)
+
def evaluate(self, expr):
"""!
Evaluate the expression.
@@ -64,13 +118,9 @@
Validate the flow graph.
All connections and blocks must be valid.
"""
- #TODO
-
- ##############################################
- ## Access file_path
- ##############################################
- def get_file_path(self): return self._file_path
- def set_file_path(self, file_path): self._file_path = file_path
+ for c in self.get_elements():
+ try: assert(c.is_valid())
+ except AssertionError: self._add_error_message('Element
"%s" is not valid.'%c)
##############################################
## Import/Export Methods
@@ -81,6 +131,10 @@
Export all block and connection data.
@return a nested data odict
"""
+ n = odict()
+ n['block'] = [block.export_data() for block in
self.get_blocks()]
+ n['connection'] = [connection.export_data() for connection in
self.get_connections()]
+ return {'flow_graph': n}
def import_data(self, n):
"""
@@ -89,3 +143,42 @@
Any blocks or connections in error will be ignored.
@param n the nested data odict
"""
+ #TODO error checking, also ignore options block
+ fg_n = n['flow_graph']
+ blocks_n = Utils.listify(fg_n, 'block')
+ connections_n = Utils.listify(fg_n, 'connection')
+ #build the blocks
+ for block_n in blocks_n:
+ key = block_n['key']
+ block = self.get_new_block(key)
+ block.import_data(block_n)
+ #build the connections
+ for connection_n in connections_n:
+ try:
+ #get the block ids
+ source_block_id =
connection_n['source_block_id']
+ sink_block_id = connection_n['sink_block_id']
+ #verify the blocks
+ assert(source_block_id in self.get_block_ids())
+ assert(sink_block_id in self.get_block_ids())
+ #get the blocks
+ source_block = self.get_block(source_block_id)
+ sink_block = self.get_block(sink_block_id)
+ #get the port keys
+ source_key = connection_n['source_key']
+ sink_key = connection_n['sink_key']
+ #verify the ports
+ assert(source_key in
source_block.get_source_keys())
+ assert(sink_key in source_block.get_sink_keys())
+ #get the ports
+ source = source_block.get_source(source_key)
+ sink = sink_block.get_sink(sink_key)
+ #build the connection
+ self.connect(source, sink)
+ except AssertionError: pass #TODO messages print problem
+
+
+
+
+
+
Modified: grc/branches/grc_reloaded/src/grc/elements/Param.py
===================================================================
--- grc/branches/grc_reloaded/src/grc/elements/Param.py 2008-02-10 23:37:26 UTC
(rev 7627)
+++ grc/branches/grc_reloaded/src/grc/elements/Param.py 2008-02-11 00:04:31 UTC
(rev 7628)
@@ -93,7 +93,7 @@
#grab the data
name = n['name']
key = n['key']
- value = Utils.exists_or_else(n, 'value', None)
+ value = Utils.exists_or_else(n, 'value', '')
type = n['type']
options = Utils.listify(n, 'option')
#build the param
@@ -129,7 +129,7 @@
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 '0'
+ else: self._value = value or ''
def test(self):
"""
@@ -185,4 +185,15 @@
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.
+ @return a nested data odict
+ """
+ n = odict()
+ n['key'] = self.get_key()
+ n['value'] = self.get_value()
+ return n
Modified: grc/branches/grc_reloaded/src/grc/elements/Platform.py
===================================================================
--- grc/branches/grc_reloaded/src/grc/elements/Platform.py 2008-02-10
23:37:26 UTC (rev 7627)
+++ grc/branches/grc_reloaded/src/grc/elements/Platform.py 2008-02-11
00:04:31 UTC (rev 7628)
@@ -68,7 +68,8 @@
def is_platform(self): return True
- def get_new_flow_graph(self): return Platform.FlowGraph(self)
+ def get_new_flow_graph(self):
+ return self.FlowGraph(self)
##############################################
# Access Blocks
Modified: grc/branches/grc_reloaded/src/grc/gui/Bars.py
===================================================================
--- grc/branches/grc_reloaded/src/grc/gui/Bars.py 2008-02-10 23:37:26 UTC
(rev 7627)
+++ grc/branches/grc_reloaded/src/grc/gui/Bars.py 2008-02-11 00:04:31 UTC
(rev 7628)
@@ -39,9 +39,9 @@
FLOW_GRAPH_EXEC,
FLOW_GRAPH_STOP,
None,
- ELEMENT_DELETE,
- SIGNAL_BLOCK_ROTATE_LEFT,
- SIGNAL_BLOCK_ROTATE_RIGHT,
+ ELEMENT_REMOVE,
+ BLOCK_ROTATE_LEFT,
+ BLOCK_ROTATE_RIGHT,
)
##The list of actions and categories for the menu bar.
@@ -62,10 +62,10 @@
FLOW_GRAPH_UNDO,
FLOW_GRAPH_REDO,
None,
- ELEMENT_DELETE,
- SIGNAL_BLOCK_ROTATE_LEFT,
- SIGNAL_BLOCK_ROTATE_RIGHT,
- SIGNAL_BLOCK_PARAM_MODIFY,
+ ELEMENT_REMOVE,
+ BLOCK_ROTATE_LEFT,
+ BLOCK_ROTATE_RIGHT,
+ BLOCK_PARAM_MODIFY,
]),
(gtk.Action('Execute', '_Execute', None, None), [
FLOW_GRAPH_EXEC,
Modified: grc/branches/grc_reloaded/src/grc/gui/DrawingArea.py
===================================================================
--- grc/branches/grc_reloaded/src/grc/gui/DrawingArea.py 2008-02-10
23:37:26 UTC (rev 7627)
+++ grc/branches/grc_reloaded/src/grc/gui/DrawingArea.py 2008-02-11
00:04:31 UTC (rev 7628)
@@ -57,8 +57,15 @@
self.connect("leave-notify-event", self._handle_focus_event,
False)
self.connect("enter-notify-event", self._handle_focus_event,
True)
#pixmap for drawing to
- self._pixmap = None
+ self.pixmap = None
self.gc = None
+
+ def draw(self):
+ """!
+ Draw the pixmap onto this drawing area.
+ """
+ self.window.draw_drawable(self.gc, self.pixmap, 0, 0, 0, 0, -1,
-1)
+
##########################################################################
## Handlers
@@ -72,9 +79,10 @@
"""!
Forward button click information to the flow graph.
"""
- self._main_window.get_flow_graph().handle_mouse_button_click(
+ self._main_window.get_flow_graph().handle_mouse_button_press(
left_click=(event.button == 1),
double_click=(event.type == gtk.gdk._2BUTTON_PRESS),
+ coordinate=(event.x, event.y),
)
return True
@@ -84,6 +92,7 @@
"""
self._main_window.get_flow_graph().handle_mouse_button_release(
left_click=(event.button == 1),
+ coordinate=(event.x, event.y),
)
return True
@@ -98,9 +107,10 @@
def _handle_window_expose(self, widget, event):
"""Called when the window initially appears or is resized:
create a new pixmap, draw the flow graph."""
+ #TODO remove set size
+ self.set_size_request(400, 400)
self.gc = self.window.new_gc()
width, height = self.get_size_request()
- if self._pixmap == None or (width, height) !=
self._pixmap.get_size():
- self._pixmap = gtk.gdk.Pixmap(self.window, width,
height, -1)
- self._main_window.get_flow_graph().draw()
-
+ if not self.pixmap or (width, height) !=
self.pixmap.get_size():
+ self.pixmap = gtk.gdk.Pixmap(self.window, width,
height, -1)
+ self._main_window.get_flow_graph().update()
Modified: grc/branches/grc_reloaded/src/grc/gui/MainWindow.py
===================================================================
--- grc/branches/grc_reloaded/src/grc/gui/MainWindow.py 2008-02-10 23:37:26 UTC
(rev 7627)
+++ grc/branches/grc_reloaded/src/grc/gui/MainWindow.py 2008-02-11 00:04:31 UTC
(rev 7628)
@@ -188,8 +188,8 @@
self.scrolled_window = gtk.ScrolledWindow()
self.scrolled_window.set_size_request(MIN_WINDOW_WIDTH,
MIN_WINDOW_HEIGHT)
self.scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,
gtk.POLICY_AUTOMATIC)
- self._drawing_area = DrawingArea(self)
- self.scrolled_window.add_with_viewport(self._drawing_area)
+ self.drawing_area = DrawingArea(self)
+ self.scrolled_window.add_with_viewport(self.drawing_area)
# create the notebook #
self.notebook = gtk.Notebook()
self.page_to_be_closed = None
@@ -219,7 +219,7 @@
vbox.show_all()
self._show_reports_window(False)
# load preferences and show the main window
- #Preferences.load(self)
+ #TODO Preferences.load(self)
self.show()#show after resize in preferences
############################################################
@@ -247,9 +247,10 @@
"""
self.current_page = self.notebook.get_nth_page(page_num)
Messages.send_page_switch(self.current_page.get_file_path())
- state = self.get_page().get_state_cache().get_current_state()
- self.get_flow_graph().from_nested_data(state)
- self.handle_states(NOTHING_SELECT)
+ #TODO may not need since we have multiple flow graph instances
now
+ #TODO state =
self.get_page().get_state_cache().get_current_state()
+ #TODO self.get_flow_graph().from_nested_data(state)
+ #TODO self.handle_states(NOTHING_SELECT)
############################################################
## Report Window
@@ -291,9 +292,13 @@
return
try: #try to load from file
if file_path: Messages.send_start_load(file_path)
+ flow_graph = self._platform.get_new_flow_graph()
+ #inject drawing area and handle states into flow graph
+ flow_graph.drawing_area = self.drawing_area
+ flow_graph.handle_states = self.handle_states
page = Page(
self,
- flow_graph=self._platform.get_new_flow_graph(),
+ flow_graph=flow_graph,
file_path=file_path,
)
if file_path: Messages.send_end_load()
Modified: grc/branches/grc_reloaded/src/grc/gui/elements/Block.py
===================================================================
--- grc/branches/grc_reloaded/src/grc/gui/elements/Block.py 2008-02-10
23:37:26 UTC (rev 7627)
+++ grc/branches/grc_reloaded/src/grc/gui/elements/Block.py 2008-02-11
00:04:31 UTC (rev 7628)
@@ -21,7 +21,7 @@
address@hidden Josh Blum
from Element import Element
-import Element as Utils
+import Utils
import Colors
from grc.Constants import *
import pygtk
@@ -35,27 +35,28 @@
def update(self):
"""Update the block, parameters, and ports when a change
occurs."""
self.clear()
- self._adjust_ports()
+ #TODO self._adjust_ports()
self._create_labels()
self.W = self.label_width + 2*LABEL_PADDING_WIDTH
- max_ports = max(self.get_num_input_ports(),
self.get_num_output_ports(), 1)
+ max_ports = max(len(self.get_sinks()), len(self.get_sources()),
1)
self.H = max(self.label_height+2*LABEL_PADDING_HEIGHT,
2*SOCKET_BORDER_SEPARATION + max_ports*SOCKET_HEIGHT +
(max_ports-1)*SOCKET_SEPARATION)
if Utils.is_horizontal(self.get_rotation()):
self.add_area((0,0),(self.W,self.H))
elif Utils.is_vertical(self.get_rotation()):
self.add_area((0,0),(self.H,self.W))
- for port in self.get_ports(): port.update()
+ map(lambda p: p.update(), self.get_sinks() + self.get_sources())
def _create_labels(self):
"""Create the labels for the signal block."""
layouts = list()
# create the main layout #
- layout = gtk.DrawingArea().create_pango_layout(self.cname)
+ layout = gtk.DrawingArea().create_pango_layout(self.get_name())
desc = pango.FontDescription(SIGNAL_BLOCK_FONT)
layout.set_font_description(desc)
layouts.append(layout)
- if not self.is_valid(): layout.set_markup('<span
foreground="red"><b>'+self.cname+'</b></span>')
+ if not self.is_valid(): layout.set_markup('<span
foreground="red"><b>'+self.get_name()+'</b></span>')
self.label_width,self.label_height = layout.get_pixel_size()
# handle each of the displayable params #
- for param in self.displayed_params:
+ #TODO for param in self.displayed_params:
+ if False:
layout = param.get_layout()
layouts.append(layout)
w,h = layout.get_pixel_size()
@@ -63,13 +64,13 @@
self.label_height = self.label_height + h +
LABEL_SEPARATION
width = self.label_width
height = self.label_height
- # setup the pixmap #
- pixmap = gtk.gdk.Pixmap(self.get_parent().window, width,
height, -1)
+ #setup the pixmap
+ pixmap = gtk.gdk.Pixmap(self.get_parent().get_window(), width,
height, -1)
gc = pixmap.new_gc()
gc.foreground = Colors.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()
@@ -77,7 +78,7 @@
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 Utils.is_vertical(self.get_rotation()):
self.vertical_label = vimage =
gtk.gdk.Image(gtk.gdk.IMAGE_NORMAL, pixmap.get_visual(), height, width)
@@ -89,31 +90,16 @@
Draw the signal block with label and inputs/outputs.
@param window the gtk window to draw on
"""
- Utils.draw(self, window)
- gc = self.gc
+ Element.draw(self, window)
+ gc = self.get_gc()
gc.foreground = Colors.TXT_COLOR
X,Y = self.get_coordinate()
if Utils.is_horizontal(self.get_rotation()):
window.draw_image(gc, self.horizontal_label, 0, 0,
X+LABEL_PADDING_WIDTH, Y+(self.H-self.label_height)/2, -1, -1)
elif Utils.is_vertical(self.get_rotation()):
window.draw_image(gc, self.vertical_label, 0, 0,
X+(self.H-self.label_height)/2, Y+LABEL_PADDING_WIDTH, -1, -1)
- for port in self.get_ports(): port.draw(window)
+ map(lambda p: p.draw(window), self.get_sources() +
self.get_sinks())
- def is_valid(self):
- """!
- Is this block is valid/are all the params valid and all ports
connected?
- User preferences can override certain validity checks.
- @return true if valid
- """
- #import Preferences
- #if Preferences.check_params(): #preferences
- for param in self.params:
- if not param.get_data_type().is_valid(): return False
- #if Preferences.check_ports(): #preferences
- for port in self.get_ports():
- if not port.is_valid(): return False
- return True
-
def modify_type_controller(self, direction):
"""!
If a type controller was set, increment/decrement its index by
1, use a % to stay in bounds.
Modified: grc/branches/grc_reloaded/src/grc/gui/elements/Element.py
===================================================================
--- grc/branches/grc_reloaded/src/grc/gui/elements/Element.py 2008-02-10
23:37:26 UTC (rev 7627)
+++ grc/branches/grc_reloaded/src/grc/gui/elements/Element.py 2008-02-11
00:04:31 UTC (rev 7628)
@@ -26,33 +26,25 @@
pygtk.require('2.0')
import gtk
import pango
+from grc.Constants import *
-## True if the rotation is 90 or 270 degrees.
-is_vertical = lambda rot: rot in (90, 270)
-
-## True if the rotation is 0 or 180 degrees.
-is_horizontal = lambda rot: rot in (0, 180)
-
-def get_angle_from_coordinates((x1,y1), (x2,y2)):
- """!
- Given two points, calculate the vector direction from point1 to point2,
directions are multiples of 90 degrees.
- @param (x1,y1) the coordinate of point 1
- @param (x2,y2) the coordinate of point 2
- @return the direction in degrees
- """
- if y1 == y2:#0 or 180
- if x2 > x1: return 0
- else: return 180
- else:#90 or 270
- if y2 > y1: return 270
- else: return 90
-
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,
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.clear()
+ self.set_highlighted(False)
+
+ def get_gc(self): return self._gc
def draw(self, window, BG_color=Colors.BG_COLOR,
FG_color=Colors.FG_COLOR):
"""!
@@ -61,8 +53,8 @@
@param BG_color the background color
@param FG_color the foreground color
"""
- gc = self.get_parent().gc
- self.gc = 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
@@ -74,5 +66,122 @@
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
+ self.set_rotation((self.get_rotation() + delta_rotation)%360)
+ 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
+
+ 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.coor = (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.
+ 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
+ @param area (width,height) tuple
+ @param rotation rotation in degrees
+ """
+ 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.
+ 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
+ @param rel_coor2 relative (x2,y2) tuple
+ @param rotation rotation in degrees
+ """
+ if rotation == None: rotation = self.get_rotation()
+ 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.
+ """
+ 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())]
+ for (x1,y1), (w,h) in self.areas_dict[self.get_rotation()]:
+ if in_between(x, x1, x1+w) and in_between(y, y1, y1+h):
return self
+ for (x1, y1), (x2, y2) in self.lines_dict[self.get_rotation()]:
#assume horizontal or vertical lines
+ 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
+
+ def get_rotation(self):
+ """!
+ Get the rotation in degrees.
+ @return the 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):
+ """Do nothing for the update. Dummy method."""
+ pass
Modified: grc/branches/grc_reloaded/src/grc/gui/elements/FlowGraph.py
===================================================================
--- grc/branches/grc_reloaded/src/grc/gui/elements/FlowGraph.py 2008-02-10
23:37:26 UTC (rev 7627)
+++ grc/branches/grc_reloaded/src/grc/gui/elements/FlowGraph.py 2008-02-11
00:04:31 UTC (rev 7628)
@@ -24,7 +24,7 @@
from grc.Actions import *
from Colors import BACKGROUND_COLOR, TXT_COLOR
-import Element
+from Element import Element
import pygtk
pygtk.require('2.0')
@@ -34,52 +34,34 @@
from grc import ParseXML
from grc import Messages
-class FlowGraph(object):
+class FlowGraph(Element):
"""
FlowGraph is the data structure to store graphical signal blocks,
graphical inputs and outputs,
and the connections between inputs and outputs.
"""
- def __init__TODO(self, handle_states, variable_modification_window):
+ def __init__(self, *args, **kwargs):
"""!
FlowGraph contructor.
Create a list for signal blocks and connections. Connect mouse
handlers.
- @param handle_states the callback function
- @param variable_modification_window var mod window also for
callbacks
"""
- #setup
- self.elements = list()
- self.remove_element = lambda e: self.elements.remove(e)
- self.gc = None
- self.handle_states = handle_states
- self.variable_modification_window = variable_modification_window
- gtk.DrawingArea.__init__(self)
- self.connect('expose-event', self._handle_window_expose)
- self.connect('motion-notify-event', self._handle_mouse_motion)
- self.connect('button-press-event',
self._handle_mouse_button_press)
- self.connect('button-release-event',
self._handle_mouse_button_release)
- self.set_events(
- gtk.gdk.BUTTON_PRESS_MASK | \
- gtk.gdk.POINTER_MOTION_MASK | \
- gtk.gdk.BUTTON_RELEASE_MASK | \
- gtk.gdk.LEAVE_NOTIFY_MASK | \
- gtk.gdk.ENTER_NOTIFY_MASK
- )
- # setup the focus flag #
- self.focus_flag = False
- self.get_focus_flag = lambda: self.focus_flag
- self.connect("leave-notify-event", self._handle_focus_event,
False)
- self.connect("enter-notify-event", self._handle_focus_event,
True)
- # important vars dealing with mouse event tracking
#
+ Element.__init__(self)
+ #important vars dealing with mouse event tracking
self.has_moved = False
self.mouse_pressed = False
- self.coordinate = (0,0)
self.selected_element = None
self.is_selected = lambda: self.selected_element != None
self.count = 0
- self.pixmap = None
+ def get_gc(self): return self.drawing_area.gc
+
+ def get_pixmap(self): return self.drawing_area.pixmap
+
+ def get_size(self): return self.drawing_area.get_size_request()
+
+ def get_window(self): return self.drawing_area.window
+
###########################################################################
# Flow Graph Access Methods
###########################################################################
@@ -104,7 +86,7 @@
self.elements.append(
SignalBlockDefs.get_signal_block(self,
(x, y), rot, tag, id, GraphicalSignalBlock)[0]
)
- self.handle_states(SIGNAL_BLOCK_CREATE)
+ self.handle_states(BLOCK_CREATE)
self.update()
return
@@ -114,48 +96,32 @@
@param direction +1 or -1
@return true for success
"""
- if Element.is_socket(self.selected_element):
self.selected_element = self.selected_element.get_parent()
+ if Element.is_port(self.selected_element):
self.selected_element = self.selected_element.get_parent()
if Element.is_signal_block(self.selected_element): return
self.selected_element.modify_type_controller(direction)
return False
- def socket_controller_modify_selected(self, direction):
+ def port_controller_modify_selected(self, direction):
"""!
- Change socket controller for the selected signal block.
+ Change port controller for the selected signal block.
@param direction +1 or -1
@return true for success
"""
- if Element.is_socket(self.selected_element):
self.selected_element = self.selected_element.get_parent()
- if Element.is_signal_block(self.selected_element): return
self.selected_element.modify_socket_controller(direction)
+ if Element.is_port(self.selected_element):
self.selected_element = self.selected_element.get_parent()
+ if Element.is_signal_block(self.selected_element): return
self.selected_element.modify_port_controller(direction)
return False
def param_modify_selected(self):
"""!
- Create and show a param modification dialog for the selected
element (socket and signal block only).
+ Create and show a param modification dialog for the selected
element (port and signal block only).
@return true if parameters were changed
"""
- if Element.is_socket(self.selected_element):
self.selected_element = self.selected_element.get_parent()
+ if Element.is_port(self.selected_element):
self.selected_element = self.selected_element.get_parent()
if Element.is_signal_block(self.selected_element):
signal_block_params_dialog =
SignalBlockParamsDialog(self.selected_element)
changed = signal_block_params_dialog.run()
self.update()
return changed #changes were made?
return False
-
- def connect_sockets(self, s1, s2):
- """!
- Connect input and output sockets. Ignore state change if
creation of connection fails.
- @param s1 a socket
- @param s2 another socket
- """
- try:
- connection = GraphicalConnection(self, s1, s2)
- self.elements.append(connection)
- self.selected_element = None
- self.handle_states(CONNECTION_CREATE)
- self.update()
- except ConnectionException:
- Messages.send_fail_connection()
- self.handle_states(NOTHING_SELECT)
def move_selected(self, delta_coordinate):
"""!
@@ -173,26 +139,19 @@
@param direction DIR_LEFT or DIR_RIGHT
@return true if rotated, otherwise false.
"""
- if self.selected_element != None and
(Element.is_signal_block(self.selected_element) or
Element.is_socket(self.selected_element)):
+ if self.selected_element != None and
(Element.is_signal_block(self.selected_element) or
Element.is_port(self.selected_element)):
self.selected_element.rotate(direction)
self.draw()
return True
return False
- def delete_selected(self):
+ 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 != None:
- if Element.is_socket(self.selected_element): # found
a socket, set to parent signal block
- self.selected_element =
self.selected_element.get_parent()
- if Element.is_signal_block(self.selected_element):
# delete a signal block
- connections =
self.selected_element.get_connections()
- for connection in connections:
connection.disconnect()
- self.remove_element(self.selected_element)
- elif Element.is_connection(self.selected_element):
# delete a connection
- self.selected_element.disconnect()
+ if self.selected_element:
+ self.remove_element(self.selected_element)
self.selected_element = None
self.update()
return True
@@ -215,89 +174,88 @@
@param coor the coordinate of the mouse click
@return the selected element or None
"""
- # check the elements #
- for element in reversed(self.elements):
+ #check the elements
+ for element in reversed(self.get_elements()):
if element.what_is_selected(coor) != None:
- self.elements.remove(element)
- self.elements.append(element)
+ self.get_elements().remove(element)
+ self.get_elements().append(element)
return element.what_is_selected(coor)
return None
def draw(self, drawable=None):
"""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.gc != None:
- # draw the background #
- W,H = self.get_size_request()
- self.gc.foreground = BACKGROUND_COLOR
- self.pixmap.draw_rectangle(self.gc, True, 0, 0, W, H)
- if Preferences.show_grid():
+ if self.get_gc():
+ #draw the background
+ W,H = self.get_size()
+ self.get_gc().foreground = BACKGROUND_COLOR
+ self.get_pixmap().draw_rectangle(self.get_gc(), True,
0, 0, W, H)
+ #TODO if Preferences.show_grid():
+ if False:
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.gc.foreground = TXT_COLOR
- self.pixmap.draw_points(self.gc, points)
- # draw the foreground #
- for element in filter(Element.is_signal_block,
self.elements) + filter(Element.is_connection, self.elements):
- element.draw(self.pixmap) # draw signal
blocks first, then connections on the top
- if self.mouse_pressed and self.selected_element != None:
- self.selected_element.draw(self.pixmap)
- self.window.draw_drawable(self.gc, self.pixmap, 0, 0,
0, 0, -1, -1)
-
- def is_valid(self):
- """!
- Is the flow graph valid, ie: are all elements valid?
- @return true if flow graph is valid
- """
- for element in self.elements:
- if not element.is_valid(): return False
- return True
- #return all([element.is_valid() for element in self.elements])
#python 2.5 and higher
+ self.get_gc().foreground = TXT_COLOR
+ self.get_pixmap().draw_points(self.get_gc(),
points)
+ #draw the foreground
+ for element in self.get_blocks() +
self.get_connections():
+ element.draw(self.get_pixmap()) # draw signal
blocks first, then connections on the top
+ if self.mouse_pressed and self.selected_element:
+ self.selected_element.draw(self.get_pixmap())
+ self.drawing_area.draw()
def update(self):
"""Call update on all elements."""
- for element in self.elements: element.update()
+ map(lambda e: e.update(), self.get_elements())
self.draw()
##########################################################################
## Handlers
##########################################################################
- def handle_mouse_button_press(self, left_click, double_click):
+ 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 != None:
self.selected_element.set_highlighted(False)
self.count = 0
self.mouse_pressed = True
- self.coordinate = (event.x, event.y)
old_selection = self.selected_element
- self.selected_element = self.what_is_selected((event.x,
event.y))
- # handle the state change with the new selection
#
- if Element.is_connection(self.selected_element):
self.handle_states(CONNECTION_SELECT)
- elif Element.is_socket(self.selected_element):
self.handle_states(SOCKET_SELECT)
- elif Element.is_signal_block(self.selected_element):
self.handle_states(SIGNAL_BLOCK_SELECT)
- elif self.selected_element == None:
self.handle_states(NOTHING_SELECT)
- # this selection and the last were Sockets, try
to connect them #
- if Element.is_socket(old_selection) and
Element.is_socket(self.selected_element) and\
- old_selection is not self.selected_element:
#cannot be the same socket
- self.connect_sockets(old_selection,
self.selected_element)
- if self.selected_element != None:
self.selected_element.set_highlighted(True)
- # double click detected, bring up params dialog
if possible #
- if double_click and
Element.is_signal_block(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:
+ 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)
+ #this selection and the last were Sockets, 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: self.connect(old_selection,
self.selected_element)
+ 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():
self.mouse_pressed = False
- self.handle_states(SIGNAL_BLOCK_PARAM_MODIFY)
+ self.handle_states(BLOCK_PARAM_MODIFY)
self.draw()
return True
- def handle_mouse_button_release(self, left_click):
+ def handle_mouse_button_release(self, left_click, coordinate):
"""A mouse button is released, record the state."""
+ self.set_coordinate(coordinate)
if left_click:
self.mouse_pressed = False
if self.has_moved:
- if Preferences.snap_to_grid():
+ #TODO if Preferences.snap_to_grid():
+ if False:
grid_size = Preferences.get_grid_size()
X,Y =
self.selected_element.get_coordinate()
deltaX = X%grid_size
@@ -307,14 +265,15 @@
if deltaY < grid_size/2: deltaY = -1 *
deltaY
else: deltaY = grid_size - deltaY
self.move_selected((deltaX,deltaY))
- self.handle_states(SIGNAL_BLOCK_MOVE)
+ self.handle_states(BLOCK_MOVE)
self.has_moved = False
return True
def handle_mouse_motion(self, coordinate):
"""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."""
- fgW,fgH = self.get_size_request()
+ scroll_pane = self.drawing_area.get_parent()
+ fgW,fgH = self.get_size()
self.count = (1 +
self.count)%MOTION_DETECT_REDRAWING_SENSITIVITY
# to perform a movement, the mouse must be pressed, an
element selected, count of zero. #
if self.mouse_pressed and\
@@ -331,25 +290,25 @@
if y >= fgH - BORDER_PROXIMITY_SENSITIVITY:
y = fgH - BORDER_PROXIMITY_SENSITIVITY
# get the change in coordinates #
- X,Y = self.coordinate
+ X,Y = self.get_coordinate()
deltaX = int(x - X)
deltaY = int(y - Y)
- vAdj = self.get_parent().get_vadjustment().get_value()
- hAdj = self.get_parent().get_hadjustment().get_value()
- width = self.get_parent().get_hadjustment().page_size
- height = self.get_parent().get_vadjustment().page_size
+ vAdj = scroll_pane.get_vadjustment().get_value()
+ hAdj = scroll_pane.get_hadjustment().get_value()
+ width = scroll_pane.get_hadjustment().page_size
+ height = scroll_pane.get_vadjustment().page_size
# scroll horizontal if we moved near the border #
if x-hAdj > width-SCROLL_PROXIMITY_SENSITIVITY and\
hAdj+SCROLL_DISTANCE < fgW - width:
-
self.get_parent().get_hadjustment().set_value(hAdj+SCROLL_DISTANCE)
+
scroll_pane.get_hadjustment().set_value(hAdj+SCROLL_DISTANCE)
elif x-hAdj < SCROLL_PROXIMITY_SENSITIVITY:
-
self.get_parent().get_hadjustment().set_value(hAdj-SCROLL_DISTANCE)
+
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\
vAdj+SCROLL_DISTANCE < fgH - height:
-
self.get_parent().get_vadjustment().set_value(vAdj+SCROLL_DISTANCE)
+
scroll_pane.get_vadjustment().set_value(vAdj+SCROLL_DISTANCE)
elif y-vAdj < SCROLL_PROXIMITY_SENSITIVITY:
-
self.get_parent().get_vadjustment().set_value(vAdj-SCROLL_DISTANCE)
+
scroll_pane.get_vadjustment().set_value(vAdj-SCROLL_DISTANCE)
# move the selected element and record the new
coordinate #
self.move_selected((deltaX, deltaY))
- self.coordinate = (x, y)
+ self.set_coordinate(coordinate)
Modified: grc/branches/grc_reloaded/src/grc/gui/elements/Platform.py
===================================================================
--- grc/branches/grc_reloaded/src/grc/gui/elements/Platform.py 2008-02-10
23:37:26 UTC (rev 7627)
+++ grc/branches/grc_reloaded/src/grc/gui/elements/Platform.py 2008-02-11
00:04:31 UTC (rev 7628)
@@ -26,15 +26,27 @@
from Port import Port
from Param import Param
-from new import classobj
+def conjoin_classes(name, c1, c2):
+ exec("""
+class %s(c1, c2):
+ def __init__(self, *args, **kwargs):
+ c1.__init__(self, *args, **kwargs)
+ c2.__init__(self, *args, **kwargs)
+"""%name, locals())
+ return locals()[name]
def Platform(platform):
#combine with gui class
- platform.FlowGraph = classobj('FlowGraph', (FlowGraph,
platform.FlowGraph), {})
- platform.Connection = classobj('Connection', (Connection,
platform.Connection), {})
- platform.Block = classobj('Block', (Block, platform.Block), {})
- platform.Source = classobj('Source', (Port, platform.Source), {})
- platform.Sink = classobj('Sink', (Port, platform.Sink), {})
- platform.Param = classobj('Param', (Param, platform.Param), {})
+ for attr, value in (
+ ('FlowGraph', FlowGraph),
+ ('Connection', Connection),
+ ('Block', Block),
+ ('Source', Port),
+ ('Sink', Port),
+ ('Param', Param),
+ ):
+ old_value = getattr(platform, attr)
+ c = conjoin_classes(attr, old_value, value)
+ setattr(platform, attr, c)
return platform
Added: grc/branches/grc_reloaded/src/grc/gui/elements/Utils.py
===================================================================
--- grc/branches/grc_reloaded/src/grc/gui/elements/Utils.py
(rev 0)
+++ grc/branches/grc_reloaded/src/grc/gui/elements/Utils.py 2008-02-11
00:04:31 UTC (rev 7628)
@@ -0,0 +1,42 @@
+"""
+Copyright 2008 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+GNU Radio Companion is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+"""
address@hidden grc.gui.elements.Utils
+#Shared functions for flow graph elements.
address@hidden Josh Blum
+
+## True if the rotation is 90 or 270 degrees.
+is_vertical = lambda rot: rot in (90, 270)
+
+## True if the rotation is 0 or 180 degrees.
+is_horizontal = lambda rot: rot in (0, 180)
+
+def get_angle_from_coordinates((x1,y1), (x2,y2)):
+ """!
+ Given two points, calculate the vector direction from point1 to point2,
directions are multiples of 90 degrees.
+ @param (x1,y1) the coordinate of point 1
+ @param (x2,y2) the coordinate of point 2
+ @return the direction in degrees
+ """
+ if y1 == y2:#0 or 180
+ if x2 > x1: return 0
+ else: return 180
+ else:#90 or 270
+ if y2 > y1: return 270
+ else: return 90
+
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r7628 - in grc/branches/grc_reloaded/src/grc: . elements gui gui/elements,
jblum <=