File: _widget.py

package info (click to toggle)
python-vispy 0.6.6-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 21,344 kB
  • sloc: python: 57,412; javascript: 6,810; makefile: 63; sh: 5
file content (104 lines) | stat: -rw-r--r-- 3,951 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
# -*- coding: utf-8 -*-
# Copyright (c) Vispy Development Team. All Rights Reserved.
# Distributed under the (new) BSD License. See LICENSE.txt for more info.

try:
    from ipywidgets.widgets import DOMWidget, register
    from traitlets import Unicode, Int, Bool, Dict
except Exception as exp:
    # Init dummy objects needed to import this module without errors.
    # These are all overwritten with imports from IPython (on success)
    DOMWidget = object

    def _noop(x):
        return x
    
    register = _noop

    class _MockTraitlet(object):
        def __init__(self, *args, **kwargs):
            pass

        def tag(self, *args, **kwargs):
            pass

    Unicode = Int = Float = Bool = Dict = _MockTraitlet
    available, testable, why_not, which = False, False, str(exp), None
else:
    available, testable, why_not, which = True, False, None, None
from ....app.backends._ipynb_util import create_glir_message
from ....app import Timer


# ---------------------------------------------------------- IPython Widget ---
def _stop_timers(canvas):
    """Stop all timers in a canvas."""
    for attr in dir(canvas):
        try:
            attr_obj = getattr(canvas, attr)
        except NotImplementedError:
            # This try/except is needed because canvas.position raises
            # an error (it is not implemented in this backend).
            attr_obj = None
        if isinstance(attr_obj, Timer):
            attr_obj.stop()


@register
class VispyWidget(DOMWidget):
    _view_name = Unicode("VispyView").tag(sync=True)
    _view_module = Unicode('vispy').tag(sync=True)
    _view_module_version = Unicode('~0.3.0').tag(sync=True)
    _model_name = Unicode('VispyModel').tag(sync=True)
    _model_module = Unicode('vispy').tag(sync=True)
    _model_module_version = Unicode('~0.3.0').tag(sync=True)

    #height/width of the widget is managed by IPython.
    #it's a string and can be anything valid in CSS.
    #here we only manage the size of the viewport.
    width = Int().tag(sync=True)
    height = Int().tag(sync=True)
    resizable = Bool(value=True).tag(sync=True)
    webgl_config = Dict(value={}).tag(sync=True)

    def __init__(self, **kwargs):
        if DOMWidget is object:
            raise ImportError("'ipywidgets' must be installed to use the notebook backend.")
        super(VispyWidget, self).__init__(**kwargs)
        self.on_msg(self.events_received)
        self.canvas = None
        self.canvas_backend = None
        self.gen_event = None

    def set_canvas(self, canvas):
        self.width, self.height = canvas._backend._default_size
        self.canvas = canvas
        self.canvas_backend = self.canvas._backend
        self.canvas_backend.set_widget(self)
        self.gen_event = self.canvas_backend._gen_event
        #setup the backend widget then.

    def events_received(self, widget, content, buffers):
        if content['msg_type'] == 'init':
            self.canvas_backend._reinit_widget()
        elif content['msg_type'] == 'events':
            events = content['contents']
            for ev in events:
                self.gen_event(ev)
        elif content['msg_type'] == 'status':
            if content['contents'] == 'removed':
                # Stop all timers associated to the widget.
                _stop_timers(self.canvas_backend._vispy_canvas)

    def send_glir_commands(self, commands):
        # older versions of ipython (<3.0) use base64
        # array_serialization = 'base64'
        array_serialization = 'binary'
        msg = create_glir_message(commands, array_serialization)
        msg['array_serialization'] = array_serialization
        if array_serialization == 'base64':
            self.send(msg)
        elif array_serialization == 'binary':
            # Remove the buffers from the JSON message: they will be sent
            # independently via binary WebSocket.
            self.send(msg, buffers=msg.pop('buffers', None))