Merge lp:~nico-inattendu/luciole/bug_727165 into lp:luciole
- bug_727165
- Merge into 0.9
Proposed by
NicoInattendu
Status: | Merged |
---|---|
Approved by: | NicoInattendu |
Approved revision: | 131 |
Merged at revision: | 129 |
Proposed branch: | lp:~nico-inattendu/luciole/bug_727165 |
Merge into: | lp:luciole |
Diff against target: |
1177 lines (+331/-232) 8 files modified
luciole/ctrl/ctrl_acq.py (+9/-5) luciole/ctrl/ctrl_project.py (+66/-41) luciole/gui/windows/assistant_new_project.py (+7/-6) luciole/gui/windows/dialog_project_properties.py (+14/-7) luciole/gui/windows/webcam_detection_widget.py (+84/-162) test/test_assistant_new_project.py (+6/-1) test/test_project_properties.py (+21/-10) test/test_webcam_detection_widget.py (+124/-0) |
To merge this branch: | bzr merge lp:~nico-inattendu/luciole/bug_727165 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
NicoInattendu | Pending | ||
Review via email: mp+52663@code.launchpad.net |
Commit message
fix for bug #727165. ow on assistant and webcam properties window, the webcam playback is activated, in viewer window. It's allow a preview of webcam parameters
Description of the change
Bug correction.
Now on assistant and webcam properties window, the webcam plauback is activated, in viewer window. It's allow a preview of webcam parameters
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'luciole/ctrl/ctrl_acq.py' |
2 | --- luciole/ctrl/ctrl_acq.py 2011-03-05 14:23:17 +0000 |
3 | +++ luciole/ctrl/ctrl_acq.py 2011-03-09 11:46:59 +0000 |
4 | @@ -33,7 +33,7 @@ |
5 | import gst |
6 | from pitivi.signalgroup import SignalGroup |
7 | from pitivi.action import ViewAction |
8 | -from pitivi.pipeline import Pipeline |
9 | +from pitivi.pipeline import Pipeline, PipelineError |
10 | |
11 | # local application/library specific imports |
12 | from luciole.media.lgst.webcam_factory import WebcamSourceFactory |
13 | @@ -157,10 +157,14 @@ |
14 | else : |
15 | #self._source_factory.active_mixer(False) |
16 | self._mode = "ACQUISITION" |
17 | - |
18 | - self._pipeline.play() |
19 | - self.debug('send acquisition-started - mode : %s', self._mode) |
20 | - self.emit('acquisition-started', with_mixer) |
21 | + try : |
22 | + self._pipeline.play() |
23 | + except PipelineError : |
24 | + self.warning('Fail to start pipeline') |
25 | + self._mode = "NO_ACQUISITION" |
26 | + else : |
27 | + self.debug('send acquisition-started - mode : %s', self._mode) |
28 | + self.emit('acquisition-started', with_mixer) |
29 | |
30 | |
31 | else : |
32 | |
33 | === modified file 'luciole/ctrl/ctrl_project.py' |
34 | --- luciole/ctrl/ctrl_project.py 2011-03-05 13:59:13 +0000 |
35 | +++ luciole/ctrl/ctrl_project.py 2011-03-09 11:46:59 +0000 |
36 | @@ -39,15 +39,11 @@ |
37 | import luciole.base.exceptions as LEXCEP |
38 | import luciole.base.tools as LT |
39 | import luciole.constants as LCONST |
40 | -import luciole.ctrl.constants as CTRL_CONST |
41 | import luciole.ctrl.ctrl_acq as CTRL_ACQ |
42 | -import luciole.ctrl.ctrl_base as CTRL_BASE |
43 | import luciole.ctrl.ctrl_timeline as CTRL_TMLN |
44 | import luciole.ctrl.ctrl_no_project as CTRL_NO_PROJECT |
45 | import luciole.ctrl.ctrl_img_vw as CTRL_IMG_VW |
46 | import luciole.ctrl.load_rush as LRUSH |
47 | -import luciole.gui.constants as GUI_CONST |
48 | -import luciole.media.image as LI |
49 | import luciole.project.project_etree as LPF |
50 | |
51 | from luciole.gui.windows.assistant_new_project import AssistantNewProject |
52 | @@ -58,7 +54,7 @@ |
53 | _NULL_TUPLE = None, None |
54 | |
55 | class Project(object) : |
56 | - |
57 | + """ Type class for project data """ |
58 | |
59 | def __init__(self) : |
60 | self.parser = LPF.ProjectToFile() |
61 | @@ -69,6 +65,7 @@ |
62 | |
63 | |
64 | def save(self, path) : |
65 | + """ save to xml file """ |
66 | _project_path = None |
67 | if path is not None : |
68 | try : |
69 | @@ -83,6 +80,9 @@ |
70 | return _project_path |
71 | |
72 | def set_non_pjt_dpdt_props(self) : |
73 | + """ set default valus for properties , |
74 | + who are not stored in xml file |
75 | + """ |
76 | # init props not managed by porject in file |
77 | self.props['is_modified'] = False |
78 | self.props['is-mixer-active'] = False |
79 | @@ -90,7 +90,8 @@ |
80 | self.props['alpha'] = LCONST.DEFAULT_ALPHA_IMAGE |
81 | |
82 | class CtrlProject(Signallable, Loggable) : |
83 | - |
84 | + """ High level class who manage a luciole project """ |
85 | + |
86 | # CONSTANTS |
87 | MODES = ("NO_PROJECT", "ACQUISITION", "TIMELINE", "IMAGE_VIEW", "EXPORT") |
88 | PROJECT_LOADED_MODES = ("ACQUISITION", "TIMELINE", "IMAGE_VIEW", "EXPORT") |
89 | @@ -141,6 +142,7 @@ |
90 | Loggable.__init__(self) |
91 | |
92 | self._mode = None |
93 | + self._old_mode = None |
94 | self.gui = None |
95 | self.project = Project() |
96 | |
97 | @@ -154,6 +156,7 @@ |
98 | |
99 | |
100 | def connect_to_gui(self, gui) : |
101 | + """ connect project controller with gui """ |
102 | self.gui = gui |
103 | |
104 | self.ctrl_acq.set_viewer(gui.drawarea) |
105 | @@ -162,6 +165,7 @@ |
106 | self.ctrl_img_vw.set_viewer(gui.drawarea) |
107 | |
108 | def no_project_mode(self) : |
109 | + """ activate NO_PROJECT mode """ |
110 | self.debug('No project mode') |
111 | |
112 | if self._mode == 'ACQUISITION' : |
113 | @@ -178,7 +182,7 @@ |
114 | |
115 | |
116 | def acquisition_mode(self, force = False) : |
117 | - """ activate acquisition mode """ |
118 | + """ activate ACQUISITION mode """ |
119 | self.debug('Acquisition mode') |
120 | if self._mode in self.PROJECT_LOADED_MODES \ |
121 | and self._mode != 'ACQUISITION' : |
122 | @@ -195,30 +199,34 @@ |
123 | |
124 | self.ctrl_acq.active_viewer() |
125 | self.ctrl_acq.start() |
126 | - self.debug('Emit project-mode-changed : %s'%self._mode) |
127 | - self.emit('project-mode-changed',self._mode) |
128 | + self.debug('Emit project-mode-changed : %s' % self._mode) |
129 | + self.emit('project-mode-changed', self._mode) |
130 | |
131 | else : |
132 | self.warning("impossible to switch to acquisition mode (%s)", |
133 | self._mode ) |
134 | |
135 | - def timeline_mode(self) : |
136 | - """ activate timeline mode """ |
137 | + def timeline_mode(self, force = False) : |
138 | + """ activate TIMELINE mode """ |
139 | + self.debug('setting timeline mode') |
140 | + |
141 | if self._mode == 'ACQUISITION' : |
142 | self.ctrl_acq.stop() |
143 | |
144 | - if self._mode in self.PROJECT_LOADED_MODES \ |
145 | - and self._mode != 'TIMELINE' : |
146 | + if (self._mode in self.PROJECT_LOADED_MODES \ |
147 | + and self._mode != 'TIMELINE') \ |
148 | + or (force == True) : |
149 | |
150 | self._mode = 'TIMELINE' |
151 | self.ctrl_tmln.active_viewer() |
152 | - self.debug('Emit project-mode-changed : %s'%self._mode) |
153 | - self.emit('project-mode-changed',self._mode) |
154 | + self.debug('Emit project-mode-changed : %s' % self._mode) |
155 | + self.emit('project-mode-changed', self._mode) |
156 | else : |
157 | self.warning("impossible to switch to timeline mode") |
158 | |
159 | |
160 | def img_vw_mode(self, origin, image_name, position = 0) : |
161 | + """ activate IMAGE_VIEW mode """ |
162 | if self._mode in self.PROJECT_LOADED_MODES : |
163 | if self._mode == 'ACQUISITION' : |
164 | self.ctrl_acq.stop() |
165 | @@ -274,7 +282,7 @@ |
166 | # close current project |
167 | self.close() |
168 | |
169 | - _ass = AssistantNewProject(self._new_project_cb) |
170 | + _ass = AssistantNewProject(self._new_project_cb, self.gui.drawarea) |
171 | |
172 | |
173 | |
174 | @@ -315,13 +323,14 @@ |
175 | self.project = None |
176 | |
177 | def save(self, dir_path = None ) : |
178 | + """ save project """ |
179 | if self._mode not in self.PROJECT_LOADED_MODES : |
180 | self.error('invalid mode for save : %s'%self._mode) |
181 | return |
182 | if dir_path and not os.path.exists(dir_path) : |
183 | self.error('Path %s exists. Impossible to save project', dir_path) |
184 | return |
185 | - self.debug("%s",dir_path) |
186 | + self.debug("%s", dir_path) |
187 | try : |
188 | _project_path = self.project.save(dir_path) |
189 | except LEXCEP.LucioException, _err_msg : |
190 | @@ -332,10 +341,11 @@ |
191 | if dir_path is not None and _project_path is not None : |
192 | # reload project is corretcly saved |
193 | self.close() |
194 | - self.debug('Opening project with path %s',_project_path) |
195 | + self.debug('Opening project with path %s', _project_path) |
196 | self.open(_project_path) |
197 | |
198 | def set_framerate(self, fpi, force = False) : |
199 | + """ set project framerate """ |
200 | if self._mode != "TIMELINE" and force == False : |
201 | self.info('update of fpi only availabe in TIMELINE mode') |
202 | return |
203 | @@ -347,18 +357,9 @@ |
204 | |
205 | |
206 | |
207 | - def new(self, project_data = None) : |
208 | - |
209 | - # create new project |
210 | - |
211 | - if project_data : |
212 | - # TODO case with assistant |
213 | - pass |
214 | - |
215 | - |
216 | - |
217 | def release(self) : |
218 | - |
219 | + """ release project ctrl """ |
220 | + # TODO : this fucntion seems unuseful : Ton analyse |
221 | # release signals between aquirer and project |
222 | if self.project.props['hardtype'] in \ |
223 | (LCONST.FAKE, LCONST.DVCAM, LCONST.WEBCAM ) : |
224 | @@ -374,12 +375,13 @@ |
225 | |
226 | |
227 | def import_images(self, paths) : |
228 | + """ import images """ |
229 | if self._mode not in self.PROJECT_LOADED_MODES : |
230 | self.error('invalid mode for import: %s'%self._mode) |
231 | return |
232 | |
233 | if paths != [] : |
234 | - self.debug('Starting image importer for %s',paths) |
235 | + self.debug('Starting image importer for %s', paths) |
236 | importer = ImportController( paths, |
237 | self.project.props, |
238 | self.project.rush, |
239 | @@ -398,7 +400,7 @@ |
240 | # snapshot tajed, so snapshot-taken signal can |
241 | # be emited for each image : |
242 | for image in images : |
243 | - self.ctrl_acq.emit('snapshot-taken',image ) |
244 | + self.ctrl_acq.emit('snapshot-taken', image ) |
245 | |
246 | # update project |
247 | # get image names |
248 | @@ -419,7 +421,7 @@ |
249 | if self._mode not in self.PROJECT_LOADED_MODES : |
250 | self.error('invalid mode for import: %s'%self._mode) |
251 | return |
252 | - self.debug('%s',self.project.props) |
253 | + self.debug('%s', self.project.props) |
254 | self._old_mode = self._mode |
255 | if self._mode == 'ACQUISITION' : |
256 | # switch to TIMELINE to free the webcam |
257 | @@ -427,21 +429,34 @@ |
258 | |
259 | |
260 | _properties = ProjectProperties(self.gui.main_window, |
261 | - self.project.props) |
262 | + self.project.props, self.gui.drawarea) |
263 | _properties.connect('project-changed', self._project_modified_cb) |
264 | + _properties.connect('dialog-closed', self._dialog_pp_closed_cb) |
265 | _properties.run() |
266 | |
267 | def _project_modified_cb(self, dialog, project_data) : |
268 | """ callback for modified data from project properties dialog """ |
269 | self.is_modified = True |
270 | + |
271 | + def _dialog_pp_closed_cb(self, dialog) : |
272 | + """ dialog project properties closed callback """ |
273 | if self._old_mode == 'ACQUISITION' : |
274 | # go back to acqusition mode |
275 | self.acquisition_mode(True) |
276 | self._old_mode = None |
277 | + if self._old_mode == 'TIMELINE' : |
278 | + # go back to acqusition mode |
279 | + # trick to force timeline mode reload |
280 | + self.timeline_mode(True) |
281 | + self._old_mode = None |
282 | + |
283 | |
284 | |
285 | |
286 | def _start_project_load(self) : |
287 | + """ start project load. |
288 | + i.e. execute project controller """ |
289 | + |
290 | # start rusher controller |
291 | _rush_ctrl = LRUSH.ControllerLoadRush( self.project, |
292 | self.gui.status_bar ) |
293 | @@ -449,6 +464,7 @@ |
294 | |
295 | |
296 | def _rush_load_finish_cb(self, rush_ctrl, rush_obj) : |
297 | + """ image rush load finish callback """ |
298 | self.debug(" Rush Load Finish :%s ", rush_obj.dump_image_name() ) |
299 | if rush_obj != None : |
300 | self._terminate_project_load(rush_obj) |
301 | @@ -456,13 +472,14 @@ |
302 | rush_ctrl.disconnect_by_function( self._rush_load_finish_cb) |
303 | |
304 | def _terminate_project_load(self, rush_obj) : |
305 | + """ terminate load of a project """ |
306 | self.project.rush = rush_obj |
307 | |
308 | # set project as not modified as it is just loaded |
309 | self.project.set_non_pjt_dpdt_props() |
310 | |
311 | # set path for image to mix |
312 | - self.project.props['image2mix'] =\ |
313 | + self.project.props['image2mix'] = \ |
314 | os.path.join( |
315 | self.project.props['project_dir'], |
316 | LCONST.IMAGE2MIX_NAME |
317 | @@ -481,15 +498,18 @@ |
318 | self.emit('project-loaded', self.project ) |
319 | |
320 | def _connect_to_acq(self , ctrl_acq) : |
321 | + """ connect to acqusision controller """ |
322 | ctrl_acq.connect('acquirer-ready', self._acquirer_ready_cb) |
323 | ctrl_acq.connect('acquirer-error', self._acquirer_error_cb) |
324 | |
325 | def _disconnect_from_acq(self , ctrl_acq) : |
326 | + """ disconnect from acqusision controller """ |
327 | ctrl_acq.disconnect_by_function( self._acquirer_ready_cb) |
328 | ctrl_acq.disconnect_by_function( self._acquirer_error_cb) |
329 | |
330 | |
331 | def _acquirer_ready_cb(self, ctrl_acq ) : |
332 | + """ acquirer ready callback """ |
333 | self.debug('RX acquirer-ready signal') |
334 | if self.project.props['hardtype'] in \ |
335 | (LCONST.FAKE, LCONST.DVCAM, LCONST.WEBCAM ) : |
336 | @@ -504,27 +524,32 @@ |
337 | |
338 | |
339 | def _acquirer_error_cb(self, ctrl_acq, msg) : |
340 | + """ acquirer error callback """ |
341 | + # TODO : implementation of acqusition errot |
342 | + # not corectly managed |
343 | self.error(msg) |
344 | |
345 | def _connect_to_timeline(self, ctrl_tmln) : |
346 | + """ connect to timeline controller """ |
347 | ctrl_tmln.connect('timeline-ready', self._timeline_ready_cb) |
348 | |
349 | def _disconnect_from_timeline(self, ctrl_tmln) : |
350 | + """ discconnect from timeline controller """ |
351 | ctrl_tmln.disconnect_from_project(self) |
352 | - ctrl_tmln.disconnect_by_function(self._timeline_loaded_cb) |
353 | + ctrl_tmln.disconnect_by_function(self._timeline_ready_cb) |
354 | |
355 | def _timeline_ready_cb(self, ctrl_tmln): |
356 | + """ timeline ready callback """ |
357 | + self.debug('RX timeline-ready signal') |
358 | if self.project.props['hardtype'] == LCONST.DIGICAM : |
359 | - # TODO : work around on mode |
360 | - # FIXME : set to image to force transtion to acquisition mode |
361 | - # default mode when project is started |
362 | - self._mode = 'IMAGE_VIEW' |
363 | - self.timeline_mode() |
364 | + # when digicam mode is set force timeline mode |
365 | + self.timeline_mode(True) |
366 | |
367 | |
368 | |
369 | def _copy_to_image2mix(self, image_name) : |
370 | - |
371 | + """ on directory, copy an image to image the image 2 mix path |
372 | + """ |
373 | _source = os.path.join( self.project.props['project_dir'], |
374 | self.project.props['rush_dir'], |
375 | image_name) |
376 | |
377 | === modified file 'luciole/gui/windows/assistant_new_project.py' |
378 | --- luciole/gui/windows/assistant_new_project.py 2011-02-28 12:58:02 +0000 |
379 | +++ luciole/gui/windows/assistant_new_project.py 2011-03-09 11:46:59 +0000 |
380 | @@ -408,8 +408,8 @@ |
381 | class PageWebcam(LWDW.WebcamDetectionWidget) : |
382 | """ Assistant page for webcam detection """ |
383 | |
384 | - def __init__(self, assistant, project_data, *args ) : |
385 | - LWDW.WebcamDetectionWidget.__init__(self, project_data, *args ) |
386 | + def __init__(self, assistant, project_data, viewer_wdg, *args ) : |
387 | + LWDW.WebcamDetectionWidget.__init__(self, project_data, viewer_wdg, *args ) |
388 | self.assistant = assistant |
389 | |
390 | def webcam_detection_prepare(self, page) : |
391 | @@ -517,8 +517,8 @@ |
392 | """ Call back for 'selection-changed' signal """ |
393 | _filename = widget.get_filename() |
394 | if _filename : |
395 | - self.project_data['sound']['active'] = 'yes' |
396 | - self.project_data['sound']['input_path'] = _filename |
397 | + self.project_data['sound']['active'] = 'yes' |
398 | + self.project_data['sound']['input_path'] = _filename |
399 | |
400 | |
401 | |
402 | @@ -650,9 +650,10 @@ |
403 | |
404 | __LUCIOLE_LOGO = os.path.join(LCONST.IMAGE_DIR,'luciole_logo.png') |
405 | |
406 | - def __init__(self, apply_callback) : |
407 | + def __init__(self, apply_callback, viewer_wdg) : |
408 | """ Initialize assistant window """ |
409 | self.apply_callback = apply_callback |
410 | + self.viewer_wdg = viewer_wdg |
411 | |
412 | # |
413 | # init project datas |
414 | @@ -696,7 +697,7 @@ |
415 | # |
416 | # configure page 3 |
417 | # |
418 | - self._pg3 = PageWebcam( self.assistant, self.project_data) |
419 | + self._pg3 = PageWebcam( self.assistant, self.project_data, self.viewer_wdg) |
420 | self.assistant.append_page(self._pg3) |
421 | self.assistant.set_page_title( self._pg3, _(' Webcam detection ')) |
422 | self.assistant.set_page_type( self._pg3, gtk.ASSISTANT_PAGE_CONTENT) |
423 | |
424 | === modified file 'luciole/gui/windows/dialog_project_properties.py' |
425 | --- luciole/gui/windows/dialog_project_properties.py 2011-02-27 18:32:53 +0000 |
426 | +++ luciole/gui/windows/dialog_project_properties.py 2011-03-09 11:46:59 +0000 |
427 | @@ -53,6 +53,7 @@ |
428 | """ |
429 | __signals__ = { |
430 | 'project-changed' : ['project'], |
431 | + 'dialog-closed' : [], |
432 | } |
433 | |
434 | # This tow 2 tables descibes how to display project info |
435 | @@ -130,7 +131,7 @@ |
436 | |
437 | _title = _('Project properties') |
438 | |
439 | - def __init__(self, main_window, project) : |
440 | + def __init__(self, main_window, project , viewer_wdg) : |
441 | """ create a Dialog with project properties and display it""" |
442 | Loggable.__init__(self) |
443 | Signallable.__init__(self) |
444 | @@ -145,8 +146,8 @@ |
445 | gtk.STOCK_APPLY, gtk.RESPONSE_APPLY |
446 | ) |
447 | ) |
448 | - print self._dialog.vbox |
449 | self._project = project |
450 | + self._viewer_wdg = viewer_wdg |
451 | # keep framerate list and framerate selected those value can change |
452 | #self._framerate_selected = None |
453 | #self._framerate_list = None |
454 | @@ -204,8 +205,9 @@ |
455 | self._new_webcam_props != self._project['webcam_data'] : |
456 | self._project['webcam_data'].update(self._new_webcam_props) |
457 | self.emit('project-changed', self._project) |
458 | - |
459 | - |
460 | + |
461 | + self.debug('emit dialog-closed signal') |
462 | + self.emit('dialog-closed') |
463 | |
464 | def _cb_on_exit(self, widget, event) : |
465 | """ on exit callback """ |
466 | @@ -530,7 +532,10 @@ |
467 | |
468 | def on_button_webcam_clicked(self, widget) : |
469 | """ Button webcam clicked """ |
470 | - self._widget_webcam = WebcamDetectionDlg(self._dialog, self._cb_webcam_updated) |
471 | + self._widget_webcam = WebcamDetectionDlg( |
472 | + self._dialog, |
473 | + self._viewer_wdg, |
474 | + self._cb_webcam_updated) |
475 | |
476 | |
477 | def _cb_webcam_updated(self, webcam_props) : |
478 | @@ -667,7 +672,7 @@ |
479 | class WebcamDetectionDlg(gtk.MessageDialog, Loggable) : |
480 | """ Opens Dialog for webcam Detection """ |
481 | |
482 | - def __init__(self, parent, cb_ok = None ) : |
483 | + def __init__(self, parent, viewer_wdg, cb_ok = None ) : |
484 | """ create a Dialog with project properties and display it |
485 | parent : The parent window |
486 | cb_ok : The callback when on button is clicked |
487 | @@ -685,7 +690,9 @@ |
488 | # detected data will be stored here |
489 | self.project_webcam = dict() |
490 | |
491 | - self.webcam_widget = LWDW.WebcamDetectionWidget(self.project_webcam) |
492 | + self.webcam_widget = \ |
493 | + LWDW.WebcamDetectionWidget(self.project_webcam, |
494 | + viewer_wdg) |
495 | self.webcam_widget.connect('webcam-caps-selected', |
496 | self._webcam_caps_selected) |
497 | self.webcam_widget.connect('webcam-caps-selected', |
498 | |
499 | === modified file 'luciole/gui/windows/webcam_detection_widget.py' |
500 | --- luciole/gui/windows/webcam_detection_widget.py 2011-02-16 13:04:44 +0000 |
501 | +++ luciole/gui/windows/webcam_detection_widget.py 2011-03-09 11:46:59 +0000 |
502 | @@ -35,19 +35,13 @@ |
503 | import gobject |
504 | |
505 | |
506 | -import gst |
507 | - |
508 | - |
509 | from pitivi.log.loggable import Loggable |
510 | from pitivi.signalinterface import Signallable |
511 | |
512 | # for test |
513 | -from pitivi.encode import RenderSinkFactory, RenderFactory |
514 | -from pitivi.action import RenderAction |
515 | -from pitivi.factories.base import SinkFactory |
516 | from pitivi.pipeline import Pipeline |
517 | -from pitivi.settings import StreamEncodeSettings, RenderSettings |
518 | |
519 | +from pitivi.action import ViewAction |
520 | # local application/library specific imports |
521 | import luciole.media.webcam_detect.webcam_detection as WBCM_DTCT |
522 | |
523 | @@ -55,6 +49,7 @@ |
524 | from luciole.media.lgst.webcam_factory import WebcamSourceFactory |
525 | |
526 | class WebcamField(Loggable, Signallable) : |
527 | + """ Manage webcam properties/fields """ |
528 | __signals__ = { |
529 | 'combo-changed' : ['field','value'], |
530 | } |
531 | @@ -68,9 +63,10 @@ |
532 | self._combo_idx = [] |
533 | self._combo = None |
534 | self._range = None |
535 | - self.widget = self._createUi() |
536 | + self.widget = self._create_ui() |
537 | |
538 | - def _createUi(self) : |
539 | + def _create_ui(self) : |
540 | + """ Gui widgetc creation """ |
541 | _bbox = gtk.HBox() |
542 | _boxalign = gtk.Alignment(xalign=0.0, yalign=0.0) |
543 | _boxalign.add(_bbox) |
544 | @@ -91,16 +87,18 @@ |
545 | return _boxalign |
546 | |
547 | def _create_combo(self, bbox) : |
548 | + """ create GUI combo box """ |
549 | _combo = gtk.combo_box_new_text() |
550 | self.debug('create combobox for field %s', self.field_name) |
551 | for _idx, _value in enumerate(self.value) : |
552 | _combo.append_text(str(_value)) |
553 | self._combo_idx.append(str(_value)) |
554 | - _combo.connect('changed', self.combobox_defintion_changed_cb) |
555 | + _combo.connect('changed', self._combobox_defintion_changed_cb) |
556 | bbox.pack_start(_combo, expand=False) |
557 | return _combo |
558 | |
559 | def _create_range(self, bbox) : |
560 | + """ create GUI range """ |
561 | |
562 | _adj = gtk.Adjustment( |
563 | float(self.value[0]), |
564 | @@ -115,19 +113,21 @@ |
565 | _scale.set_value_pos(gtk.POS_RIGHT) |
566 | _scale.set_draw_value(True) |
567 | _scale.set_size_request(500, 500) |
568 | - _scale.connect('value-changed', self.vscale_value_changed_cb) |
569 | + _scale.connect('value-changed', self._vscale_value_changed_cb) |
570 | bbox.pack_start(_scale, expand=True, fill = True ) |
571 | return _scale |
572 | |
573 | - def combobox_defintion_changed_cb(self, widget) : |
574 | - |
575 | + def _combobox_defintion_changed_cb(self, widget) : |
576 | + """ combobox change callback""" |
577 | self.emit('combo-changed', self.field_name, widget.get_active_text() ) |
578 | |
579 | - def vscale_value_changed_cb(self, widget) : |
580 | + def _vscale_value_changed_cb(self, widget) : |
581 | + """ scale value changed callback""" |
582 | self.emit('combo-changed', self.field_name, widget.get_value() ) |
583 | |
584 | |
585 | def set_active(self, value) : |
586 | + """ active values on combo """ |
587 | if self._combo is not None : |
588 | try : |
589 | _idx = self._combo_idx.index(value) |
590 | @@ -138,7 +138,7 @@ |
591 | |
592 | |
593 | class WebcamPropsWdg(Loggable, Signallable) : |
594 | - """ Webcam Properties """ |
595 | + """ Webcam Properties widget """ |
596 | |
597 | __signals__ = { |
598 | 'prop-changed' : ['prop','value'], |
599 | @@ -158,46 +158,48 @@ |
600 | |
601 | parent_wdg.add(self._main_window) |
602 | |
603 | - self.prepare_ui() |
604 | |
605 | # Show the window and all its children |
606 | self._main_window.show_all() |
607 | |
608 | - |
609 | - |
610 | - def prepare_ui(self) : |
611 | - pass |
612 | |
613 | |
614 | def set_definitions(self, definitions) : |
615 | + """ set webcam definitions GUI prop""" |
616 | self.set_prop('definition', definitions) |
617 | |
618 | def set_active_defintion(self, definition) : |
619 | + """ set webcam active definition GUI prop""" |
620 | _wdg = self.prop_widgets['definition'] |
621 | _wdg.set_active(definition) |
622 | |
623 | |
624 | def set_videotypes(self, videotypes) : |
625 | + """ set webcam videotypes GUI prop""" |
626 | self.set_prop('videotype', videotypes) |
627 | |
628 | def set_active_videotype(self, value) : |
629 | + """ set webcam active videotype GUI prop""" |
630 | self.set_active_prop('videotype', value) |
631 | |
632 | |
633 | def set_prop(self, prop, prop_values, wdg_type='combo' ) : |
634 | + """ set a webcam GUI prop. Generic method """ |
635 | _wdg = WebcamField(prop, prop_values, wdg_type ) |
636 | if isinstance(prop_values, list) : |
637 | - _wdg.connect('combo-changed', self.combo_changed_cb) |
638 | + _wdg.connect('combo-changed', self._combo_changed_cb) |
639 | self.prop_widgets[prop] = _wdg |
640 | self._main_window.pack_start(_wdg.widget) |
641 | _wdg.widget.show_all() |
642 | |
643 | |
644 | def set_active_prop(self, prop, active_value): |
645 | + """ set a webcam active GUI prop. Generic method """ |
646 | _wdg = self.prop_widgets[prop] |
647 | _wdg.set_active(active_value) |
648 | |
649 | def remove_prop(self, prop) : |
650 | + """ remove a webcam property """ |
651 | if prop in self.prop_widgets : |
652 | |
653 | self.debug('remove prop %s', prop) |
654 | @@ -207,20 +209,23 @@ |
655 | del self.prop_widgets[prop] |
656 | |
657 | def remove_all_props(self) : |
658 | + """ remove all properties """ |
659 | _props = self.prop_widgets.keys() |
660 | for _prop in _props: |
661 | _wdg = self.prop_widgets.pop(_prop) |
662 | self._main_window.remove(_wdg.widget) |
663 | - _wdg.disconnect_by_function(self.combo_changed_cb) |
664 | + _wdg.disconnect_by_function(self._combo_changed_cb) |
665 | self.debug("remove widget prop %s", _prop) |
666 | |
667 | |
668 | - def combo_changed_cb(self, widget, prop, value) : |
669 | + def _combo_changed_cb(self, widget, prop, value) : |
670 | + """ combobox value changed callback """ |
671 | self.debug('emit prop-changed : %s=%s', prop, value) |
672 | self.emit('prop-changed', prop, value) |
673 | |
674 | |
675 | def display_webcams(self, _webcams) : |
676 | + """ display detected webcams """ |
677 | _wdg = WebcamField('webcam-name', _webcams) |
678 | if isinstance(_webcams, list) : |
679 | _wdg.connect('combo-changed', self._webcam_changed_cb) |
680 | @@ -230,21 +235,15 @@ |
681 | _wdg.widget.show_all() |
682 | |
683 | def _webcam_changed_cb(self, widget, prop, value) : |
684 | + """ webcam selection callback """ |
685 | self.debug('emit webcam-changed : %s=%s', prop, value) |
686 | |
687 | self.emit('webcam-changed', value) |
688 | |
689 | |
690 | -class FakeSinkFactory(SinkFactory): |
691 | - def __init__(self, factoryname="fakesink", *args, **kwargs): |
692 | - SinkFactory.__init__(self, *args, **kwargs) |
693 | - self.__factoryname=factoryname |
694 | - |
695 | - def _makeBin(self, output_stream=None): |
696 | - return gst.element_factory_make(self.__factoryname) |
697 | - |
698 | class WebcamDetectionWidget(gtk.Frame, Loggable) : |
699 | """ Assistant page for webcam detection """ |
700 | + |
701 | __gsignals__ = { |
702 | 'webcams-detected' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, |
703 | (gobject.TYPE_PYOBJECT,)), |
704 | @@ -260,12 +259,14 @@ |
705 | |
706 | |
707 | |
708 | - def __init__(self, project_data, *args ) : |
709 | + def __init__(self, project_data, viewer, *args ) : |
710 | gtk.Frame.__init__(self, *args ) |
711 | - Signallable.__init__(self) |
712 | Loggable.__init__(self) |
713 | self.wcam_params = {} |
714 | - |
715 | + self._viewer = viewer |
716 | + self.factory = None |
717 | + self.action = None |
718 | + self.pipeline = None |
719 | self.set_name('Page_webcam') |
720 | self.project_data = project_data |
721 | |
722 | @@ -306,57 +307,55 @@ |
723 | self.info('No webcam detected') |
724 | self.emit('webcam-not-detetcted') |
725 | |
726 | + def prepare_viewer(self, wcam_params) : |
727 | + """ prepare viewer and pipeline """ |
728 | + self.debug('prepare pipeline/viewer start') |
729 | |
730 | - def active_webcam(self, device) : |
731 | - if self.pipeline is not None : |
732 | + viewer = self._viewer |
733 | + if viewer.pipeline is not None : |
734 | try : |
735 | - self.pipeline.pause() |
736 | - self.render.deactivate() |
737 | + viewer.pause() |
738 | except : |
739 | - pass |
740 | - |
741 | - |
742 | + self.warning('Impossible to pause viewer') |
743 | self.factory = WebcamSourceFactory() |
744 | - self.debug("%s", self.wcam_params) |
745 | - self.factory.webcam_params = self.wcam_params |
746 | + self.factory.webcam_params = wcam_params |
747 | + self.factory.with_scale = False |
748 | + |
749 | self.pipeline = Pipeline() |
750 | - |
751 | - vsettings = StreamEncodeSettings(encoder="theoraenc") |
752 | - rsettings = RenderSettings(settings=[vsettings], |
753 | - muxer="oggmux") |
754 | - |
755 | - self.fakesink = FakeSinkFactory() |
756 | - rendersink = RenderSinkFactory(RenderFactory(settings=rsettings), |
757 | - self.fakesink) |
758 | - self.render = RenderAction() |
759 | - #self.pipeline.connect("eos", self._renderEOSCb) |
760 | - #self.pipeline.connect("error", self._renderErrorCb) |
761 | - self.pipeline.addAction(self.render) |
762 | - self.render.addConsumers(rendersink) |
763 | - self.render.addProducers(self.factory) |
764 | - self.render.activate() |
765 | - self.pipeline.play() |
766 | - gobject.timeout_add(1000, self._deactive_pipeline) |
767 | - return self.factory |
768 | - |
769 | - def _deactive_pipeline(self) : |
770 | - self.debug('Deactive Pipeline') |
771 | - if self.pipeline is not None : |
772 | + self.action = ViewAction() |
773 | + self.action.addProducers(self.factory) |
774 | + viewer.setPipeline(None) |
775 | + #viewer.showSlider() |
776 | + |
777 | + # FIXME: why do I have to call viewer.setAction ? |
778 | + viewer.setAction(self.action) |
779 | + viewer.setPipeline(self.pipeline) |
780 | + viewer.play() |
781 | + self.debug('viewer started') |
782 | + |
783 | + def release_viewer(self) : |
784 | + """ release pipeline for viewer""" |
785 | + self.debug(' release pipe %s', self.pipeline) |
786 | + |
787 | + viewer = self._viewer |
788 | + if self.pipeline is None : |
789 | + self.debug('No pipeline to release') |
790 | + return |
791 | + if viewer.pipeline is not None : |
792 | try : |
793 | - print " release ." |
794 | - self.pipeline.stop() |
795 | - self.render.deactivate() |
796 | - self.render.setPipeline(None) |
797 | - self.pipeline.release() |
798 | - self.pipeline = None |
799 | - self.factory = None |
800 | - |
801 | + viewer.stop() |
802 | except : |
803 | - pass |
804 | - return False |
805 | + self.warning('Impossible to stop pipeline') |
806 | + |
807 | + viewer.setPipeline(None) |
808 | + self.pipeline.release() |
809 | + self.pipeline = None |
810 | + self.factory = None |
811 | + self.action = None |
812 | |
813 | |
814 | def _webcam_changed_cb(self, wdg, webcam) : |
815 | + """ webcam selection changed callback """ |
816 | self.debug('Rx webcam-changed : %s', webcam ) |
817 | self.webcam_props.clear_all() |
818 | self.wcam_params = {} |
819 | @@ -379,8 +378,8 @@ |
820 | 'device':_selected_device['device-file'], |
821 | } |
822 | } |
823 | - _factory = self.active_webcam(self.wcam_params) |
824 | - self.webcam_props.prepare(_factory.webcam_caps) |
825 | + self.prepare_viewer(self.wcam_params) |
826 | + self.webcam_props.prepare(self.factory.webcam_caps) |
827 | |
828 | |
829 | else : |
830 | @@ -388,94 +387,17 @@ |
831 | |
832 | |
833 | def _caps_selected_cb(self, webcam_props, caps) : |
834 | + """ webcam caps(propeties) selected callback """ |
835 | self.project_data['webcam_data']['caps'] = caps |
836 | + |
837 | + self.wcam_params['wcam_filter'] = { |
838 | + 'media_type' : caps, |
839 | + } |
840 | + |
841 | + self.prepare_viewer(self.wcam_params) |
842 | + |
843 | self.debug('Rx caps-selected : %s', caps.to_string() ) |
844 | self.emit('webcam-caps-selected', caps) |
845 | - |
846 | - |
847 | - |
848 | - |
849 | - def _on_webcam_detect_complete(self, webcam_obj) : |
850 | - """ callback , executed when webcam detection is complete |
851 | - Return the number of detected webcams""" |
852 | - _status = 0 |
853 | - |
854 | - if webcam_obj != None and webcam_obj.webcam_devices != None: |
855 | - _vbox = self._vbox |
856 | - # firt clean childs on the vbox widget |
857 | - for _child in _vbox.get_children() : |
858 | - _vbox.remove(_child) |
859 | - # loop on detected webcams |
860 | - _rd_btn = None |
861 | - |
862 | - for (_wbcm_idx, _webcam ) in \ |
863 | - enumerate(webcam_obj.webcam_devices) : |
864 | - _rd_btn = gtk.RadioButton( |
865 | - group =_rd_btn, |
866 | - label = _webcam["name"] ) |
867 | - _vbox.pack_start(_rd_btn) |
868 | - _rd_btn.show() |
869 | - |
870 | - #connect event |
871 | - _rd_btn.connect( |
872 | - "clicked", |
873 | - self.on_webcam_radio_button_clicked, |
874 | - _wbcm_idx, |
875 | - webcam_obj ) |
876 | - |
877 | - # First set |
878 | - if _wbcm_idx == 0 : |
879 | - # select by default. |
880 | - self.project_data['webcam_data'] = \ |
881 | - webcam_obj.get_gst_best_input(_wbcm_idx) |
882 | - |
883 | - self.label.set_text(_('Detected webcam(s)')) |
884 | - _status = len(webcam_obj.webcam_devices) |
885 | - else : |
886 | - self.project_data['webcam_data'] = None |
887 | - self.label.set_text(_('No webcam detected')) |
888 | - self.label.show() |
889 | - return _status |
890 | - |
891 | - def on_webcam_radio_button_clicked(self, widget, webcam_index, webcam_obj): |
892 | - """ callback for webcam rasdio button. |
893 | - Save info on selected webcam |
894 | - """ |
895 | - # when a webcam is selected select webcam data |
896 | - self.project_data['webcam_data'] = \ |
897 | - webcam_obj.get_gst_best_input(webcam_index) |
898 | - |
899 | |
900 | -if __name__ == '__main__' : |
901 | - import pygtk |
902 | - |
903 | - def init_log() : |
904 | - import os |
905 | - from pitivi.log import log |
906 | - enable_color = os.environ.get('PITIVI_DEBUG_NO_COLOR', '0') in ('', '0') |
907 | - log.init('PITIVI_DEBUG', enable_color) |
908 | |
909 | - class Tester(Loggable) : |
910 | - |
911 | - def __init__(self) : |
912 | - Loggable.__init__(self) |
913 | - window = gtk.Window() |
914 | - window.connect('destroy', lambda w: gtk.main_quit()) |
915 | - self.debug(' starting App') |
916 | - _wdg = WebcamDetectionWidget(project_data = {}) |
917 | - _wdg.connect('webcams-detected',self._webcam_detected_cb) |
918 | - window.add(_wdg) |
919 | - window.show_all() |
920 | - |
921 | - _wdg.prepare_webcam_detection() |
922 | - |
923 | - return |
924 | - |
925 | - def _webcam_detected_cb(self, widget, data = None): |
926 | - self.debug('Rx webcam detected %s', data) |
927 | - |
928 | - init_log() |
929 | - Tester() |
930 | - gtk.main() |
931 | - |
932 | |
933 | |
934 | === modified file 'test/test_assistant_new_project.py' |
935 | --- test/test_assistant_new_project.py 2011-02-25 08:17:16 +0000 |
936 | +++ test/test_assistant_new_project.py 2011-03-09 11:46:59 +0000 |
937 | @@ -42,6 +42,7 @@ |
938 | # local application/library specific imports |
939 | from common import init_log |
940 | |
941 | +from pitivi.ui.viewer import PitiviViewer |
942 | #tested module |
943 | from luciole.gui.windows.assistant_new_project import AssistantNewProject |
944 | |
945 | @@ -49,6 +50,7 @@ |
946 | PROJECT_PATH = '/home/nico/temp/testLuciole' |
947 | |
948 | class Tester(Loggable) : |
949 | + """ Tester class """ |
950 | |
951 | def __init__(self) : |
952 | Loggable.__init__(self) |
953 | @@ -56,10 +58,13 @@ |
954 | gobject.threads_init() |
955 | window = gtk.Window() |
956 | window.connect('destroy', lambda w: gtk.main_quit()) |
957 | + |
958 | + self.ptv_viewer = PitiviViewer() |
959 | + window.add(self.ptv_viewer) |
960 | window.show_all() |
961 | |
962 | # start assistant |
963 | - _ass =AssistantNewProject(self._apply_cb) |
964 | + _ass =AssistantNewProject(self._apply_cb, self.ptv_viewer) |
965 | self.prepare_assistant(_ass) |
966 | |
967 | def _apply_cb(self, project_data) : |
968 | |
969 | === modified file 'test/test_project_properties.py' |
970 | --- test/test_project_properties.py 2011-02-27 18:32:53 +0000 |
971 | +++ test/test_project_properties.py 2011-03-09 11:46:59 +0000 |
972 | @@ -22,12 +22,10 @@ |
973 | # |
974 | # |
975 | """ |
976 | -test_assistant_new_project.py : |
977 | - GTK assistant for creation of new projects |
978 | +test_project_properties.py : |
979 | + Test project properties |
980 | """ |
981 | # standard library imports |
982 | -import os.path |
983 | -import shutil |
984 | |
985 | # related third party imports |
986 | import pygtk |
987 | @@ -41,11 +39,11 @@ |
988 | |
989 | # local application/library specific imports |
990 | from common import init_log |
991 | +from pitivi.ui.viewer import PitiviViewer |
992 | |
993 | #tested module |
994 | from luciole.gui.windows.dialog_project_properties import ProjectProperties |
995 | |
996 | -import gst |
997 | |
998 | CAPS_STR = ("video/x-raw-yuv, format=(fourcc)I420, width=(int)1280," |
999 | "height=(int)1024, interlaced=(boolean)false," |
1000 | @@ -63,7 +61,6 @@ |
1001 | 'v4ldriver': 'v4l2src', |
1002 | 'name': 'Built-in iSight' |
1003 | }, |
1004 | - 'project_name': 'test_luciole', |
1005 | 'fpi': 5, |
1006 | 'hardtype': 2, |
1007 | 'resize' : 'no', |
1008 | @@ -71,22 +68,36 @@ |
1009 | } |
1010 | |
1011 | class Tester(Loggable) : |
1012 | - |
1013 | + """ Tester class """ |
1014 | + |
1015 | def __init__(self) : |
1016 | Loggable.__init__(self) |
1017 | self.debug('starting tester') |
1018 | gobject.threads_init() |
1019 | window = gtk.Window() |
1020 | window.connect('destroy', lambda w: gtk.main_quit()) |
1021 | + self.ptv_viewer = PitiviViewer() |
1022 | + window.add(self.ptv_viewer) |
1023 | + |
1024 | window.show_all() |
1025 | self.debug("project properties : %s", PROJECT_PROPS) |
1026 | - _properties = ProjectProperties(window, PROJECT_PROPS) |
1027 | + _properties = ProjectProperties(window, PROJECT_PROPS, self.ptv_viewer) |
1028 | _properties.connect('project-changed', self._project_modified_cb) |
1029 | + _properties.connect('dialog-closed', self._dialog_pp_closed_cb) |
1030 | _properties.run() |
1031 | |
1032 | def _project_modified_cb(self, gui, project_data) : |
1033 | - self.debug('received aplly cb -- project_data =%s ; %r %r', project_data, project_data, PROJECT_PROPS ) |
1034 | - |
1035 | + """ callback for modified data from project properties dialog """ |
1036 | + self.debug( ("received aplly cb" |
1037 | + "-- project_data =%s ; %r %r"), |
1038 | + project_data, |
1039 | + project_data, |
1040 | + PROJECT_PROPS) |
1041 | + |
1042 | + def _dialog_pp_closed_cb(self, dialog) : |
1043 | + """ dialog project properties closed callback """ |
1044 | + self.debug('dialog closed') |
1045 | + gtk.main_quit() |
1046 | |
1047 | |
1048 | if __name__ == '__main__' : |
1049 | |
1050 | === added file 'test/test_webcam_detection_widget.py' |
1051 | --- test/test_webcam_detection_widget.py 1970-01-01 00:00:00 +0000 |
1052 | +++ test/test_webcam_detection_widget.py 2011-03-09 11:46:59 +0000 |
1053 | @@ -0,0 +1,124 @@ |
1054 | +#!/usr/bin/env python |
1055 | +# -*- coding: utf-8 -*- |
1056 | +# -*- Mode: Python -*- |
1057 | +# vim:si:ai:et:sw=4:sts=4:ts=4 |
1058 | +# |
1059 | +# Copyright Nicolas Bertrand (nico@inattendu.org), 2009-2010 |
1060 | +# |
1061 | +# This file is part of Luciole. |
1062 | +# |
1063 | +# Luciole is free software: you can redistribute it and/or modify |
1064 | +# it under the terms of the GNU General Public License as published by |
1065 | +# the Free Software Foundation, either version 3 of the License, or |
1066 | +# (at your option) any later version. |
1067 | +# |
1068 | +# Luciole is distributed in the hope that it will be useful, |
1069 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1070 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1071 | +# GNU General Public License for more details. |
1072 | +# |
1073 | +# You should have received a copy of the GNU General Public License |
1074 | +# along with Luciole. If not, see <http://www.gnu.org/licenses/>. |
1075 | +# |
1076 | +# |
1077 | +""" |
1078 | +test_webcam_detection_widget.py : |
1079 | + test webcam detection widget |
1080 | +""" |
1081 | +# standard library imports |
1082 | + |
1083 | +# related third party imports |
1084 | +import pygtk |
1085 | +pygtk.require('2.0') |
1086 | +import gtk |
1087 | +import gobject |
1088 | +import pygst |
1089 | +pygst.require('0.10') |
1090 | + |
1091 | +from pitivi.log.loggable import Loggable |
1092 | +from pitivi.action import ViewAction |
1093 | +from pitivi.ui.viewer import PitiviViewer |
1094 | +from pitivi.pipeline import Pipeline |
1095 | +from pitivi.ui.viewer import PitiviViewer |
1096 | + |
1097 | +# local application/library specific imports |
1098 | +from common import init_log |
1099 | + |
1100 | +#tested module |
1101 | +from luciole.gui.windows.webcam_detection_widget import WebcamDetectionWidget |
1102 | +from luciole.media.lgst.webcam_factory import WebcamSourceFactory |
1103 | + |
1104 | +class Tester(Loggable) : |
1105 | + """ Test class """ |
1106 | + |
1107 | + def __init__(self) : |
1108 | + Loggable.__init__(self) |
1109 | + self.debug('starting tester') |
1110 | + gobject.threads_init() |
1111 | + self.wcam_params = {} |
1112 | + self.factory = None |
1113 | + |
1114 | + window = gtk.Window() |
1115 | + window.connect('destroy', lambda w: gtk.main_quit()) |
1116 | + bbox = gtk.VBox() |
1117 | + boxalign = gtk.Alignment(xalign=0.5, yalign=0.5) |
1118 | + boxalign.add(bbox) |
1119 | + |
1120 | + self.ptv_viewer = PitiviViewer() |
1121 | + |
1122 | + # set webcam detection widget |
1123 | + self.project_data = {} |
1124 | + _wdg = WebcamDetectionWidget(self.project_data, self.ptv_viewer) |
1125 | + _wdg.connect('webcam-caps-selected', self._wcam_caps_selected) |
1126 | + _wdg.prepare_webcam_detection() |
1127 | + bbox.pack_start(_wdg) |
1128 | + |
1129 | + bbox.pack_start(self.ptv_viewer, expand=False) |
1130 | + |
1131 | + |
1132 | + window.add(boxalign) |
1133 | + |
1134 | + window.show_all() |
1135 | + |
1136 | + def _wcam_caps_selected(self, wdg ,caps) : |
1137 | + self.debug('received webcam-caps-selected -- project_data =%s', |
1138 | + caps ) |
1139 | + |
1140 | + self.wcam_params['wcam_filter'] = { |
1141 | + 'media_type' : caps, |
1142 | + } |
1143 | + |
1144 | + #self.prepare_viewer() |
1145 | + |
1146 | + def prepare_viewer(self) : |
1147 | + viewer = self.ptv_viewer |
1148 | + if viewer.pipeline is not None : |
1149 | + try : |
1150 | + viewer.pause() |
1151 | + except : |
1152 | + pass |
1153 | + self.factory = WebcamSourceFactory() |
1154 | + self.factory.webcam_params = self.wcam_params |
1155 | + self.factory.with_scale = False |
1156 | + |
1157 | + pipeline = Pipeline() |
1158 | + action = ViewAction() |
1159 | + action.addProducers(self.factory) |
1160 | + viewer.setPipeline(None) |
1161 | + viewer.showSlider() |
1162 | + |
1163 | + # FIXME: why do I have to call viewer.setAction ? |
1164 | + viewer.setAction(action) |
1165 | + viewer.setPipeline(pipeline) |
1166 | + viewer.play() |
1167 | + |
1168 | + return False |
1169 | + |
1170 | + |
1171 | + |
1172 | +if __name__ == '__main__' : |
1173 | + init_log() |
1174 | + Tester() |
1175 | + gtk.main() |
1176 | + |
1177 | + |