summaryrefslogtreecommitdiff
path: root/cad/src/temporary_commands/RotateMode.py
blob: 12ecf104e08820712d65ca1027a39be937fccfba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# Copyright 2005-2009 Nanorex, Inc.  See LICENSE file for details.
"""
Rotate mode functionality.

@author:    Mark Sims
@version:   $Id$
@copyright: 2005-2009 Nanorex, Inc.  See LICENSE file for details.
@license:   GPL

piotr 080808: added "auto-rotation" feature.
"""

from temporary_commands.TemporaryCommand import TemporaryCommand_Overdrawing
from PyQt4.Qt import Qt, QTimer, SIGNAL

## from utilities.debug import set_enabled_for_profile_single_call
## clicked = False

# == GraphicsMode part
_superclass = TemporaryCommand_Overdrawing.GraphicsMode_class

class RotateMode_GM( TemporaryCommand_Overdrawing.GraphicsMode_class ):
    """
    Custom GraphicsMode for use as a component of RotateMode.
    """

    def __init__(self, glpane):
        TemporaryCommand_Overdrawing.GraphicsMode_class.__init__(self, glpane)

        self.auto_rotate = False # set to True when user presses "A" key while
        self.animationTimer = None # time used to animate view
        self.last_quat = None # last quaternion to be used for incremental rotation

    def leftDown(self, event):
        ## global clicked
        ## clicked = True
        self.glpane.SaveMouse(event)
        self.glpane.trackball.start(self.glpane.MousePos[0],
                                    self.glpane.MousePos[1])

        # piotr 080807: The most recent quaternion to be used for "auto-rotate"
        # animation, initially set to None, so the animation stops when
        # user pushes down mouse button.
        self.last_quat = None

        self.picking = False
        return

    def leftDrag(self, event):
        ## global clicked
        ## if clicked:
        ##     set_enabled_for_profile_single_call(True)
        ##     clicked = False

        self.glpane.SaveMouse(event)
        q = self.glpane.trackball.update(self.glpane.MousePos[0],
                                         self.glpane.MousePos[1])
        self.glpane.quat += q

        # piotr 080807: Remember the most recent quaternion to be used
        # in 'auto_rotate' mode. Do it only if 'auto_rotate' class attribute
        # is True, i.e. when user pressed an "A" key while dragging the mouse.
        if self.auto_rotate:
            self.last_quat = q

        self.glpane.gl_update()
        self.picking = False
        return

    def leftUp(self, event):
        if self.last_quat:
            # Create and enable animation timer.
            if self.animationTimer is None:
                self.animationTimer  =  QTimer(self.glpane)
                self.win.connect(self.animationTimer,
                                 SIGNAL('timeout()'),
                                 self._animationTimerTimeout)
            self.animationTimer.start(20) # use 50 fps for smooth animation
        else:
            # Stop animation if mouse was not dragged.
            if self.animationTimer:
                self.animationTimer.stop()

    def _animationTimerTimeout(self):
        if self.last_quat:
            self.glpane.quat += self.last_quat
            self.glpane.gl_update()

    def update_cursor_for_no_MB(self): # Fixes bug 1638. Mark 3/12/2006
        """
        Update the cursor for 'Rotate' mode.
        """
        self.glpane.setCursor(self.win.RotateViewCursor)
        return

    def keyPress(self, key):
        if key == Qt.Key_A:
            self.auto_rotate = True

        _superclass.keyPress(self, key)
        return

    def keyRelease(self, key):
        if key == Qt.Key_A:
            self.auto_rotate = False

        _superclass.keyRelease(self, key)
        return
    pass

# == Command part

class RotateMode(TemporaryCommand_Overdrawing): # TODO: rename to RotateTool or RotateCommand or TemporaryCommand_Rotate or ...
    """
    Encapsulates the Rotate Tool functionality.
    """

    # class constants
    commandName = 'ROTATE'
    featurename = "Rotate Tool"
    from utilities.constants import CL_VIEW_CHANGE
    command_level = CL_VIEW_CHANGE

    GraphicsMode_class = RotateMode_GM

    def command_will_exit(self):
        # Disable auto-rotation.
        self.graphicsMode.last_quat = False
        super(RotateMode, self).command_will_exit()

    def command_enter_misc_actions(self):
        """
        See superclass method for documentation
        """
        self.win.rotateToolAction.setChecked(True)

    def command_exit_misc_actions(self):
        """
        See superclass method for documentation
        """
        self.win.rotateToolAction.setChecked(False)