1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 __maintainer__ = 'Florian Boucault <florian@fluendo.com>'
19
20
21 from elisa.core.observers.list import ListObserver
22 from elisa.core.media_manager import MediaProviderNotFound
23 from elisa.core import common
24
25 from twisted.internet import reactor, defer
26
27 plugin_registry = common.application.plugin_registry
28 PigmentView = plugin_registry.get_component_class('pigment:pigment_view')
29
30
31 import os, cairo, math, array, pgm
32
33 -class ListView(PigmentView, ListObserver):
68
71
74
84
86 raise NotImplementedError
87
101
102 - def removed(self, elements, position):
103 self.debug("removed %r elements from %r: %r", len(elements), position,
104 elements)
105 for i in xrange(len(elements)):
106 try:
107 self.pop(position)
108 except IndexError:
109 break
110
113
115 self.debug("all the elements changed")
116
118 self.debug("attribute %r of element at %r set to %r", key, position,
119 new_value)
120
137
139
140
141 def display(result):
142 image_path = result[0]
143 image.set_from_file(image_path)
144 image.set_name(image_path)
145 return image_path
146
147 def error(error):
148
149 self.info(error)
150 if self.frontend:
151 return self.frontend.theme.get_media('unknown_icon')
152
153 dfr = self._get_path_from_thumbnailer(uri)
154 dfr.addErrback(error)
155 dfr.addCallback(display)
156 return dfr
157
168
169 dfr.addCallback(got_media_type)
170 return dfr
171
172
188
190
191 if not it_is:
192
193 return
194
195 smalling = 0.7
196 canvas = self.frontend.context.viewport_handle.get_canvas()
197 media_manager = common.application.media_manager
198 list_of_images = []
199
200 def create_stack():
201 if len(list_of_images) == 0:
202 return
203
204 size = 450
205 data = array.array('c', chr(0) * size * size * 4)
206 dest_surface = cairo.ImageSurface.create_for_data(data, cairo.FORMAT_ARGB32,
207 size,
208 size,
209 size * 4)
210
211 ctx = cairo.Context(dest_surface)
212
213 degrees = math.pi / 180.0 * 15.0
214
215 list_of_images.reverse()
216
217
218 ctx.translate(size/2, size/2)
219 ctx.scale(1.3, 1.3)
220 ctx.rotate(-degrees * len(list_of_images))
221 ctx.translate(-size/2, -size/2)
222
223 for path in list_of_images:
224 path = path[0]
225
226 image_surface = cairo.ImageSurface.create_from_png(path)
227 width = image_surface.get_width()
228 height = image_surface.get_height()
229
230
231 left_offset = ((size - width) / 2)
232 top_offset = ((size - height) / 2)
233 ctx.translate(left_offset, top_offset)
234
235
236 ctx.translate(width / 2, height / 2)
237 ctx.rotate(degrees)
238 ctx.translate(-width / 2, -height / 2)
239 ctx.set_source_surface(image_surface)
240 ctx.paint()
241
242
243 ctx.rectangle(0, 0, width, height)
244 ctx.set_line_width(5.0)
245 ctx.set_source_rgb(255, 255, 255)
246 ctx.stroke()
247
248
249 ctx.translate(-left_offset, -top_offset)
250
251 ctx.save()
252
253
254 image.set_from_buffer(pgm.IMAGE_BGRA, size, size, size*4,
255 size*size*4, data.tostring())
256
257 image.opacity = 255
258 image.bg_color = (0, 0, 0, 0)
259 image.visible = True
260
261 if reflection is not None:
262
263 ref_data = array.array('c', chr(0) * size * size * 4)
264 dest_surface = cairo.ImageSurface.create_for_data(ref_data,
265 cairo.FORMAT_ARGB32,
266 size,
267 size,
268 size * 4)
269 source = cairo.ImageSurface.create_for_data(data,
270 cairo.FORMAT_ARGB32,
271 size,
272 size,
273 size * 4)
274
275
276 context = cairo.Context(dest_surface)
277 context.set_source_surface(source)
278
279 context.scale(size, size)
280
281 gradient = cairo.LinearGradient(0.0, 0.0, 0.0, 1.0)
282 gradient.add_color_stop_rgba(stop_gradient, 0, 0, 0, 0)
283 gradient.add_color_stop_rgba(1, 0, 0, 0, 1)
284
285 context.mask(gradient)
286
287 reflection.set_from_buffer(pgm.IMAGE_BGRA, size, size, size*4,
288 size*size*4, ref_data.tostring())
289
290
291 def image_created(image_path, list_of_children):
292 if image_path is None:
293 process_next_child(list_of_children)
294 return
295
296 if not os.path.isfile(image_path[0]):
297 process_next_child(list_of_children)
298 return
299
300 list_of_images.append(image_path)
301 if len(list_of_images) == self.images_per_stack \
302 or len(list_of_children) == 0:
303 self.debug("creating stack")
304 create_stack()
305 else:
306 process_next_child(list_of_children)
307
308 def error(failure, pending_children):
309 self.info("Got an error:%s" % failure)
310 process_next_child(pending_children)
311
312 def process_next_child(pending_children):
313 if len(pending_children) == 0:
314 return
315
316 uri, metadata = pending_children.pop(0)
317 self.info("Looking for thumbnail for %s" % uri)
318
319 dfr = self._get_path_from_thumbnailer(uri)
320 dfr.addCallback(image_created, pending_children)
321 dfr.addErrback(error, pending_children)
322
323 lst = []
324 dfr = media_manager.get_direct_children(uri, lst)
325 dfr.addCallback(process_next_child)
326