WorldWideTelescope / pywwt

Python interface to WorldWide Telescope :milky_way:
https://pywwt.readthedocs.io
BSD 3-Clause "New" or "Revised" License
51 stars 15 forks source link

Robustify JupyterLab experience: multiple views for one widget model #241

Open pkgw opened 5 years ago

pkgw commented 5 years ago

The Jupyter/ipywidgets model for how custom widgets work is fairly complex. Not only do widgets have representations on both the Python and JavaScript sides that must talk to each other, there can also be multiple JS views for the same widget model (as in this example).

pywwt currently does not do a good job of handling the case of there being multiple views for one WWT widget. This is an issue for us because people are really going to want to open up a WWT window in JupyterLab and then use the "Create new view for output" command to pop open the WWT view in a separate pane, while they type Python away in their notebook pane. This action indeed results in there being two views for the same widget model, and they can get out of sync in various ways. It's important to note here that there are two kinds of "out of sync" that can happen. The two views might be pointed at different RA/Dec coordinates, which doesn't seem like an unreasonable thing to support. But the two views might also have inconsistent sets of data layers loaded, which IMO is something we strongly do not want. This can happen if you create a widget, load a data layer, and then use the "create new view" function: the new pane won't contain the data layer.

I think it will be important for the pywwt/Jupyter experience to make sure that we have a solid foundation for dealing with these complexities. It's tricky for us because the WWT engine does not expose any kind of model/view architecture: each pywwt widget view must contain a full WWT engine that mixes both model-y and view-y state. So, short of a dramatic restructuring of the JS engine, I think we're going to have to manually keep everything in sync somehow. Either that, or perhaps the most reasonable approach would be to only have one "active" pywwt widget view that contains the WWT engine iframe, and other views just contain a big button that says "click to move WWT here", and we reparent the iframe around as widget views come and go.

xref #210 since I suspect that having a solid story about Python <=> JS communication in Jupyter will also be an important piece of the puzzle.

pkgw commented 5 years ago

Also note that if we do want to support multiple active views for one pywwt Jupyter widget with different pointing centers, the function wwt.get_center() becomes ill-defined.

pkgw commented 4 years ago

I had had the idea that maybe a good solution would be to create a single WWT <iframe> and move it between different "views", leaving old views blank (or maybe with a button saying "Bring WWT back here").

It turns out this won't work, because when you reparent an iframe its inner document gets reloaded. This erases all of the WWT state, which I think pretty much kills the idea of warping the WWT view from one place to another.