1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
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
57
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
93
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
107
110
113
121
129
137
139 r = self.__tools[self.__selectedTool].mouseEnter()
140 if r:
141 self.redrawBuffer()
142 self.queue_draw()
143
145 r = self.__tools[self.__selectedTool].mouseLeave()
146 if r:
147 self.redrawBuffer()
148 self.queue_draw()
149
150
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
161
163 """
164 Zoom in
165 """
166 self.__zoomLevel += 1
167 self.__setZoom()
168
170 """
171 Zooms out
172 """
173 self.__zoomLevel -= 1
174 self.__setZoom()
175
182
184 """ Set the zoom level"""
185 self.__validateZoom()
186 self.__scaleFactor = preferences.zoomLevels[self.__zoomLevel]
187
188
189
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
198 return self.__scaleFactor
199
201 """ Override this in derived classes """
202 pass
203
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
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
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
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
261 """ Turns the grid on or off """
262 self.__showGrid = not self.__showGrid
263 self.redrawBuffer()
264 self.queue_draw()
265