Merged r9481:9518 on jblum/grc_reorganize into trunk. Reorganized grc source under...
[debian/gnuradio] / grc / src / gui / DrawingArea.py
1 """
2 Copyright 2007 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 import pygtk
21 pygtk.require('2.0')
22 import gtk
23 from Constants import MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT
24
25 class DrawingArea(gtk.DrawingArea):
26         """
27         DrawingArea is the gtk pixel map that graphical elements may draw themselves on.
28         The drawing area also responds to mouse and key events.
29         """
30
31         def __init__(self, main_window):
32                 """
33                 DrawingArea contructor.
34                 Connect event handlers.
35                 @param main_window the main_window containing all flow graphs
36                 """
37                 self.ctrl_mask = False
38                 self._main_window = main_window
39                 #inject drawing area into main_window
40                 self._main_window.drawing_area = self
41                 gtk.DrawingArea.__init__(self)
42                 self.set_size_request(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT)
43                 self.connect('expose-event', self._handle_window_expose)
44                 self.connect('motion-notify-event', self._handle_mouse_motion)
45                 self.connect('button-press-event', self._handle_mouse_button_press)
46                 self.connect('button-release-event', self._handle_mouse_button_release)
47                 self.set_events(
48                         gtk.gdk.BUTTON_PRESS_MASK | \
49                         gtk.gdk.POINTER_MOTION_MASK | \
50                         gtk.gdk.BUTTON_RELEASE_MASK | \
51                         gtk.gdk.LEAVE_NOTIFY_MASK | \
52                         gtk.gdk.ENTER_NOTIFY_MASK
53                 )
54                 #setup the focus flag
55                 self._focus_flag = False
56                 self.get_focus_flag = lambda: self._focus_flag
57                 self.connect("leave-notify-event", self._handle_focus_event, False)
58                 self.connect("enter-notify-event", self._handle_focus_event, True)
59                 #pixmap for drawing
60                 self.pixmap = None
61                 self.gc = None
62
63         def draw(self):
64                 """
65                 Draw the pixmap onto this drawing area.
66                 """
67                 self.window.draw_drawable(self.gc, self.pixmap, 0, 0, 0, 0, -1, -1)
68
69         ##########################################################################
70         ## Handlers
71         ##########################################################################
72         def _handle_focus_event(self, widget, event, focus_flag):
73                 """Record the focus state of the flow graph window."""
74                 self._focus_flag = focus_flag
75
76         def _handle_mouse_button_press(self, widget, event):
77                 """
78                 Forward button click information to the flow graph.
79                 """
80                 self.ctrl_mask = event.state & gtk.gdk.CONTROL_MASK
81                 self._main_window.get_flow_graph().handle_mouse_button_press(
82                         left_click=(event.button == 1),
83                         double_click=(event.type == gtk.gdk._2BUTTON_PRESS),
84                         coordinate=(event.x, event.y),
85                 )
86                 return True
87
88         def _handle_mouse_button_release(self, widget, event):
89                 """
90                 Forward button release information to the flow graph.
91                 """
92                 self.ctrl_mask = event.state & gtk.gdk.CONTROL_MASK
93                 self._main_window.get_flow_graph().handle_mouse_button_release(
94                         left_click=(event.button == 1),
95                         coordinate=(event.x, event.y),
96                 )
97                 return True
98
99         def _handle_mouse_motion(self, widget, event):
100                 """
101                 Forward mouse motion information to the flow graph.
102                 """
103                 self.ctrl_mask = event.state & gtk.gdk.CONTROL_MASK
104                 self._main_window.get_flow_graph().handle_mouse_motion(
105                         coordinate=(event.x, event.y),
106                 )
107                 return True
108
109         def _handle_window_expose(self, widget, event):
110                 """
111                 Called when the window initially appears or is resized: create a new pixmap, draw the flow graph.
112                 """
113                 self.gc = self.window.new_gc()
114                 width, height = self.get_size_request()
115                 if not self.pixmap or (width, height) != self.pixmap.get_size():
116                         self.pixmap = gtk.gdk.Pixmap(self.window, width, height, -1)
117                 self._main_window.get_flow_graph().draw()
118                 return True