1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 __maintainer__ = 'Lionel Martin <lionel@fluendo.com>'
19 __maintainer2__ = 'Florian Boucault <florian@fluendo.com>'
20
21
22 from elisa.base_components.context import Context
23 from elisa.core.utils import signal
24
25 import pgm
26 import os
27
28 from twisted.internet import reactor
29
30 -class PigmentContext(Context):
31 """
32 Context based on Pigment. Creates a Pigment viewport and associates a
33 Pigment canvas to it. It takes care of the viewport resizes and
34 subsequent regenerations.
35
36 @ivar master_drawables: dictionary of master drawables used for improved
37 theme management based on Pigment cloning
38 keys: theme icons
39 values: master drawables
40 @type master_drawables: dictionary
41 """
42
43 default_config = {'screen_ratio' : 'auto',
44 'window_width': '0',
45 'touchscreen': '0',
46 'use_gtk': '0'}
47 config_doc = {'screen_ratio' : 'The ratio of the screen. This is a string'
48 ' containing a relation value, separated'
49 ' by a colon (:). Common values are 16:9,'
50 ' 4:3, 16:10, but it could be any other,'
51 ' too. You can have special values : mm,'
52 ' based on screen size in milimeters,'
53 ' sr, based on window manager resolution,'
54 ' or auto. auto will use mm special value.',
55 'window_width' : 'Here you can set the width in pixels the'
56 ' window should have at startup. The height'
57 ' is computed using screen_ratio.'
58 ' If this value is 0, we decide'
59 ' automatically.',
60 'touchscreen' : 'If set to 1, the mouse behaviour will be'
61 ' adapted for touchscreen equipped hardware.'
62 }
63
64 master_drawables = {}
65
66 - def initialize(self):
67 Context.initialize(self)
68
69
70 self._signal_handler_ids = []
71
72 config_screen_ratio = self.config.get('screen_ratio', 'auto')
73
74 self.touchscreen = self.config.get('touchscreen', '1') == '1'
75 try:
76
77 self._compiz_check()
78 except:
79 pass
80
81
82
83
84 import pgm
85
86
87 factory = pgm.ViewportFactory('opengl')
88 viewport = factory.create()
89
90 self.viewport_handle = viewport
91 viewport.title = 'Elisa Media Center'
92 self._window_managet_screen_size_mm = viewport.screen_size_mm
93
94
95 self.canvas = pgm.Canvas()
96
97 try:
98 width = int(self.config.get('window_width', '0'))
99 if width != 0:
100 viewport.width = width
101 except Exception, e:
102 self.warning("The configuration value of window_width seems to be"
103 " no number value in pixels: %s" % e)
104
105
106 self._resize_delay = 0.200
107 self._resize_delayed = None
108 self.canvas_resized = signal.Signal('canvas_resized', tuple)
109 self.aspect_ratio_changed(None, config_screen_ratio)
110
111
112 viewport.set_canvas(self.canvas)
113
114 use_gtk = self.config.get('use_gtk',
115 self.default_config.get('use_gtk')) == '1'
116 if use_gtk:
117 import gtk
118 import pgm.gtk
119 self.gtk_window = gtk.Window(gtk.WINDOW_TOPLEVEL)
120 id = self.gtk_window.connect('delete-event',
121 self._gtk_window_delete_event_cb)
122 self._signal_handler_ids.append(id)
123 embed = pgm.gtk.PgmGtk()
124 self.gtk_window.add(embed)
125 embed.set_viewport(viewport)
126 self.gtk_window.resize(*viewport.size)
127 self.gtk_window.set_focus_child(embed)
128 self.gtk_window.show_all()
129 else:
130
131 self.gtk_window = None
132 viewport.show()
133 id = viewport.connect('configure-event', self._configure_callback)
134 self._signal_handler_ids.append(id)
135
136
137 self.viewport_handle.cursor = pgm.VIEWPORT_NONE
138
139 if not self.touchscreen:
140
141 self._cursor_delay = 1.000
142 self._cursor_delayed = None
143
144 id = viewport.connect('motion-notify-event',
145 self._motion_notify_callback)
146 self._signal_handler_ids.append(id)
147
151
152 - def aspect_ratio_changed(self, old_aspect_ratio, new_aspect_ratio):
153 if old_aspect_ratio is not None:
154 self.debug("aspect ratio changed from %r to %r", old_aspect_ratio,
155 new_aspect_ratio)
156 else:
157 self.info("will set the aspect ratio with parameter %r", new_aspect_ratio)
158
159 screen_ratio = self._get_screen_size_from_ratio(new_aspect_ratio)
160 self.debug("screen ratio is %r", screen_ratio)
161
162 pixel_aspect_ratio = self._get_pixel_aspect_ratio(screen_ratio)
163 self.info("used pixel aspect ratio is %r", pixel_aspect_ratio)
164
165 canvas_height = self.canvas.width / screen_ratio
166 self.debug("new canvas height: %r", canvas_height)
167 self.canvas.height = canvas_height
168
169
170 viewport_height = self.viewport_handle.width / (screen_ratio * pixel_aspect_ratio)
171 self.debug("new viewport height: %r", viewport_height)
172 self.viewport_handle.height = viewport_height
173
174
175
176 self.viewport_size = self.viewport_handle.size
177 self.debug("viewport size: %r", self.viewport_size)
178
179 config_screen_ratio = self.config.get('screen_ratio', 'auto')
180 if config_screen_ratio != new_aspect_ratio:
181 self.config['screen_ratio'] = new_aspect_ratio
182
183 self.canvas_resized.emit(self.canvas.size)
184
186 viewport = self.viewport_handle
187
188
189 for id in self._signal_handler_ids:
190 viewport.disconnect(id)
191
192
193 viewport.set_canvas(None)
194
195
196 del self.viewport_handle
197
198 - def context_handle__set(self, context_handle):
199 self._context_handle = context_handle
200 if isinstance(context_handle, pgm.Drawable):
201 self.canvas.add(pgm.DRAWABLE_MIDDLE, context_handle)
202
204 return self._context_handle
205
206 - def _compiz_check(self):
207
208 ps_aux = os.popen('ps aux')
209
210 compiz = False
211
212 for line in ps_aux:
213 if 'compiz' in line:
214 compiz = True
215
216 if compiz:
217 self.warning("Compiz detected, trying to hide all other windows.")
218 try:
219 import wnck
220 except ImportError:
221 self.warning("Could not import WNCK. Windows hiding disabled.")
222 else:
223 s = wnck.screen_get_default()
224 s.force_update()
225 lst = s.get_windows()
226 cur_workspace = s.get_active_workspace()
227 for window in lst:
228 if window.is_in_viewport(cur_workspace):
229 window.minimize()
230
231 else:
232 self.info('Compiz not found')
233
234 - def _get_screen_size_from_ratio(self, config_screen_ratio):
235
236 if config_screen_ratio == 'sr':
237 self.info("using window manager screen resolution as screen aspect ratio: %r",
238 self.viewport_handle.screen_resolution)
239 w, h = self.viewport_handle.screen_resolution
240 self.viewport_handle.screen_size_mm = (int(w), int(h) )
241 elif config_screen_ratio.find(':') != -1:
242 self.info("Using configured aspect screen ratio: %r", config_screen_ratio)
243 w, h = config_screen_ratio.split(':')
244 self.viewport_handle.screen_size_mm = (int(w), int(h))
245 else:
246 self.info("Using the milimeter based screen aspect ratio : %r",
247 self.viewport_handle.screen_size_mm)
248 w, h = self._window_managet_screen_size_mm
249 self.viewport_handle.screen_size_mm = (int(w), int(h))
250 width = float(w)
251 height = float(h)
252 self.debug("screen size: (%r,%r)", width, height)
253
254 return width / float(height)
255
256 - def _get_pixel_aspect_ratio(self, screen_aspect_ratio):
257 w, h = self.viewport_handle.screen_resolution
258 return ( w / float(h) ) / float(screen_aspect_ratio)
259
261
262 if self._resize_delayed != None and self._resize_delayed.active():
263 self._resize_delayed.reset(self._resize_delay)
264 else:
265 self._resize_delayed = reactor.callLater(self._resize_delay,
266 self._resize_canvas)
267
268 - def _resize_canvas(self):
269
270 if self.viewport_size != self.viewport_handle.size:
271 self.debug("regeneration of the drawables")
272 self.viewport_size = self.viewport_handle.size
273 self.canvas_resized.emit(self.canvas.size)
274
275 """
276 # resize the canvas to follow the aspect ratio of the viewport
277 viewport_ratio = float(self.viewport_handle.width)/float(self.viewport_handle.height)
278 canvas_ratio = float(self.canvas.width)/float(self.canvas.height)
279
280 # only resize the canvas if the aspect ratio of the viewport has changed
281 if viewport_ratio != canvas_ratio:
282 # FIXME: only one of width/height needs to change (multiplied by
283 # viewport_ratio)
284 self.canvas.size = (self.viewport_handle.width/100.0,
285 self.viewport_handle.height/100.0)
286 self.debug("The canvas is getting resized. New size = (%s, %s)" % \
287 (self.canvas.size[0], self.canvas.size[1]))
288 """
289
290 - def _motion_notify_callback(self, viewport, event):
291
292 viewport.cursor = pgm.VIEWPORT_INHERIT
293
294
295 if self._cursor_delayed != None and self._cursor_delayed.active():
296 self._cursor_delayed.reset(self._cursor_delay)
297 else:
298 self._cursor_delayed = reactor.callLater(self._cursor_delay, self._hide_cursor)
299
300 - def _hide_cursor(self):
301 self.viewport_handle.cursor = pgm.VIEWPORT_NONE
302
303 - def theme_changed(self, old_theme, new_theme):
304 for icon, master in self.master_drawables.iteritems():
305 image_path = new_theme.get_media(icon)
306 master.set_from_file(image_path)
307