Package arcmap :: Module tilegrid
[hide private]
[frames] | no frames]

Source Code for Module arcmap.tilegrid

  1  ################################################################################ 
  2  # Authors: Brian Schott (Sir Alaran) 
  3  # Copyright: Brian Schott (Sir Alaran) 
  4  # Date: Sep 29 2009 
  5  # License: 
  6  # 
  7  # This program is free software: you can redistribute it and/or modify 
  8  # it under the terms of the GNU General Public License as published by 
  9  # the Free Software Foundation, either version 3 of the License, or 
 10  # (at your option) any later version. 
 11  # 
 12  # This program is distributed in the hope that it will be useful, 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
 15  # GNU General Public License for more details. 
 16  # 
 17  # You should have received a copy of the GNU General Public License 
 18  # along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 19  ################################################################################ 
 20   
 21   
 22  """ 
 23  Contains the TileGrid class 
 24  """ 
 25   
 26   
 27  __docformat__ = "epytext" 
 28   
 29  import logging 
 30  import gtk 
 31  import cairo 
 32  import preferences 
 33  import mapcontroller 
 34  import graphics 
 35   
36 -class TileGrid(gtk.DrawingArea):
37 """ 38 Base class for MapGrid and TilePalette. Handles functionality common 39 to both such as drawing grids, handling mouse events, etc 40 """ 41 __gsignals__ = {"expose-event": "override"} 42
43 - def __init__(self, width, height, tileSize):
44 gtk.DrawingArea.__init__(self) 45 46 self.__showGrid = False 47 self.__scaleFactor = 1.0 48 self.__zoomLevel = preferences.zoomNormalIndex 49 self.__tileSize = tileSize 50 self.__tools = [] 51 self.__selectedTool = 0 52 self.__width = 0 53 self.__height = 0 54 self.__checkerPattern = graphics.getCheckerPattern(tileSize) 55 56 # DrawingArea can't get events of its own for whatever reason. 57 # Sticking it in an EventBox works around this 58 self.eventBox = gtk.EventBox() 59 self.eventBox.connect("button-press-event", self.buttonPress) 60 self.eventBox.connect("button-release-event", self.buttonRelease) 61 self.eventBox.connect("motion-notify-event", self.mouseMotion) 62 self.eventBox.connect("leave-notify-event", self.mouseLeave) 63 self.eventBox.connect("enter-notify-event", self.mouseEnter) 64 self.eventBox.connect("key-press-event", self.keyPress) 65 self.eventBox.add(self) 66 67 self.eventBox.set_events(gtk.gdk.POINTER_MOTION_MASK | 68 gtk.gdk.POINTER_MOTION_HINT_MASK | 69 gtk.gdk.BUTTON_PRESS_MASK | 70 gtk.gdk.KEY_PRESS_MASK | 71 gtk.gdk.BUTTON_RELEASE_MASK | 72 gtk.gdk.LEAVE_NOTIFY_MASK | 73 gtk.gdk.ENTER_NOTIFY_MASK) 74 self.eventBox.show_all() 75 76 self.setSize(width, height, 0, 0)
77
78 - def setSize(self, width, height, ignored1, ignored2):
79 """ 80 Sets the size of the tile grid 81 @type width: int 82 @param width: width of the grid in pixels 83 @type height: int 84 @param height: height of the grid in pixels 85 """ 86 self.drawBuffer = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) 87 self.__width = width 88 self.__height = height 89 self.set_size_request(self.__width, self.__height)
90
91 - def getWidget(self):
92 return self.eventBox
93
94 - def do_expose_event(self, event):
95 windowContext = self.window.cairo_create() 96 windowContext.rectangle(event.area.x, event.area.y, event.area.width, 97 event.area.height) 98 windowContext.clip() 99 windowContext.scale(self.__scaleFactor, self.__scaleFactor) 100 windowContext.set_source_surface(self.drawBuffer, 0, 0) 101 windowContext.paint()
102
103 - def addTool(self, tool, toolID):
104 while len(self.__tools) < toolID + 1: 105 self.__tools.append(None) 106 self.__tools[toolID] = tool
107
108 - def toolSelect(self, toolID):
109 self.__selectedTool = toolID
110
111 - def getToolInstructions(self):
112 return self.__tools[self.__selectedTool].getInstructions()
113
114 - def buttonPress(self, widget, event):
115 if len(self.__tools) > 0: 116 r = self.__tools[self.__selectedTool].mouseButtonPress(event.button, 117 event.time) 118 if r: 119 self.redrawBuffer() 120 self.queue_draw()
121
122 - def buttonRelease(self, widget, event):
123 if len(self.__tools) > 0: 124 r = self.__tools[self.__selectedTool].mouseButtonRelease( 125 event.button, event.time) 126 if r: 127 self.redrawBuffer() 128 self.queue_draw()
129
130 - def mouseMotion(self, widget, event):
131 x, y = self.__translateCoords(event.x, event.y) 132 if len(self.__tools) > 0: 133 r = self.__tools[self.__selectedTool].mouseMotion(x, y) 134 if r: 135 self.redrawBuffer() 136 self.queue_draw()
137
138 - def mouseEnter(self, widget, event):
139 r = self.__tools[self.__selectedTool].mouseEnter() 140 if r: 141 self.redrawBuffer() 142 self.queue_draw()
143
144 - def mouseLeave(self, widget, event):
145 r = self.__tools[self.__selectedTool].mouseLeave() 146 if r: 147 self.redrawBuffer() 148 self.queue_draw()
149 150
151 - def keyPress(self, widget, event):
152 if len(self.__tools) > 0: 153 r = self.__tools[self.__selectedTool].keyPress(event.keyval) 154 if r: 155 self.redrawBuffer() 156 self.queue_draw()
157
158 - def __validateZoom(self):
159 self.__zoomLevel = min(max(self.__zoomLevel, 0), 160 len(preferences.zoomLevels) - 1)
161
162 - def zoomIn(self):
163 """ 164 Zoom in 165 """ 166 self.__zoomLevel += 1 167 self.__setZoom()
168
169 - def zoomOut(self):
170 """ 171 Zooms out 172 """ 173 self.__zoomLevel -= 1 174 self.__setZoom()
175
176 - def zoomNormal(self):
177 """ 178 Reset the zoom level to 100% 179 """ 180 self.__zoomLevel = preferences.zoomNormalIndex 181 self.__setZoom()
182
183 - def __setZoom(self):
184 """ Set the zoom level""" 185 self.__validateZoom() 186 self.__scaleFactor = preferences.zoomLevels[self.__zoomLevel] 187 188 # This looks redundant, but it's necessary for the scrolledwindow to 189 # actualy update 190 self.window.resize(int(self.__width * self.__scaleFactor), 191 int(self.__height * self.__scaleFactor)) 192 self.set_size_request(int(self.__width * self.__scaleFactor), 193 int(self.__height * self.__scaleFactor)) 194 self.redrawBuffer() 195 self.queue_draw()
196
197 - def getZoom(self):
198 return self.__scaleFactor
199
200 - def specialRedraw(self, context):
201 """ Override this in derived classes """ 202 pass
203
204 - def getThumbnail(self, largest):
205 """ 206 @type largest: int 207 @param largest: the largest of the dimentions of the returned image 208 """ 209 w = self.drawBuffer.get_width() 210 h = self.drawBuffer.get_height() 211 s = 1.0 212 if w > h: 213 s = float(largest) / float(w) 214 else: 215 s = float(largest) / float(h) 216 result = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(w * s), int(h * s)) 217 context = cairo.Context(result) 218 context.scale(s, s) 219 self.specialRedraw(context) 220 return result
221
222 - def __drawGrid(self, context):
223 """ Draw a grid with cells the same size as tiles on a cairo context """ 224 context.set_source_rgba(0.0, 0.0, 0.0, 1.0) 225 context.set_dash((4, 2)) 226 context.set_line_width(1) 227 width = self.drawBuffer.get_width() 228 height = self.drawBuffer.get_height() 229 for i in range(width // self.__tileSize): 230 context.move_to(i * self.__tileSize + .5 , 0) 231 context.line_to(i * self.__tileSize + .5, height) 232 context.stroke() 233 for i in range(height // self.__tileSize): 234 context.move_to(0, i * self.__tileSize + .5) 235 context.line_to(width, i * self.__tileSize + .5) 236 context.stroke()
237
238 - def __translateCoords(self, x, y):
239 """ 240 Translates the coordinates x and y based on the zoom level given in sf 241 For example, at a zoom level of 2 an x-coordinate of 50 screen pixels 242 would actually be at 25 map pixels. 243 """ 244 sfinverse = 1.0 / self.__scaleFactor 245 return round(x * sfinverse), round(y * sfinverse)
246 247
248 - def redrawBuffer(self):
249 """ Updates self.drawBuffer """ 250 context = cairo.Context(self.drawBuffer) 251 context.set_source(self.__checkerPattern) 252 context.paint() 253 self.specialRedraw(context) 254 if len(self.__tools) > 0: 255 self.__tools[self.__selectedTool].draw(context) 256 if self.__showGrid == True: 257 graphics.drawGrid(context, self.__tileSize, 258 self.drawBuffer.get_width(), self.drawBuffer.get_height())
259
260 - def toggleGrid(self):
261 """ Turns the grid on or off """ 262 self.__showGrid = not self.__showGrid 263 self.redrawBuffer() 264 self.queue_draw()
265