~ubuntu-branches/ubuntu/trusty/gnuradio/trusty

« back to all changes in this revision

Viewing changes to grc/gui/Block.py

  • Committer: Bazaar Package Importer
  • Author(s): Kamal Mostafa
  • Date: 2010-03-13 07:46:01 UTC
  • mfrom: (2.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20100313074601-zjsa893a87bozyh7
Tags: 3.2.2.dfsg-1ubuntu1
* Fix build for Ubuntu lucid (LP: #260406)
  - add binary package dep for libusrp0, libusrp2-0: adduser
  - debian/rules clean: remove pre-built Qt moc files

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""
 
2
Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
 
3
This file is part of GNU Radio
 
4
 
 
5
GNU Radio Companion is free software; you can redistribute it and/or
 
6
modify it under the terms of the GNU General Public License
 
7
as published by the Free Software Foundation; either version 2
 
8
of the License, or (at your option) any later version.
 
9
 
 
10
GNU Radio Companion is distributed in the hope that it will be useful,
 
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
GNU General Public License for more details.
 
14
 
 
15
You should have received a copy of the GNU General Public License
 
16
along with this program; if not, write to the Free Software
 
17
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 
18
"""
 
19
 
 
20
from Element import Element
 
21
import Utils
 
22
import Colors
 
23
from .. base import odict
 
24
from Constants import BORDER_PROXIMITY_SENSITIVITY
 
25
from Constants import \
 
26
        BLOCK_LABEL_PADDING, \
 
27
        PORT_SEPARATION, LABEL_SEPARATION, \
 
28
        PORT_BORDER_SEPARATION, POSSIBLE_ROTATIONS
 
29
import pygtk
 
30
pygtk.require('2.0')
 
31
import gtk
 
32
 
 
33
BLOCK_MARKUP_TMPL="""\
 
34
#set $foreground = $block.is_valid() and 'black' or 'red'
 
35
<span foreground="$foreground" font_desc="Sans 8"><b>$encode($block.get_name())</b></span>"""
 
36
 
 
37
class Block(Element):
 
38
        """The graphical signal block."""
 
39
 
 
40
        def __init__(self, *args, **kwargs):
 
41
                """
 
42
                Block contructor.
 
43
                Add graphics related params to the block.
 
44
                """
 
45
                #add the position param
 
46
                self._params['_coordinate'] = self.get_parent().get_parent().Param(
 
47
                        self,
 
48
                        odict({
 
49
                                'name': 'GUI Coordinate',
 
50
                                'key': '_coordinate',
 
51
                                'type': 'raw',
 
52
                                'value': '(0, 0)',
 
53
                                'hide': 'all',
 
54
                        })
 
55
                )
 
56
                self._params['_rotation'] = self.get_parent().get_parent().Param(
 
57
                        self,
 
58
                        odict({
 
59
                                'name': 'GUI Rotation',
 
60
                                'key': '_rotation',
 
61
                                'type': 'raw',
 
62
                                'value': '0',
 
63
                                'hide': 'all',
 
64
                        })
 
65
                )
 
66
                Element.__init__(self)
 
67
 
 
68
        def get_coordinate(self):
 
69
                """
 
70
                Get the coordinate from the position param.
 
71
                @return the coordinate tuple (x, y) or (0, 0) if failure
 
72
                """
 
73
                try: #should evaluate to tuple
 
74
                        coor = eval(self.get_param('_coordinate').get_value())
 
75
                        x, y = map(int, coor)
 
76
                        fgW,fgH = self.get_parent().get_size()
 
77
                        if x <= 0:
 
78
                                x = 0
 
79
                        elif x >= fgW - BORDER_PROXIMITY_SENSITIVITY:
 
80
                                x = fgW - BORDER_PROXIMITY_SENSITIVITY
 
81
                        if y <= 0:
 
82
                                y = 0
 
83
                        elif y >= fgH - BORDER_PROXIMITY_SENSITIVITY:
 
84
                                y = fgH - BORDER_PROXIMITY_SENSITIVITY
 
85
                        return (x, y)
 
86
                except:
 
87
                        self.set_coordinate((0, 0))
 
88
                        return (0, 0)
 
89
 
 
90
        def set_coordinate(self, coor):
 
91
                """
 
92
                Set the coordinate into the position param.
 
93
                @param coor the coordinate tuple (x, y)
 
94
                """
 
95
                self.get_param('_coordinate').set_value(str(coor))
 
96
 
 
97
        def get_rotation(self):
 
98
                """
 
99
                Get the rotation from the position param.
 
100
                @return the rotation in degrees or 0 if failure
 
101
                """
 
102
                try: #should evaluate to dict
 
103
                        rotation = eval(self.get_param('_rotation').get_value())
 
104
                        return int(rotation)
 
105
                except:
 
106
                        self.set_rotation(POSSIBLE_ROTATIONS[0])
 
107
                        return POSSIBLE_ROTATIONS[0]
 
108
 
 
109
        def set_rotation(self, rot):
 
110
                """
 
111
                Set the rotation into the position param.
 
112
                @param rot the rotation in degrees
 
113
                """
 
114
                self.get_param('_rotation').set_value(str(rot))
 
115
 
 
116
        def update(self):
 
117
                """Update the block, parameters, and ports when a change occurs."""
 
118
                self._bg_color = self.get_enabled() and Colors.BLOCK_ENABLED_COLOR or Colors.BLOCK_DISABLED_COLOR
 
119
                self.clear()
 
120
                self._create_labels()
 
121
                self.W = self.label_width + 2*BLOCK_LABEL_PADDING
 
122
                self.H = max(*(
 
123
                        [self.label_height+2*BLOCK_LABEL_PADDING] + [2*PORT_BORDER_SEPARATION + \
 
124
                        sum([port.H + PORT_SEPARATION for port in ports]) - PORT_SEPARATION
 
125
                        for ports in (self.get_sources(), self.get_sinks())]
 
126
                ))
 
127
                if self.is_horizontal(): self.add_area((0, 0), (self.W, self.H))
 
128
                elif self.is_vertical(): self.add_area((0, 0), (self.H, self.W))
 
129
                map(lambda p: p.update(), self.get_ports())
 
130
 
 
131
        def _create_labels(self):
 
132
                """Create the labels for the signal block."""
 
133
                layouts = list()
 
134
                #create the main layout
 
135
                layout = gtk.DrawingArea().create_pango_layout('')
 
136
                layouts.append(layout)
 
137
                layout.set_markup(Utils.parse_template(BLOCK_MARKUP_TMPL, block=self))
 
138
                self.label_width, self.label_height = layout.get_pixel_size()
 
139
                #display the params
 
140
                for param in filter(lambda p: p.get_hide() not in ('all', 'part'), self.get_params()):
 
141
                        layout = param.get_layout()
 
142
                        layouts.append(layout)
 
143
                        w,h = layout.get_pixel_size()
 
144
                        self.label_width = max(w, self.label_width)
 
145
                        self.label_height = self.label_height + h + LABEL_SEPARATION
 
146
                width = self.label_width
 
147
                height = self.label_height
 
148
                #setup the pixmap
 
149
                pixmap = self.get_parent().new_pixmap(width, height)
 
150
                gc = pixmap.new_gc()
 
151
                gc.set_foreground(self._bg_color)
 
152
                pixmap.draw_rectangle(gc, True, 0, 0, width, height)
 
153
                #draw the layouts
 
154
                h_off = 0
 
155
                for i,layout in enumerate(layouts):
 
156
                        w,h = layout.get_pixel_size()
 
157
                        if i == 0: w_off = (width-w)/2
 
158
                        else: w_off = 0
 
159
                        pixmap.draw_layout(gc, w_off, h_off, layout)
 
160
                        h_off = h + h_off + LABEL_SEPARATION
 
161
                #create vertical and horizontal images
 
162
                self.horizontal_label = image = pixmap.get_image(0, 0, width, height)
 
163
                if self.is_vertical():
 
164
                        self.vertical_label = vimage = gtk.gdk.Image(gtk.gdk.IMAGE_NORMAL, pixmap.get_visual(), height, width)
 
165
                        for i in range(width):
 
166
                                for j in range(height): vimage.put_pixel(j, width-i-1, image.get_pixel(i, j))
 
167
                map(lambda p: p._create_labels(), self.get_ports())
 
168
 
 
169
        def draw(self, gc, window):
 
170
                """
 
171
                Draw the signal block with label and inputs/outputs.
 
172
                @param gc the graphics context
 
173
                @param window the gtk window to draw on
 
174
                """
 
175
                x, y = self.get_coordinate()
 
176
                #draw main block
 
177
                Element.draw(
 
178
                        self, gc, window, bg_color=self._bg_color,
 
179
                        border_color=self.is_highlighted() and Colors.HIGHLIGHT_COLOR or Colors.BORDER_COLOR,
 
180
                )
 
181
                #draw label image
 
182
                if self.is_horizontal():
 
183
                        window.draw_image(gc, self.horizontal_label, 0, 0, x+BLOCK_LABEL_PADDING, y+(self.H-self.label_height)/2, -1, -1)
 
184
                elif self.is_vertical():
 
185
                        window.draw_image(gc, self.vertical_label, 0, 0, x+(self.H-self.label_height)/2, y+BLOCK_LABEL_PADDING, -1, -1)
 
186
                #draw ports
 
187
                for port in self.get_ports(): port.draw(gc, window)
 
188
 
 
189
        def what_is_selected(self, coor, coor_m=None):
 
190
                """
 
191
                Get the element that is selected.
 
192
                @param coor the (x,y) tuple
 
193
                @param coor_m the (x_m, y_m) tuple
 
194
                @return this block, a port, or None
 
195
                """
 
196
                for port in self.get_ports():
 
197
                        port_selected = port.what_is_selected(coor, coor_m)
 
198
                        if port_selected: return port_selected
 
199
                return Element.what_is_selected(self, coor, coor_m)