1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """
23 Contains custom widget for previewing parallax backgrounds.
24 """
25
26 import gtk
27 import cairo
28
29 import graphics
30 import tilemap
31
33 """
34 Widget for drawing parallax backgrounds to the screen
35 """
36
37 __gsignals__ = {"expose-event": "override"}
38
39 - def __init__(self, width, height, scale):
40 """
41 @type width: int
42 @param width: width of preview in pixels
43 @type height: int
44 @param height: height of preview in pixels
45 @type scale: int
46 @param scale: scale factor for the preview.
47 """
48 gtk.DrawingArea.__init__(self)
49
50 self.__layers = []
51
52 self.__backgrounds = []
53
54 self.__x = 0
55
56 self.__y = 0
57
58 self.__width = width
59
60 self.__height = height
61
62 self.__scaleFactor = scale
63
64 self.__drawBuffer = cairo.ImageSurface(cairo.FORMAT_ARGB32, width,
65 height)
66
67 self.__backColor = graphics.RGBA(0.0, 0.0, 0.0, 1.0)
68
69 self.set_size_request(int(self.__width * self.__scaleFactor),
70 int(self.__height * self.__scaleFactor))
71 self.__redrawBuffer()
72
74 windowContext = self.window.cairo_create()
75 windowContext.rectangle(event.area.x, event.area.y, event.area.width,
76 event.area.height)
77 windowContext.clip()
78 windowContext.scale(self.__scaleFactor, self.__scaleFactor)
79 windowContext.set_source_surface(self.__drawBuffer)
80 windowContext.paint()
81
83 """
84 Adds a background to the preview
85 @type parallax: tilemap.Parallax
86 @param parallax: the background to add
87 """
88 self.__layers.append(graphics.loadImage(parallax.fileName))
89 self.__backgrounds.append(parallax)
90 self.__redrawBuffer()
91 self.queue_draw()
92
94 """
95 @type x: int
96 @param x: the new x-coordinate for the preview
97 """
98 self.__x = x
99 self.__redrawBuffer()
100 self.queue_draw()
101
103 """
104 @type y: int
105 @param y: the y-coordinate for the preview
106 """
107 self.__y = y
108 self.__redrawBuffer()
109 self.queue_draw()
110
112 """
113 @type color: graphics.RGBA
114 @param color: the color to draw on the background below all the other
115 layers
116 """
117 self.__backColor = color
118 self.__redrawBuffer()
119 self.queue_draw()
120
122 """
123 @type width: int
124 @param width: the new width of the preview
125 """
126 self.__width = width
127 self.__sizeChanged()
128
130 """
131 @type height: int
132 @param height: the new height of the preview
133 """
134 self.__height = height
135 self.__sizeChanged()
136
138 """
139 @type scale: float
140 @param scale: the new scale factor for the preview
141 """
142 self.__scaleFactor = scale
143 self.__sizeChanged()
144
146 """
147 @type index: int
148 @param index: index of the layer to set (in)visible
149 @type vis: bool
150 @param vis: True to set the layer visible, False to set invisible
151 """
152 self.__backgrounds[index].visible = vis
153 self.__redrawBuffer()
154 self.queue_draw()
155
157 """
158 Swaps two layers in the display order
159 @type index1: int
160 @param index1: the first layer
161 @type index2: int
162 @param index2: the second layer
163 """
164 tb = self.__backgrounds[index1]
165 self.__backgrounds[index1] = self.__backgrounds[index2]
166 self.__backgrounds[index2] = tb
167
168 tl = self.__layers[index1]
169 self.__layers[index1] = self.__layers[index2]
170 self.__layers[index2] = tl
171
172 self.__redrawBuffer()
173 self.queue_draw()
174
176 """
177 @type index: int
178 @param index: the index of the layer to delete
179 """
180 del self.__backgrounds[index]
181 del self.__layers[index]
182 self.__redrawBuffer()
183 self.queue_draw()
184
186 """
187 Called to recalculate things when the size of the widget changes
188 """
189 self.set_size_request(int(self.__width * self.__scaleFactor),
190 int(self.__height * self.__scaleFactor))
191 self.__drawBuffer = cairo.ImageSurface(cairo.FORMAT_ARGB32,
192 self.__width, self.__height)
193 self.__redrawBuffer()
194 self.queue_draw()
195
197 """
198 Redraws the window
199 """
200 context = cairo.Context(self.__drawBuffer)
201 self.__backColor.contextColor(context)
202 context.paint()
203 for index, layerSurface in enumerate(self.__layers):
204 back = self.__backgrounds[index]
205 if back.visible == False:
206 continue
207
208 def calcBaseTimes(coord, scroll, scrollSpeed, tile, dimention,
209 viewDimention):
210 if scroll == True:
211 coord = int(coord * scrollSpeed)
212 else:
213 coord = 0
214 if tile == True:
215 if coord > 0:
216 coord = -(coord % dimention)
217 else:
218 coord = -coord % dimention
219 times = (viewDimention // dimention) + 2
220 else:
221 times = 1
222 return coord, times
223
224 x, xTimes = calcBaseTimes(self.__x, back.hScroll, back.hScrollSpeed,
225 back.hTile, layerSurface.get_width(), self.__width)
226 y, yTimes = calcBaseTimes(-self.__y, back.vScroll,
227 back.vScrollSpeed, back.vTile, layerSurface.get_height(),
228 self.__height)
229
230 for i in range(xTimes):
231 if x <= 0:
232 dstX = x + (layerSurface.get_width() * i)
233 else:
234 if self.__width > layerSurface.get_width():
235 dstX = x + (layerSurface.get_width() * -(i - 1))
236 else:
237 dstX = x + (layerSurface.get_width() * -i)
238 for j in range(yTimes):
239 if y <= 0:
240 dstY = y + (layerSurface.get_height() * j)
241 else:
242 if self.__height > layerSurface.get_height():
243 dstY = y + (layerSurface.get_height() * -(j - 1))
244 else:
245 dstY = y + (layerSurface.get_height() * -j)
246 context.set_source_surface(layerSurface, dstX, dstY)
247 context.rectangle(dstX, dstY, layerSurface.get_width(),
248 layerSurface.get_height())
249 context.fill()
250