1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import math
23
24 import pgm
25 from pgm.graph.group import Group
26 from pgm.graph.image import Image
27 from pgm.timing import implicit
28
29 from twisted.internet import reactor
30
32 """
33 Widget providing facilities for displaying a temporary quickly loaded
34 image while a bigger one is being loaded.
35
36 Display L{quick_image} and then L{image} when it is finished loading.
37
38 Also supports a rotating image on top to notify loadings.
39
40 @ivar image: image that can take time to load
41 @type image: L{pgm.graph.image.Image}
42 @ivar quick_image: image quick to load
43 @type quick_image: L{pgm.graph.image.Image}
44 @ivar loading: DOCME
45 @type loading: bool
46 @ivar loading_image_path: DOCME
47 @type loading_image_path: str
48
49 @cvar time_before_quick: DOCME
50 @type time_before_quick: float
51 @cvar time_before_loading: DOCME
52 @type time_before_loading: float
53 """
54
55 time_before_quick = 0.250
56 time_before_loading = 0.250
57
59 Group.__init__(self)
60
61
62 self._image = Image()
63 self.add(self._image)
64 self._image.bg_color = (0, 0, 0, 0)
65 self._image.opacity = 0
66 self._image.layout = pgm.IMAGE_SCALED
67 self._image.visible = False
68 self._image.connect("pixbuf-loaded", self._image_loaded)
69
70 settings = {'duration': 300,
71 'transformation': implicit.SMOOTH,
72 'end_callback' : lambda c: self._hide_quick_image()
73 }
74
75 attributes = ('opacity',)
76 self._animated_image = implicit.AnimatedObject(self._image, attributes)
77 self._animated_image.setup_next_animations(**settings)
78
79
80 self._quick_image = None
81 self._quick_image_call = None
82
83
84 self._loading = False
85 self._loading_image = None
86 self._loading_image_path = None
87 self._loading_call = None
88 self._rotation_matrix = None
89 self._rotation_call = None
90
93
95
96 if self._quick_image_call != None and self._quick_image_call.active():
97 self._quick_image_call.cancel()
98
99
100 self._animated_image.stop_animations()
101 self._image.opacity = 0
102 self._image.visible = True
103 self._animated_image.opacity = 255
104
106
107 if self._quick_image == None:
108 self._quick_image = Image()
109 self._quick_image.size = self.size
110 self.add(self._quick_image)
111 self._quick_image.z -= 0.001
112 self._quick_image.bg_color = (0, 0, 0, 0)
113 self._quick_image.layout = pgm.IMAGE_SCALED
114 self._quick_image.visible = False
115 self._quick_image.connect("pixbuf-loaded", self._quick_image_loaded)
116
125
127
128 if self._quick_image_call != None and self._quick_image_call.active():
129 self._quick_image_call.cancel()
130
131 self._quick_image_call = reactor.callLater(self.time_before_quick,
132 self._show_quick_image)
133
135 if self._quick_image != None:
136 self._quick_image.opacity = 255
137 self._quick_image.visible = True
138
140 if self._quick_image != None:
141 self._quick_image.visible = False
142 self.remove(self._quick_image)
143 self._quick_image = None
144
146 self._loading_image_path = path
147 if self._loading_image != None:
148 self._loading_image.set_from_file(path)
149
151
152 if self._loading_image == None:
153 self._loading_image = Image()
154 self._loading_image.size = self.size
155 self.add(self._loading_image)
156 self._loading_image.bg_color = (0, 0, 0, 0)
157 self._loading_image.layout = pgm.IMAGE_SCALED
158 self._loading_image.visible = False
159
160 self._rotation_matrix = pgm.mat4x4_new_identity()
161 self._rotation_matrix.translate(0.5, 0.5, 0.0)
162 self._rotation_matrix.rotate_z(math.pi / 30.0)
163 self._rotation_matrix.translate(-0.5, -0.5, 0.0)
164 if self._loading_image_path:
165 self._loading_image.set_from_file(self._loading_image_path)
166
168 self._loading = loading
169
170
171 if self._loading_call != None and self._loading_call.active():
172 self._loading_call.cancel()
173
174 if loading == True:
175 self._loading_call = reactor.callLater(self.time_before_loading,
176 self._start_loading_animation)
177 else:
178
179 if self._loading_call != None and self._loading_call.active():
180 self._rotation_call.cancel()
181
182 if self._loading_image != None:
183 self.remove(self._loading_image)
184 self._loading_image = None
185
188
190 if self._loading_image_path != None:
191 if self._loading_image == None:
192 self._create_loading_image()
193 self._loading_image.visible = self.loading
194
195
196 if self._loading_call == None or not self._loading_call.active():
197 self._rotation_call = reactor.callLater(0.017,
198 self._rotate_loading)
199
201 if self._loading_image:
202 self._loading_image.mapping_matrix *= self._rotation_matrix
203 if self._loading:
204 self._rotation_call = reactor.callLater(0.017,
205 self._rotate_loading)
206