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))
|