diff --git a/setup.py b/setup.py index 2cf3fe986..ef7553c99 100644 --- a/setup.py +++ b/setup.py @@ -42,7 +42,6 @@ 'jupyter_client>=4.0.0,<5.0.0', 'notebook>=4.0.0,<5.0.0', 'nbconvert>=4.0.0, <5.0.0', - 'ipywidgets>=5.1.5, <6.0', - 'netpyne' + 'ipywidgets>=5.1.5, <6.0' ], ) diff --git a/src/jupyter_geppetto/GeppettoJupyter.js b/src/jupyter_geppetto/GeppettoJupyter.js index 5db62b60e..335f4f080 100644 --- a/src/jupyter_geppetto/GeppettoJupyter.js +++ b/src/jupyter_geppetto/GeppettoJupyter.js @@ -5,8 +5,8 @@ define('jupyter_geppetto', function () { var jupyter_geppettoWidgetSync = window.parent.GEPPETTO.GeppettoJupyterWidgetSync; return { + ComponentSync: jupyter_geppettoGUISync.ComponentSync, PanelSync: jupyter_geppettoGUISync.PanelSync, - TextFieldSync: jupyter_geppettoGUISync.TextFieldSync, CheckboxSync: jupyter_geppettoGUISync.CheckboxSync, ButtonSync: jupyter_geppettoGUISync.ButtonSync, LabelSync: jupyter_geppettoGUISync.LabelSync, diff --git a/src/jupyter_geppetto/__init__.py b/src/jupyter_geppetto/__init__.py index 98dd19b3f..578a3e675 100644 --- a/src/jupyter_geppetto/__init__.py +++ b/src/jupyter_geppetto/__init__.py @@ -1,12 +1,11 @@ -import os +import os.path import json +import codecs from notebook.utils import url_path_join from notebook.base.handlers import IPythonHandler import tornado.websocket import tornado.web import nbformat as nbf -import codecs -import os.path from nbformat.v4.nbbase import new_notebook diff --git a/src/jupyter_geppetto/geppetto b/src/jupyter_geppetto/geppetto index 21bce83da..6dc3a6063 160000 --- a/src/jupyter_geppetto/geppetto +++ b/src/jupyter_geppetto/geppetto @@ -1 +1 @@ -Subproject commit 21bce83da507e854da8b7b8277b0f6f59c38af95 +Subproject commit 6dc3a60635d450e358c5486adcf33b715dcbbe16 diff --git a/src/jupyter_geppetto/geppettoJupyter.css b/src/jupyter_geppetto/geppettoJupyter.css index 915e6538a..d8f5f974b 100644 --- a/src/jupyter_geppetto/geppettoJupyter.css +++ b/src/jupyter_geppetto/geppettoJupyter.css @@ -6,29 +6,63 @@ div#notebook{ padding: 0; } +.notebook_app { + background:transparent!important; +} + +#notebook-container { + box-shadow: none; +} + .container { width:100% !important; } #notebook-container { - background:rgba(66,59,59,1); + background:transparent; } div.input_prompt { - color: #fc6320; + color: white; } div.output_area pre { - color: #fc6320; + color: #D84315; } div.cell.selected { border:0 ; border-left-width: 0px; padding-left: 6px; - background: linear-gradient(to right, #fc6320 -40px, #fc6320 5px, transparent 5px, transparent 100%); } .close { color:white; } +#site::-webkit-scrollbar, +#site::-webkit-scrollbar-button, +#site::-webkit-scrollbar-track, +#site::-webkit-scrollbar-track-piece, +#site::-webkit-scrollbar-thumb, +#site::-webkit-scrollbar-corner, +#site::-webkit-resizer { + background: transparent; +} +#sitet::-webkit-scrollbar { + width: 0px; + height: 0px; + -webkit-border-radius: 0px; + border-radius: 0px; +} +#site::-webkit-scrollbar-track-piece { + -webkit-border-radius: 0px; + border-radius: 0px; +} +#site::-webkit-scrollbar-thumb { + background: #4f4f4f; + border-radius: 0px; +} +#site::-webkit-scrollbar-button { + width:0; + height:0; +} \ No newline at end of file diff --git a/src/jupyter_geppetto/geppetto_comm/GeppettoJupyterGUISync.py b/src/jupyter_geppetto/geppetto_comm/GeppettoJupyterGUISync.py index fe9ed289a..68478b4d0 100644 --- a/src/jupyter_geppetto/geppetto_comm/GeppettoJupyterGUISync.py +++ b/src/jupyter_geppetto/geppetto_comm/GeppettoJupyterGUISync.py @@ -9,44 +9,78 @@ from jupyter_geppetto.geppetto_comm import GeppettoJupyterModelSync -# Current variables -sync_values = defaultdict(list) - +# This is a list of all the models that are synched between Python and Javascript +synched_models = defaultdict(list) + +def remove_component_sync(componentType, model): + component_to_remove = None + for existingModel, synched_component in list(synched_models.items()): + if existingModel == model: + component_to_remove = model + break + if(component_to_remove): + synched_models[component_to_remove].disconnect() + del synched_models[component_to_remove] class ComponentSync(widgets.Widget): - widget_id = Unicode('').tag(sync=True) + componentType = Unicode('componentType').tag(sync=True) + model = Unicode('').tag(sync=True) + id = Unicode('').tag(sync=True) + value = Unicode().tag(sync=True) + widget_name = Unicode('').tag(sync=True) embedded = Bool(True).tag(sync=True) - - sync_value = Unicode().tag(sync=True) - value = None + _model_name = Unicode('ComponentSync').tag(sync=True) + _model_module = Unicode('jupyter_geppetto').tag(sync=True) + + read_only = Bool(False).tag(sync=True) extraData = None def __init__(self, **kwargs): super(ComponentSync, self).__init__(**kwargs) - if 'value' in kwargs and kwargs["value"] is not None and kwargs["value"] != '': - sync_values[kwargs["value"]] = self + if 'model' in kwargs and kwargs["model"] is not None and kwargs["model"] != '': + synched_models[kwargs["model"]] = self - self._change_handlers = widgets.CallbackDispatcher() - self._blur_handlers = widgets.CallbackDispatcher() + self._value_handler = widgets.CallbackDispatcher() + #the method updateModel is executed in response to the sync_value event + self._value_handler.register_callback(self.updateModel) self.on_msg(self._handle_component_msg) - def on_change(self, callback, remove=False): - self._change_handlers.register_callback(callback, remove=remove) - - def on_blur(self, callback, remove=False): - self._blur_handlers.register_callback(callback, remove=remove) - def _handle_component_msg(self, _, content, buffers): - if content.get('event', '') == 'change': - self._change_handlers(self, content) - elif content.get('event', '') == 'blur': - self._blur_handlers(self, content) + if content.get('event', '') == 'sync_value': + self._value_handler(self, content) + + + def updateModel(self, *args): + if self.model != None and self.model != '' and args[1]['value'] != None: + try: + if isinstance(args[1]['value'], (str, unicode)): + value = "'" + args[1]['value'] + "'" + else: + value = str(args[1]['value']) + logging.debug("Updating model with new value " + value) + if(args[1]['requirement']): + exec(args[1]['requirement']) + + exec(self.model + "=" + value) + except Exception as identifier: + logging.exception("Error updating model") + + def connect(self): + logging.debug("ComponentSync connecting to " + self.model) + self.send({"type": "connect"}) + + def disconnect(self): + logging.debug("ComponentSync disconnecting from " + self.model) + self.send({"type": "disconnect"}) + self._value_handler.register_callback(self.updateModel, remove=True) + self.on_msg(self._handle_component_msg, remove=True) + def __str__(self): - return "Component Sync => " + "Widget Id: " + self.widget_id + ", Widget Name: " + self.widget_name + ", Embedded: " + str(self.embedded) + ", Sync Value: " + self.sync_value + ", Value: " + str(self.value) + ", Extra Data: " + self.extraData + return "Component Sync => Widget Name: " + self.widget_name + ", Embedded: " + str(self.embedded) + ", Sync Value: " + self.value + ", Model: " + str(self.model) + ", Extra Data: " + self.extraData class TextFieldSync(ComponentSync): @@ -58,6 +92,9 @@ class TextFieldSync(ComponentSync): def __init__(self, **kwargs): super(TextFieldSync, self).__init__(**kwargs) + def sync(self): + self.send({"type": "sync"}) + class CheckboxSync(ComponentSync): _model_name = Unicode('CheckboxSync').tag(sync=True) diff --git a/src/jupyter_geppetto/geppetto_comm/GeppettoJupyterModelSync.py b/src/jupyter_geppetto/geppetto_comm/GeppettoJupyterModelSync.py index 1528374b0..08faff971 100644 --- a/src/jupyter_geppetto/geppetto_comm/GeppettoJupyterModelSync.py +++ b/src/jupyter_geppetto/geppetto_comm/GeppettoJupyterModelSync.py @@ -17,7 +17,8 @@ class EventsSync(widgets.Widget): _model_module = Unicode('jupyter_geppetto').tag(sync=True) _events = { 'Select': 'experiment:selection_changed', - 'Instances_created': "instances:created" + 'Instances_created': "instances:created", + 'Global_message': 'Global_message' } _eventsCallbacks = {} @@ -36,7 +37,8 @@ def _handle_event(self, _, content, buffers): content.get('geometryIdentifier', ''), content.get('point', '')) except Exception as e: - logging.exception( "Unexpected error executing callback on select event triggered:") + logging.exception( + "Unexpected error executing callback on select event triggered:") raise elif content.get('event', '') == self._events['Instances_created']: logging.debug("Instances_created Event triggered") @@ -45,8 +47,19 @@ def _handle_event(self, _, content, buffers): try: callback(content.get('data', '')) except Exception as e: - logging.exception( "Unexpected error executing callback on instances_created event triggered:") + logging.exception( + "Unexpected error executing callback on instances_created event triggered:") raise + elif content.get('event', '') == self._events['Global_message']: + logging.debug("Global message") + if self._events['Global_message'] in self._eventsCallbacks: + for callback in self._eventsCallbacks[self._events['Global_message']]: + try: + callback(content.get('id', ''), content.get('command', ''), content.get('parameters', '')) + except Exception as e: + logging.exception( "Unexpected error executing callback on Global_message event triggered:") + raise + def register_to_event(self, events, callback): for event in events: @@ -198,6 +211,8 @@ class ModelSync(widgets.Widget): geometries_raw = [] derived_state_variables = List(Instance(DerivedStateVariableSync)).tag( sync=True, **widgets.widget_serialization) + original_model = Unicode('').tag( + sync=True) def __init__(self, **kwargs): super(ModelSync, self).__init__(**kwargs) @@ -232,4 +247,4 @@ def highlight_visual_group_element(self, visual_group_element): self.send({"type": "highlight_visual_group_element", 'visual_group_element': visual_group_element}) def reload(self, module, model): - self.send({"type": "reload", 'module': module, 'model': model}) \ No newline at end of file + self.send({"type": "reload", 'module': module, 'model': model})