source: trunk/papywizard/controller/shootController.py @ 1067

Revision 1067, 13.5 KB checked in by fma, 5 years ago (diff)

Bug correction in onButtonPressed()

  • Property svn:keywords set to Id
Line 
1# -*- coding: utf-8 -*-
2
3""" Panohead remote control.
4
5License
6=======
7
8 - B{papywizard} (U{http://trac.gbiloba.org/papywizard}) is Copyright:
9  - (C) 2007-2008 Frédéric Mantegazza
10
11This software is governed by the B{CeCILL} license under French law and
12abiding by the rules of distribution of free software.  You can  use,
13modify and/or redistribute the software under the terms of the CeCILL
14license as circulated by CEA, CNRS and INRIA at the following URL
15U{http://www.cecill.info}.
16
17As a counterpart to the access to the source code and  rights to copy,
18modify and redistribute granted by the license, users are provided only
19with a limited warranty  and the software's author,  the holder of the
20economic rights,  and the successive licensors  have only  limited
21liability.
22
23In this respect, the user's attention is drawn to the risks associated
24with loading,  using,  modifying and/or developing or reproducing the
25software by the user in light of its specific status of free software,
26that may mean  that it is complicated to manipulate,  and  that  also
27therefore means  that it is reserved for developers  and  experienced
28professionals having in-depth computer knowledge. Users are therefore
29encouraged to load and test the software's suitability as regards their
30requirements in conditions enabling the security of their systems and/or
31data to be ensured and,  more generally, to use and operate it in the
32same conditions as regards security.
33
34The fact that you are presently reading this means that you have had
35knowledge of the CeCILL license and that you accept its terms.
36
37Module purpose
38==============
39
40Graphical toolkit controller
41
42Implements
43==========
44
45- ShootController
46
47@author: Frédéric Mantegazza
48@copyright: (C) 2007-2008 Frédéric Mantegazza
49@license: CeCILL
50"""
51
52__revision__ = "$Id$"
53
54import os.path
55import time
56import threading
57
58import pygtk
59pygtk.require("2.0")
60import gtk
61import gtk.gdk
62import gobject
63
64from papywizard.common.loggingServices import Logger
65from papywizard.common.configManager import ConfigManager
66from papywizard.controller.messageController import ErrorMessageController
67from papywizard.controller.abstractController import AbstractController
68from papywizard.controller.generalInfoController import GeneralInfoController
69from papywizard.controller.spy import Spy
70from papywizard.view.shootingArea import MosaicArea, PresetArea
71
72
73class ShootController(AbstractController):
74    """ Shoot controller object.
75    """
76    def _init(self):
77        self._gladeFile = "shootDialog.glade"
78        self._signalDict = {"on_manualShootCheckbutton_toggled": self.__onManualShootCheckbuttonToggled,
79                            "on_dataFileEnableCheckbutton_toggled": self.__onDataFileEnableCheckbuttonToggled,
80                            "on_startButton_clicked": self.__onStartButtonClicked,
81                            "on_pauseResumeButton_clicked": self.__onPauseResumeButtonClicked,
82                            "on_stopButton_clicked": self.__onStopButtonClicked,
83                            "on_doneButton_clicked": self.__onDoneButtonClicked,
84                        }
85
86        self.__keyPressedDict = {'Return': False,
87                                 'Escape': False
88                             }
89        self.__key = {'Return': gtk.keysyms.Return,
90                      'Escape': gtk.keysyms.Escape
91                      }
92
93    def _retreiveWidgets(self):
94        super(ShootController, self)._retreiveWidgets()
95
96        vbox = self.wTree.get_widget("vbox")
97        drawingarea = self.wTree.get_widget("drawingarea")
98        drawingarea.destroy()
99        if self._model.mode == 'mosaic':
100            self.shootingArea = MosaicArea()
101        else:
102            self.shootingArea = PresetArea()
103        vbox.pack_start(self.shootingArea)
104        vbox.reorder_child(self.shootingArea, 0)
105        if self._model.mode == 'mosaic':
106
107            # todo: give args in shootingArea.__init__()
108            self.shootingArea.init(self._model.mosaic.yawStart, self._model.mosaic.yawEnd,
109                                   self._model.mosaic.pitchStart, self._model.mosaic.pitchEnd,
110                                   self._model.mosaic.yawFov, self._model.mosaic.pitchFov,
111                                   self._model.camera.getYawFov(self._model.cameraOrientation),
112                                   self._model.camera.getPitchFov(self._model.cameraOrientation),
113                                   self._model.mosaic.yawRealOverlap, self._model.mosaic.pitchRealOverlap)
114            for index, (yaw, pitch) in self._model.mosaic.iterPositions():
115                self.shootingArea.add_pict(yaw, pitch, 'preview')
116        else:
117            self.shootingArea.init(440., 220., # visible fov
118                                    16.,  16.) # camera fov
119            for index, (yaw, pitch) in self._model.preset.iterPositions():
120                self.shootingArea.add_pict(yaw, pitch, 'preview')
121        self.shootingArea.show()
122        self.progressbar = self.wTree.get_widget("progressbar")
123        self.manualShootCheckbutton = self.wTree.get_widget("manualShootCheckbutton")
124        self.dataFileEnableCheckbutton = self.wTree.get_widget("dataFileEnableCheckbutton")
125        self.startButton = self.wTree.get_widget("startButton")
126        self.pauseResumeButton = self.wTree.get_widget("pauseResumeButton")
127        self.pauseResumeLabel = self.wTree.get_widget("pauseResumeLabel")
128        self.stopButton = self.wTree.get_widget("stopButton")
129        self.doneButton = self.wTree.get_widget("doneButton")
130
131        self.pauseResumeButton.set_sensitive(False)
132        self.stopButton.set_sensitive(False)
133
134    def _connectSignals(self):
135        super(ShootController, self)._connectSignals()
136
137        self.dialog.connect("key-press-event", self.__onKeyPressed)
138        self.dialog.connect("key-release-event", self.__onKeyReleased)
139        self.dialog.connect("delete-event", self.__onDelete)
140
141        self.shootingArea.connect("button-press-event", self.__onButtonPressed)
142
143        self._model.newPictSignal.connect(self.__addPicture)
144
145    # Callbacks
146    def __onButtonPressed(self, widget, event):
147        Logger().trace("ShootController.__onButtonPressed()")
148        if self._model.isPaused():
149            if event.button == 1:
150                Logger().debug("ShootController.__onButtonPressed(): x=%d, y=%d" % (event.x, event.y))
151                index = self.shootingArea.get_selected_image_index(event.x, event.y)
152                if index is not None:
153                    self._model.setShootingIndex(index)
154
155    def __onDelete(self, widget, event):
156        Logger().trace("ShootController.__onDelete()")
157        self.__stopShooting()
158
159    def __onKeyPressed(self, widget, event, *args):
160
161        # 'Return' key
162        if event.keyval == self.__key['Return']:
163            if not self.__keyPressedDict['Return']:
164                Logger().debug("shootController.__onKeyPressed(): 'Return' key pressed")
165                self.__keyPressedDict['Return'] = True
166
167                # Pressing 'Return' while not shooting starts shooting
168                if not self._model.isShooting():
169                    Logger().debug("shootController.__onKeyPressed(): start shooting")
170                    self.__startShooting()
171
172                # Pressing 'Return' while shooting...
173                else:
174
175                    # ...and not paused pauses shooting
176                    if not self._model.isPaused():
177                        Logger().debug("shootController.__onKeyPressed(): pause shooting")
178                        self.__pauseShooting()
179
180                    #... and paused resumes shooting
181                    else:
182                        Logger().debug("shootController.__onKeyPressed(): resume shooting")
183                        self.__resumeShooting()
184                return True
185
186        # 'Escape' key
187        elif event.keyval == self.__key['Escape']:
188           if not self.__keyPressedDict['Escape']:
189               Logger().debug("shootController.__onKeyPressed(): 'Escape' key pressed")
190               self.__keyPressedDict['Escape'] = True
191
192               # Pressing 'Escape' while not shooting exit shoot dialog
193               if not self._model.isShooting():
194                   Logger().debug("shootController.__onKeyPressed(): close shooting dialog")
195                   self.dialog.response(0)
196
197               # Pressing 'Escape' while shooting stops shooting
198               else:
199                   Logger().debug("shootController.__onKeyPressed(): stop shooting")
200                   self.__stopShooting()
201               return True
202
203        else:
204            Logger().warning("MainController.__onKeyPressed(): unbind '%s' key" % event.keyval)
205
206    def __onKeyReleased(self, widget, event, *args):
207
208        # 'Return' key
209        if event.keyval == self.__key['Return']:
210            if self.__keyPressedDict['Return']:
211                Logger().debug("MainController.__onKeyReleased(): 'Return' key released")
212                self.__keyPressedDict['Return'] = False
213            return True
214
215        # 'Escape' key
216        if event.keyval == self.__key['Escape']:
217            if self.__keyPressedDict['Escape']:
218                Logger().debug("MainController.__onKeyReleased(): 'Escape' key released")
219                self.__keyPressedDict['Escape'] = False
220            return True
221
222        else:
223            Logger().warning("MainController.__onKeyReleased(): unbind '%s' key" % event.keyval)
224
225    def __onManualShootCheckbuttonToggled(self, widget):
226        Logger().trace("ShootController.____onManualShootCheckbuttonToggled()")
227        switch = self.manualShootCheckbutton.get_active()
228        self._model.setManualShoot(switch)
229
230    def __onDataFileEnableCheckbuttonToggled(self, widget):
231        Logger().trace("ShootController.__onDataFileEnableCheckbuttonToggled()")
232        switch = self.dataFileEnableCheckbutton.get_active()
233        ConfigManager().setBoolean('Data', 'DATA_FILE_ENABLE', self.dataFileEnableCheckbutton.get_active())
234        if switch:
235            controller = GeneralInfoController(self, self._model)
236            controller.run()
237            controller.shutdown()
238
239    def __onStartButtonClicked(self, widget):
240        Logger().trace("ShootController.__startButtonClicked()")
241        self.__startShooting()
242
243    def __onPauseResumeButtonClicked(self, widget):
244        Logger().trace("ShootController.__pauseResumeButtonClicked()")
245        if self._model.isShooting(): # Should always be true here, but...
246            if not self._model.isPaused():
247                self.__pauseShooting()
248            else:
249                self.__resumeShooting()
250
251    def __onStopButtonClicked(self, widget):
252        Logger().trace("ShootController.__stopButtonClicked()")
253        self.__stopShooting()
254
255    def __onDoneButtonClicked(self, widget):
256        Logger().trace("ShootController.__onDoneButtonClicked()")
257        #self.dialog.response(0)
258
259    def __addPicture(self, yaw, pitch, status):
260        Logger().trace("ShootController.__addPicture()")
261        self.shootingArea.add_pict(yaw, pitch, status)
262
263    # Helpers
264    def __startShooting(self):
265        def monitorShooting():
266            Logger().trace("ShootController.__startShooting().monitorShooting()")
267
268            # Check if model paused (manual shoot mode)
269            if self._model.isPaused():
270                self.pauseResumeLabel.set_text(_("Resume"))
271            else:
272                self.pauseResumeLabel.set_text(_("Pause"))
273
274            # Check end of shooting
275            if not self._model.isShooting():
276                Logger().debug("monitorShooting(): model not shooting anymore")
277
278                # Check status
279                #if self._model.error:
280                    #ErrorMessageController(_("Internal error"), _("Please report bug (include logs)"))
281
282                self.dataFileEnableCheckbutton.set_sensitive(True)
283                self.startButton.set_sensitive(True)
284                self.pauseResumeLabel.set_text(_("Pause"))
285                self.pauseResumeButton.set_sensitive(False)
286                self.stopButton.set_sensitive(False)
287                self.doneButton.set_sensitive(True)
288                self.refreshView()
289                thread.join()
290                Logger().debug("ShootController.__startShooting().monitorShooting(): model thread over")
291
292                return False # Stop execution by Gtk timeout
293
294            self.refreshView()
295
296            return True
297
298        self.shootingArea.clear()
299        self.dataFileEnableCheckbutton.set_sensitive(False)
300        self.startButton.set_sensitive(False)
301        self.pauseResumeButton.set_sensitive(True)
302        self.stopButton.set_sensitive(True)
303        self.doneButton.set_sensitive(False)
304
305        thread = threading.Thread(target=self._model.start, name="Shooting")
306        thread.start()
307        #self._model.startEvent.wait() # Does not work under maemo
308        while not self._model.isShooting():
309            time.sleep(.1)
310
311        # Monitor shooting process
312        gobject.timeout_add(100, monitorShooting)
313
314    def __pauseShooting(self):
315        self._model.pause()
316        #self.pauseResumeLabel.set_text(_("Resume"))
317
318    def __resumeShooting(self):
319        self._model.resume()
320        #self.pauseResumeLabel.set_text(_("Pause"))
321
322    def __stopShooting(self):
323        self._model.stop()
324
325        # Wait for shooting really stops
326        # todo: use condition
327        while self._model.isShooting():
328            time.sleep(0.1)
329
330    def shutdown(self):
331        super(ShootController, self).shutdown()
332        self._model.newPictSignal.disconnect(self.__addPicture)
333
334    def refreshView(self):
335        self.progressbar.set_fraction(self._model.progress)
336        self.progressbar.set_text(self._model.sequence)
337        self.dataFileEnableCheckbutton.set_active(ConfigManager().getBoolean('Data', 'DATA_FILE_ENABLE'))
Note: See TracBrowser for help on using the repository browser.