[share]Interactive MatplotLib backend
I had the idea to make a custom backend for matplotlib, to allow pythonista to be used with pylab as an interactive matlab of sorts. I found the show() functionality which dumped things to a console image to be hard to work with.
Currently this only works in the python 2.7 interpreter, due to a problem with the included matplotlib on py3 (subject of a future bug report ), but it is otherwise reasonably functional.
There is also a problem due to global clearing, which I have not yet found a workaround, other than the slow force reloading in the example code.
This has live figure windows, which can be moved , resized or minimized. These live inside the pythonista root window, so can be seen in the editor or console, and do not steal focus from the keyboard. Plots are updated interactively in real time for most operations.
For content views which do not have PanGestureRecognizers, which would be anything not in a scrollview or tableview, ui.Views do not take ownership of touches that occur in their bounds, and any type of touch motion gets stolen by the PA2SlidingPanel container. This has long been a complaint of mine ( presenting a custom view in a
panelbreaks any custom touch handling that is achieved by simple touch_moved), but using Gestures.py, it is possible to install a gesture recognizer that prevents the PA2SlidingPanel container from recognizing swipes if they are recognized by the custom view.
You can see the problem if you set the parent to Windows.detail in the original example, and try dragging the window left or right -- you get one move, then the pythonista panel starts sliding.
For content that use pans, the the only way to move would be through the title bar( another reason to not completely ditch the title bar), though perhaps using something like long press to switch between the content getting touch events, and the Overlay container getting the events.... Not sure. Floating interactive windows are not a concept used by iOS, (the ios9 PiP content is not interactive for example) so I don't know that anyone has thought through how they should work.
@JonB , sorry I dint really figure out how to make the change you pointed out to see the problem with panning.
If not too much trouble could you just write the change.
I have the original ready to try on.
I think I get what you are saying though. Still like to see it
@JonB , but anyway I really like how it fits in with minimal code. I realize you are not finished. But I really like when you can do something like the below. Meaning it seems natural to how things already work.
Getting the name from the content needs some help though. If content.name is None, error expects a string. Small thing I know, just let you know.
But one line and your overlay works in a normal senerio. That's great
class MyClass(ui.View): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.overlay = Overlay(content=self) self.make_view() def make_view(self): tbl = ui.TableView(frame=self.bounds) tbl.height -= 44 tbl.data_source = ui.ListDataSource(items = range(0, 100)) tbl.flex = 'wh' self.add_subview(tbl) if __name__=='__main__': f=(0,0,600, 800) mc = MyClass( name = 'My Table', frame = f)
@JonB , sorry, don't mean to bombard you post with senseless code. But this just seemed to small to put into a gist.
Anyway, the below is more inline with your original example about and fitting it into a so called normal use as I think of it anyway.
I thought It would be nice to see what happened when drawing into the content view. You would hope it all just works as it does. But I guess a lot is going on. Also nice to see that the alpha is working all the way back to underlying Windows.
class MyClass(ui.View): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.content_mode=ui.CONTENT_SCALE_ASPECT_FIT self.overlay = Overlay(content=self) self.overlay.content_view.touch_enabled = False def draw(self): w = self.width if self.width < self.height else self.height r = ui.Rect(0, 0, w, w).inset(5, 5) r.center(self.center) s = ui.Path.oval(*r) ui.set_color((255, 0, 0, .4)) s.fill() if __name__=='__main__': f=(0, 0, 300, 400) mc = MyClass( name = 'My Red Cirlce', frame = f)
@JonB, I don't know if this special or not. But I had both your original version running and my modified version running at the same time. So 2 different apps running at the same time. The overlays still working normally. Maybe you expected that. I launched the other version by mistake. That's pretty cool
Actually there is a third app running also. I was replying to the post in an app that is in a panel.
(in the latest github version)
@JonB , are you still refining the overlay class? Not sure about the real world use cases for it. But I think one real world use case is when you are making tools for ui. Look, I call it a floating palette, but toolbar or whatever. But can be be very handy if you want a bunch of cmds to act on a view without having to incorporate the interface into the view.
Just saying you might be more inclined to refine it in a certain direction if you can see a real world use for it.
Same idea as below...
yes that is a good idea. i probably ought to revive editmenu as an overlay...
@JonB , I really think it's a great idea. Granted it's not a normal iOS interface element. But many other uses also I suspect other than a floating toolbar/editmenu. Realtime property sheet of the current view for example. But it does something that is very unique. It can float and it's not modal.