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
00020
00021
00022
00023 import pygtk
00024 pygtk.require('2.0')
00025 import gtk
00026 from grc.Constants import *
00027
00028 class DrawingArea(gtk.DrawingArea):
00029 """
00030 DrawingArea is the gtk pixel map that graphical elements may draw themselves on.
00031 The drawing area also responds to mouse and key events.
00032 """
00033
00034 def __init__(self, main_window):
00035 """!
00036 DrawingArea contructor.
00037 Connect event handlers.
00038 @param main_window the main_window containing all flow graphs
00039 """
00040 self.ctrl_mask = False
00041 self._main_window = main_window
00042
00043 self._main_window.drawing_area = self
00044 gtk.DrawingArea.__init__(self)
00045 self.set_size_request(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT)
00046 self.connect('expose-event', self._handle_window_expose)
00047 self.connect('motion-notify-event', self._handle_mouse_motion)
00048 self.connect('button-press-event', self._handle_mouse_button_press)
00049 self.connect('button-release-event', self._handle_mouse_button_release)
00050 self.set_events(
00051 gtk.gdk.BUTTON_PRESS_MASK | \
00052 gtk.gdk.POINTER_MOTION_MASK | \
00053 gtk.gdk.BUTTON_RELEASE_MASK | \
00054 gtk.gdk.LEAVE_NOTIFY_MASK | \
00055 gtk.gdk.ENTER_NOTIFY_MASK
00056 )
00057
00058 self._focus_flag = False
00059 self.get_focus_flag = lambda: self._focus_flag
00060 self.connect("leave-notify-event", self._handle_focus_event, False)
00061 self.connect("enter-notify-event", self._handle_focus_event, True)
00062
00063 self.pixmap = None
00064 self.gc = None
00065
00066 def draw(self):
00067 """!
00068 Draw the pixmap onto this drawing area.
00069 """
00070 self.window.draw_drawable(self.gc, self.pixmap, 0, 0, 0, 0, -1, -1)
00071
00072
00073
00074
00075 def _handle_focus_event(self, widget, event, focus_flag):
00076 """Record the focus state of the flow graph window."""
00077 self._focus_flag = focus_flag
00078
00079 def _handle_mouse_button_press(self, widget, event):
00080 """!
00081 Forward button click information to the flow graph.
00082 """
00083 self.ctrl_mask = event.state & gtk.gdk.CONTROL_MASK
00084 self._main_window.get_flow_graph().handle_mouse_button_press(
00085 left_click=(event.button == 1),
00086 double_click=(event.type == gtk.gdk._2BUTTON_PRESS),
00087 coordinate=(event.x, event.y),
00088 )
00089 return True
00090
00091 def _handle_mouse_button_release(self, widget, event):
00092 """!
00093 Forward button release information to the flow graph.
00094 """
00095 self.ctrl_mask = event.state & gtk.gdk.CONTROL_MASK
00096 self._main_window.get_flow_graph().handle_mouse_button_release(
00097 left_click=(event.button == 1),
00098 coordinate=(event.x, event.y),
00099 )
00100 return True
00101
00102 def _handle_mouse_motion(self, widget, event):
00103 """!
00104 Forward mouse motion information to the flow graph.
00105 """
00106 self.ctrl_mask = event.state & gtk.gdk.CONTROL_MASK
00107 self._main_window.get_flow_graph().handle_mouse_motion(
00108 coordinate=(event.x, event.y),
00109 )
00110 return True
00111
00112 def _handle_window_expose(self, widget, event):
00113 """!
00114 Called when the window initially appears or is resized: create a new pixmap, draw the flow graph.
00115 """
00116 self.gc = self.window.new_gc()
00117 width, height = self.get_size_request()
00118 if not self.pixmap or (width, height) != self.pixmap.get_size():
00119 self.pixmap = gtk.gdk.Pixmap(self.window, width, height, -1)
00120 self._main_window.get_flow_graph().draw()
00121 return True