File: remote_widget.py

package info (click to toggle)
mayavi2 4.8.3-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 21,892 kB
  • sloc: python: 49,447; javascript: 32,885; makefile: 129; fortran: 60
file content (150 lines) | stat: -rw-r--r-- 4,971 bytes parent folder | download | duplicates (2)
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
143
144
145
146
147
148
149
150
import puremagic


class RemoteWidget(object):
    """An abstract remote widget which talks to the bridge but has no toolkit
    specific code.

    This is similar to the QVTKRenderWindowInteractor but instead of actually
    setting things on a local render window interactor, passes them off to a
    remote server to do the job and simply renders a PNG sent by the remote
    server.
    """
    def __init__(self, scene_proxy, bridge, **kw):
        super(RemoteWidget, self).__init__(**kw)
        self.scene_proxy = scene_proxy
        self.bridge = bridge
        bridge.add_widget(scene_proxy.id, self)

        self._ActiveButton = 'none'

        # private attributes
        self._saveX = 0
        self._saveY = 0
        self._saveModifiers = False, False
        self._saveButtons = 'none'
        self._wheelDelta = 0
        self._is_resizing = False
        self._move_count = 0

        # Note that since this is just a raw image sent by the server we do
        # not need to worry about the pixel ratio for this case unlike
        # the QRenderWindowInteractor.

    # ###### Public protocol ##############

    def handle_vtk_event(self, obj_name, vtk_event, data):
        if vtk_event == 'RenderEvent':
            if not self._is_resizing:
                self.on_render(data)
        elif vtk_event == 'CursorChangedEvent':
            self.on_cursor_changed(data)

    def send(self, method, *args):
        self.scene_proxy.call_rwi(*((method, ) + args))

    def show_image(self, data, format='PNG'):
        pass

    # #### Private protocol ############

    def _update_image(self):
        data = self.scene_proxy.get_raw_image()
        format = puremagic.what('', h=data)
        self.show_image(data, format=format.upper())

    # ##### VTK Event handling ##########
    def on_render(self, data):
        pass

    def on_cursor_changed(self, data):
        pass

    # ##### Toolkit event handling ##########

    def on_resize(self, w, h):
        if not self._is_resizing:
            self.send('SetSize', w, h)
            self.send('ConfigureEvent')
            self._update_image()

    def on_close(self):
        self.bridge.remove_widget(self.scene_proxy.id, self)

    def on_enter(self, ctrl, shift):
        self.send('SetEventInformationFlipY', self._saveX, self._saveY,
                  ctrl, shift, chr(0), 0, None)
        self.send('EnterEvent')

    def on_leave(self, ctrl, shift):
        self.send('SetEventInformationFlipY', self._saveX, self._saveY,
                  ctrl, shift, chr(0), 0, None)
        self.send('LeaveEvent')

    def on_mouse_press(self, ctrl, shift, x, y, button, repeat=0):
        '''
        ctrl, shift are bools indicating if the modifiers are pressed.
        x, y are screen relative coordinates.
        button is one of 'left', 'right', 'middle' or 'none'
        repeate is for repeat clicks (double click)
        '''
        self.send('SetEventInformationFlipY', x, y,
                  ctrl, shift, chr(0), repeat, None)

        self._ActiveButton = 'left'

        if button == 'left':
            self.send('LeftButtonPressEvent')
        elif button == 'right':
            self.send('RightButtonPressEvent')
        elif button == 'middle':
            self.send('MiddleButtonPressEvent')

    def on_mouse_release(self, ctrl, shift, x, y):
        self.send('SetEventInformationFlipY', x, y,
                  ctrl, shift, chr(0), 0, None)
        button = self._ActiveButton
        if button == 'left':
            self.send('LeftButtonReleaseEvent')
        elif button == 'right':
            self.send('RightButtonReleaseEvent')
        elif button == 'middle':
            self.send('MiddleButtonReleaseEvent')

    def on_mouse_move(self, ctrl, shift, button, x, y):
        self._move_count += 1

        if self._move_count % 3 == 0:
            self._saveModifiers = ctrl, shift
            self._saveButtons = button
            self._saveX = x
            self._saveY = y

            self.send('SetEventInformationFlipY', x, y,
                      ctrl, shift, chr(0), 0, None)
            self.send('MouseMoveEvent')
            self._move_count = 0

    def on_key_press(self, ctrl, shift, key, key_sym):
        """ React to key pressed event.

        """
        self.send('SetEventInformationFlipY', self._saveX, self._saveY,
                  ctrl, shift, key, 0, key_sym)
        self.send('KeyPressEvent')
        self.send('CharEvent')

    def on_key_release(self, ctrl, shift, key):
        self.send('SetEventInformationFlipY', self._saveX, self._saveY,
                  ctrl, shift, key, 0, None)
        self.send('KeyReleaseEvent')

    def on_wheel(self, delta):
        self._wheelDelta += delta

        if self._wheelDelta >= 60:
            self.send('MouseWheelForwardEvent')
            self._wheelDelta = 0
        elif self._wheelDelta <= -60:
            self.send('MouseWheelBackwardEvent')
            self._wheelDelta = 0