Block.py

Go to the documentation of this file.
00001 """
00002 Copyright 2007 Free Software Foundation, Inc.
00003 This file is part of GNU Radio
00004 
00005 GNU Radio Companion is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU General Public License
00007 as published by the Free Software Foundation; either version 2
00008 of the License, or (at your option) any later version.
00009 
00010 GNU Radio Companion is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 GNU General Public License for more details.
00014 
00015 You should have received a copy of the GNU General Public License
00016 along with this program; if not, write to the Free Software
00017 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
00018 """
00019 ##@package grc.gui.elements.Block
00020 #The graphical signal block.
00021 #@author Josh Blum
00022 
00023 from grc import Preferences
00024 from Element import Element
00025 import Utils
00026 import Colors
00027 from grc.Constants import *
00028 import pygtk
00029 pygtk.require('2.0')
00030 import gtk
00031 import pango
00032 
00033 class Block(Element):
00034         """The graphical signal block."""
00035 
00036         def __init__(self, *args, **kwargs):
00037                 """!
00038                 Block contructor.
00039                 Add graphics related params to the block.
00040                 """
00041                 #add the position param
00042                 self._params['_coordinate'] = self.get_parent().get_parent().Param(
00043                         self,
00044                         {
00045                                 'name': 'GUI Coordinate',
00046                                 'key': '_coordinate',
00047                                 'type': 'raw',
00048                                 'value': '(0, 0)',
00049                                 'hide': 'all',
00050                         }
00051                 )
00052                 self._params['_rotation'] = self.get_parent().get_parent().Param(
00053                         self,
00054                         {
00055                                 'name': 'GUI Rotation',
00056                                 'key': '_rotation',
00057                                 'type': 'raw',
00058                                 'value': '0',
00059                                 'hide': 'all',
00060                         }
00061                 )
00062                 Element.__init__(self)
00063 
00064         def get_coordinate(self):
00065                 """!
00066                 Get the coordinate from the position param.
00067                 @return the coordinate tuple (x, y) or (0, 0) if failure
00068                 """
00069                 try: #should evaluate to tuple
00070                         coor = eval(self.get_param('_coordinate').get_value())
00071                         x, y = map(int, coor)
00072                         fgW,fgH = self.get_parent().get_size()
00073                         if x <= 0:
00074                                 x = 0
00075                         elif x >= fgW - BORDER_PROXIMITY_SENSITIVITY:
00076                                 x = fgW - BORDER_PROXIMITY_SENSITIVITY
00077                         if y <= 0:
00078                                 y = 0
00079                         elif y >= fgH - BORDER_PROXIMITY_SENSITIVITY:
00080                                 y = fgH - BORDER_PROXIMITY_SENSITIVITY
00081                         return (x, y)
00082                 except:
00083                         self.set_coordinate((0, 0))
00084                         return (0, 0)
00085 
00086         def set_coordinate(self, coor):
00087                 """!
00088                 Set the coordinate into the position param.
00089                 @param coor the coordinate tuple (x, y)
00090                 """
00091                 self.get_param('_coordinate').set_value(str(coor))
00092 
00093         def get_rotation(self):
00094                 """!
00095                 Get the rotation from the position param.
00096                 @return the rotation in degrees or 0 if failure
00097                 """
00098                 try: #should evaluate to dict
00099                         rotation = eval(self.get_param('_rotation').get_value())
00100                         return int(rotation)
00101                 except:
00102                         self.set_rotation(POSSIBLE_ROTATIONS[0])
00103                         return POSSIBLE_ROTATIONS[0]
00104 
00105         def set_rotation(self, rot):
00106                 """!
00107                 Set the rotation into the position param.
00108                 @param rot the rotation in degrees
00109                 """
00110                 self.get_param('_rotation').set_value(str(rot))
00111 
00112         def update(self):
00113                 """Update the block, parameters, and ports when a change occurs."""
00114                 self.bg_color = self.get_enabled() and Colors.BG_COLOR or Colors.DISABLED_BG_COLOR
00115                 self.clear()
00116                 self._create_labels()
00117                 self.W = self.label_width + 2*LABEL_PADDING_WIDTH
00118                 max_ports = max(len(self.get_sinks()), len(self.get_sources()), 1)
00119                 self.H = max(self.label_height+2*LABEL_PADDING_HEIGHT, 2*PORT_BORDER_SEPARATION + max_ports*PORT_HEIGHT + (max_ports-1)*PORT_SEPARATION)
00120                 if self.is_horizontal(): self.add_area((0,0),(self.W,self.H))
00121                 elif self.is_vertical(): self.add_area((0,0),(self.H,self.W))
00122                 map(lambda p: p.update(), self.get_sinks() + self.get_sources())
00123 
00124         def _create_labels(self):
00125                 """Create the labels for the signal block."""
00126                 layouts = list()
00127                 #create the main layout
00128                 layout = gtk.DrawingArea().create_pango_layout('')
00129                 layouts.append(layout)
00130                 if self.is_valid():     layout.set_markup('<b>'+Utils.xml_encode(self.get_name())+'</b>')
00131                 else: layout.set_markup('<span foreground="red"><b>'+Utils.xml_encode(self.get_name())+'</b></span>')
00132                 desc = pango.FontDescription(BLOCK_FONT)
00133                 layout.set_font_description(desc)
00134                 self.label_width, self.label_height = layout.get_pixel_size()
00135                 #display the params (except for the special params id and position)
00136                 if Preferences.show_params():
00137                         for param in filter(lambda p: p.get_hide() not in ('all', 'part'), self.get_params()):
00138                                 if not Preferences.show_id() and param.get_key() == 'id': continue
00139                                 layout = param.get_layout()
00140                                 layouts.append(layout)
00141                                 w,h = layout.get_pixel_size()
00142                                 self.label_width = max(w, self.label_width)
00143                                 self.label_height = self.label_height + h + LABEL_SEPARATION
00144                 width = self.label_width
00145                 height = self.label_height
00146                 #setup the pixmap
00147                 pixmap = gtk.gdk.Pixmap(self.get_parent().get_window(), width, height, -1)
00148                 gc = pixmap.new_gc()
00149                 gc.foreground = self.bg_color
00150                 pixmap.draw_rectangle(gc, True, 0, 0, width, height)
00151                 gc.foreground = Colors.TXT_COLOR
00152                 #draw the layouts
00153                 h_off = 0
00154                 for i,layout in enumerate(layouts):
00155                         w,h = layout.get_pixel_size()
00156                         if i == 0: w_off = (width-w)/2
00157                         else: w_off = 0
00158                         pixmap.draw_layout(gc, w_off, h_off, layout)
00159                         h_off = h + h_off + LABEL_SEPARATION
00160                 #create vertical and horizontal images
00161                 self.horizontal_label = image = pixmap.get_image(0, 0, width, height)
00162                 if self.is_vertical():
00163                         self.vertical_label = vimage = gtk.gdk.Image(gtk.gdk.IMAGE_NORMAL, pixmap.get_visual(), height, width)
00164                         for i in range(width):
00165                                 for j in range(height): vimage.put_pixel(j, width-i-1, image.get_pixel(i, j))
00166 
00167         def draw(self, window):
00168                 """!
00169                 Draw the signal block with label and inputs/outputs.
00170                 @param window the gtk window to draw on
00171                 """
00172                 x, y = self.get_coordinate()
00173                 #draw main block
00174                 Element.draw(self, window, BG_color=self.bg_color)
00175                 #draw label image
00176                 gc = self.get_gc()
00177                 if self.is_horizontal():
00178                         window.draw_image(gc, self.horizontal_label, 0, 0, x+LABEL_PADDING_WIDTH, y+(self.H-self.label_height)/2, -1, -1)
00179                 elif self.is_vertical():
00180                         window.draw_image(gc, self.vertical_label, 0, 0, x+(self.H-self.label_height)/2, y+LABEL_PADDING_WIDTH, -1, -1)
00181                 #draw ports
00182                 map(lambda p: p.draw(window), self.get_ports())
00183 
00184         def what_is_selected(self, coor, coor_m=None):
00185                 """!
00186                 Get the element that is selected.
00187                 @param coor the (x,y) tuple
00188                 @param coor_m the (x_m, y_m) tuple
00189                 @return this block, a port, or None
00190                 """
00191                 for port in self.get_ports():
00192                         port_selected = port.what_is_selected(coor, coor_m)
00193                         if port_selected: return port_selected
00194                 return Element.what_is_selected(self, coor, coor_m)
00195 

Generated on Sat Aug 23 02:00:11 2008 for GNU Radio Companion by  doxygen 1.5.4