~kivy-team/kivy/master

426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
1
'''
426.113.27 by Mathieu Virbel
fixes app build with kv usage/root widget + others typo
2
Interactive launcher
3
====================
426.109.6 by Brian Knapp
Updatd docs and tried to fix some rest syntax but it's not done.
4
5
.. versionadded:: 1.3.0
426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
6
3339.1.1 by dessant
deprecate the interactive launcher
7
.. versionchanged:: 1.9.2
8
    The interactive launcher has been deprecated.
9
1655.1.6 by tshirtman
pep8 fixes for kivy/interactive.py
10
The :class:`InteractiveLauncher` provides a user-friendly python shell
11
interface to an :class:`App` so that it can be prototyped and debugged
12
interactively.
426.109.6 by Brian Knapp
Updatd docs and tried to fix some rest syntax but it's not done.
13
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
14
.. note::
15
16
    The Kivy API intends for some functions to only be run once or before the
2576.14.1 by Charles Merriam
Clean 'make style' spacing and long line errors'
17
    main EventLoop has started. Methods that can normally be called during the
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
18
    course of an application will work as intended, but specifically overriding
19
    methods such as :meth:`on_touch` dynamically leads to trouble.
426.109.6 by Brian Knapp
Updatd docs and tried to fix some rest syntax but it's not done.
20
426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
21
Creating an InteractiveLauncher
426.109.6 by Brian Knapp
Updatd docs and tried to fix some rest syntax but it's not done.
22
-------------------------------
426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
23
1499 by Zen-CODE
doc: revisions to interactive.py
24
Take your existing subclass of :class:`App` (this can be production code) and
3527.2.1 by Peter Badida
Fix typos and links
25
pass an instance to the :class:`InteractiveLauncher` constructor. ::
426.109.3 by Brian Knapp
Updated documentation and fixed some doc errors
26
27
    from kivy.interactive import InteractiveLauncher
28
    from kivy.app import App
29
    from kivy.uix.button import Button
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
30
426.109.3 by Brian Knapp
Updated documentation and fixed some doc errors
31
    class MyApp(App):
32
        def build(self):
3077 by Alexander Taylor
Update interactive.py
33
            return Button(text='Hello Shell')
426.109.3 by Brian Knapp
Updated documentation and fixed some doc errors
34
1586 by Mathieu Virbel
interactive: fix examples and add a note about how the examples can be runned. refs #1608
35
    launcher = InteractiveLauncher(MyApp())
36
    launcher.run()
426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
37
2131 by Zen-CODE
doc: make explicit that it needs to be the enter key
38
After pressing *enter*, the script will return. This allows the interpreter to
2130 by Zen-CODE
doc: added need for keypress to InteractiveLauncher docs
39
continue running. Inspection or modification of the :class:`App` can be done
40
safely through the InteractiveLauncher instance or the provided
41
:class:`SafeMembrane` class instances.
426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
42
1586 by Mathieu Virbel
interactive: fix examples and add a note about how the examples can be runned. refs #1608
43
.. note::
44
45
    If you want to test this example, start Python without any file to have
46
    already an interpreter, and copy/paste all the lines. You'll still have the
47
    interpreter at the end + the kivy application running.
48
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
49
Interactive Development
426.109.6 by Brian Knapp
Updatd docs and tried to fix some rest syntax but it's not done.
50
-----------------------
51
1499 by Zen-CODE
doc: revisions to interactive.py
52
IPython provides a fast way to learn the Kivy API. The :class:`App` instance
53
and all of it's attributes, including methods and the entire widget tree,
54
can be quickly listed by using the '.' operator and pressing 'tab'. Try this
3527.2.1 by Peter Badida
Fix typos and links
55
code in an Ipython shell. ::
426.109.6 by Brian Knapp
Updatd docs and tried to fix some rest syntax but it's not done.
56
426.109.15 by Brian Knapp
say no to buggy docs
57
    from kivy.interactive import InteractiveLauncher
426.225.19 by Bruno Gola
fixes typo in kivy/interactive.py documentation
58
    from kivy.app import App
426.109.6 by Brian Knapp
Updatd docs and tried to fix some rest syntax but it's not done.
59
    from kivy.uix.widget import Widget
60
    from kivy.graphics import Color, Ellipse
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
61
426.109.6 by Brian Knapp
Updatd docs and tried to fix some rest syntax but it's not done.
62
    class MyPaintWidget(Widget):
63
        def on_touch_down(self, touch):
64
            with self.canvas:
65
                Color(1, 1, 0)
66
                d = 30.
67
                Ellipse(pos=(touch.x - d/2, touch.y - d/2), size=(d, d))
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
68
69
426.109.6 by Brian Knapp
Updatd docs and tried to fix some rest syntax but it's not done.
70
    class TestApp(App):
71
        def build(self):
72
            return Widget()
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
73
74
426.109.6 by Brian Knapp
Updatd docs and tried to fix some rest syntax but it's not done.
75
    i = InteractiveLauncher(TestApp())
76
    i.run()
77
    i.       # press 'tab' to list attributes of the app
78
    i.root.  # press 'tab' to list attributes of the root widget
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
79
2576.14.1 by Charles Merriam
Clean 'make style' spacing and long line errors'
80
    # App is boring. Attach a new widget!
426.109.6 by Brian Knapp
Updatd docs and tried to fix some rest syntax but it's not done.
81
    i.root.add_widget(MyPaintWidget())
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
82
426.109.14 by Brian Knapp
updated docs.
83
    i.safeIn()
426.109.6 by Brian Knapp
Updatd docs and tried to fix some rest syntax but it's not done.
84
    # The application is now blocked.
85
    # Click on the screen several times.
426.109.14 by Brian Knapp
updated docs.
86
    i.safeOut()
426.109.6 by Brian Knapp
Updatd docs and tried to fix some rest syntax but it's not done.
87
    # The clicks will show up now
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
88
426.109.6 by Brian Knapp
Updatd docs and tried to fix some rest syntax but it's not done.
89
    # Erase artwork and start over
90
    i.root.canvas.clear()
426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
91
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
92
.. note::
93
426.109.9 by Brian Knapp
reST docs do not generate errors on make html.
94
    All of the proxies used in the module store their referent in the
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
95
    :attr:`_ref` attribute, which can be accessed directly if needed, such as
1499 by Zen-CODE
doc: revisions to interactive.py
96
    for getting doc strings. :func:`help` and :func:`type` will access the
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
97
    proxy, not its referent.
426.109.9 by Brian Knapp
reST docs do not generate errors on make html.
98
426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
99
Directly Pausing the Application
426.109.6 by Brian Knapp
Updatd docs and tried to fix some rest syntax but it's not done.
100
--------------------------------
426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
101
1499 by Zen-CODE
doc: revisions to interactive.py
102
Both the :class:`InteractiveLauncher` and :class:`SafeMembrane` hold internal
103
references to the :class:`EventLoop`'s 'safe' and 'confirmed'
104
:class:`threading.Event` objects. You can use their safing methods to control
426.109.8 by Brian Knapp
Tried to debug the reST docs. make html doesn't explicitly give any
105
the application manually.
426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
106
1499 by Zen-CODE
doc: revisions to interactive.py
107
:meth:`SafeMembrane.safeIn` will cause the application to pause and
108
:meth:`SafeMembrane.safeOut` will allow a paused application
109
to continue running. This is potentially useful for scripting actions into
110
functions that need the screen to update etc.
426.109.8 by Brian Knapp
Tried to debug the reST docs. make html doesn't explicitly give any
111
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
112
.. note::
113
1586 by Mathieu Virbel
interactive: fix examples and add a note about how the examples can be runned. refs #1608
114
    The pausing is implemented via the
1503 by Zen-CODE
doc: fixed link to Clock, broke into two parts
115
    :class:`Clocks' <kivy.clock.Clock>`
116
    :meth:`~kivy.clock.ClockBase.schedule_once` method
117
    and occurs before the start of each frame.
426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
118
119
Adding Attributes Dynamically
426.109.6 by Brian Knapp
Updatd docs and tried to fix some rest syntax but it's not done.
120
-----------------------------
426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
121
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
122
.. note::
123
426.109.9 by Brian Knapp
reST docs do not generate errors on make html.
124
    This module uses threading and object proxies to encapsulate the running
1499 by Zen-CODE
doc: revisions to interactive.py
125
    :class:`App`. Deadlocks and memory corruption can occur if making direct
426.109.9 by Brian Knapp
reST docs do not generate errors on make html.
126
    references inside the thread without going through the provided proxy(s).
127
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
128
The :class:`InteractiveLauncher` can have attributes added to it exactly like a
1499 by Zen-CODE
doc: revisions to interactive.py
129
normal object and if these were created from outside the membrane, they will
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
130
not be threadsafe because the external references to them in the python
1655.1.6 by tshirtman
pep8 fixes for kivy/interactive.py
131
interpreter do not go through InteractiveLauncher's membrane behavior,
132
inherited from :class:`SafeMembrane`.
426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
133
1500 by Zen-CODE
doc: fix spelling in interactive.py
134
To threadsafe these external references, simply assign them to
1499 by Zen-CODE
doc: revisions to interactive.py
135
:class:`SafeMembrane` instances of themselves like so::
426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
136
426.109.15 by Brian Knapp
say no to buggy docs
137
    from kivy.interactive import SafeMembrane
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
138
426.109.3 by Brian Knapp
Updated documentation and fixed some doc errors
139
    interactiveLauncher.attribute = myNewObject
140
    # myNewObject is unsafe
141
    myNewObject = SafeMembrane(myNewObject)
2576.14.1 by Charles Merriam
Clean 'make style' spacing and long line errors'
142
    # myNewObject is now safe. Call at will.
426.109.3 by Brian Knapp
Updated documentation and fixed some doc errors
143
    myNewObject.method()
426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
144
426.109.6 by Brian Knapp
Updatd docs and tried to fix some rest syntax but it's not done.
145
TODO
146
====
147
1499 by Zen-CODE
doc: revisions to interactive.py
148
Unit tests, examples, and a better explanation of which methods are safe in a
149
running application would be nice. All three would be excellent.
426.109.6 by Brian Knapp
Updatd docs and tried to fix some rest syntax but it's not done.
150
3527.2.1 by Peter Badida
Fix typos and links
151
Could be re-written with a context-manager style i.e. ::
426.109.14 by Brian Knapp
updated docs.
152
153
    with safe:
154
        foo()
155
156
Any use cases besides compacting code?
157
426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
158
'''
159
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
160
__all__ = ('SafeMembrane', 'InteractiveLauncher')
426.109.14 by Brian Knapp
updated docs.
161
2833.1.1 by dessant
style issues fixed
162
import inspect
3339.1.1 by dessant
deprecate the interactive launcher
163
from threading import Thread, Event
2833.1.1 by dessant
style issues fixed
164
426.109.1 by Brian Knapp
Added kivy.interactive, which contains classes to run any App instance
165
from kivy.app import App
166
from kivy.base import EventLoop
426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
167
from kivy.clock import Clock
3339.1.1 by dessant
deprecate the interactive launcher
168
from kivy.utils import deprecated
426.109.1 by Brian Knapp
Added kivy.interactive, which contains classes to run any App instance
169
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
170
426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
171
def safeWait(dt):
172
    EventLoop.confirmed.set()
173
    EventLoop.safe.wait()
174
    EventLoop.confirmed.clear()
426.109.1 by Brian Knapp
Added kivy.interactive, which contains classes to run any App instance
175
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
176
426.109.13 by Brian Knapp
Added unwrapping behavior to prevent SafeMembrane from injecting
177
def unwrap(ob):
178
    while type(ob) == SafeMembrane:
179
        ob = ob._ref
180
    return ob
181
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
182
426.109.1 by Brian Knapp
Added kivy.interactive, which contains classes to run any App instance
183
class SafeMembrane(object):
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
184
    '''
1499 by Zen-CODE
doc: revisions to interactive.py
185
    This help is for a proxy object. Did you want help on the proxy's referent
186
    instead? Try using help(<instance>._ref)
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
187
1499 by Zen-CODE
doc: revisions to interactive.py
188
    The SafeMembrane is a threadsafe proxy that also returns attributes as new
189
    thread-safe objects
426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
190
    and makes thread-safe method calls, preventing thread-unsafe objects
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
191
    from leaking into the user's environment.
192
    '''
193
1775.1.1 by Ian McCowan
Fixes #1847.
194
    __slots__ = ('_ref', 'safe', 'confirmed')
426.109.1 by Brian Knapp
Added kivy.interactive, which contains classes to run any App instance
195
426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
196
    def __init__(self, ob, *args, **kwargs):
426.109.5 by Brian Knapp
Fixed a few bugs. Need to write more tests.
197
        self.confirmed = EventLoop.confirmed
198
        self.safe = EventLoop.safe
426.109.8 by Brian Knapp
Tried to debug the reST docs. make html doesn't explicitly give any
199
        self._ref = ob
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
200
426.109.1 by Brian Knapp
Added kivy.interactive, which contains classes to run any App instance
201
    def safeIn(self):
1499 by Zen-CODE
doc: revisions to interactive.py
202
        """Provides a thread-safe entry point for interactive launching."""
426.109.1 by Brian Knapp
Added kivy.interactive, which contains classes to run any App instance
203
        self.safe.clear()
426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
204
        Clock.schedule_once(safeWait, -1)
426.109.1 by Brian Knapp
Added kivy.interactive, which contains classes to run any App instance
205
        self.confirmed.wait()
206
207
    def safeOut(self):
1499 by Zen-CODE
doc: revisions to interactive.py
208
        """Provides a thread-safe exit point for interactive launching."""
426.109.1 by Brian Knapp
Added kivy.interactive, which contains classes to run any App instance
209
        self.safe.set()
210
211
    def isMethod(self, fn):
2833.1.1 by dessant
style issues fixed
212
        return inspect.ismethod(fn)
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
213
214
    # Everything from this point on is just a series of thread-safing proxy
215
    # methods that make calls against _ref and threadsafe whenever data will be
2576.14.1 by Charles Merriam
Clean 'make style' spacing and long line errors'
216
    # written to or if a method will be called. SafeMembrane instances should
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
217
    # be unwrapped whenever passing them into the thread
3773.4.12 by Meet Udeshi
Remove pep8 E265 from all files
218
    # use type() to determine if an object is a SafeMembrane while debugging
426.109.1 by Brian Knapp
Added kivy.interactive, which contains classes to run any App instance
219
    def __repr__(self):
426.109.8 by Brian Knapp
Tried to debug the reST docs. make html doesn't explicitly give any
220
        return self._ref.__repr__()
426.109.1 by Brian Knapp
Added kivy.interactive, which contains classes to run any App instance
221
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
222
    def __call__(self, *args, **kw):
426.109.1 by Brian Knapp
Added kivy.interactive, which contains classes to run any App instance
223
        self.safeIn()
899.37.1 by Mathieu Virbel
first 2to3 pass + manual fix for metaclass, UserDict and OrderedDict
224
        args = list(map(unwrap, args))
225
        for k in list(kw.keys()):
426.109.13 by Brian Knapp
Added unwrapping behavior to prevent SafeMembrane from injecting
226
            kw[k] = unwrap(kw[k])
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
227
        r = self._ref(*args, **kw)
426.109.1 by Brian Knapp
Added kivy.interactive, which contains classes to run any App instance
228
        self.safeOut()
426.109.12 by Brian Knapp
All SafeMembrane returns, including functions, converted to return
229
        if r is not None:
230
            return SafeMembrane(r)
426.109.1 by Brian Knapp
Added kivy.interactive, which contains classes to run any App instance
231
232
    def __getattribute__(self, attr, oga=object.__getattribute__):
426.184.22 by Mathieu Virbel
update pep8 contrib, and fix all the last warning from "make style".
233
        if attr.startswith('__') or attr == '_ref':
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
234
            subject = oga(self, '_ref')
235
            if attr == '_ref':
426.109.1 by Brian Knapp
Added kivy.interactive, which contains classes to run any App instance
236
                return subject
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
237
            return getattr(subject, attr)
238
        return oga(self, attr)
426.109.1 by Brian Knapp
Added kivy.interactive, which contains classes to run any App instance
239
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
240
    def __getattr__(self, attr, oga=object.__getattribute__):
241
        r = getattr(oga(self, '_ref'), attr)
426.109.12 by Brian Knapp
All SafeMembrane returns, including functions, converted to return
242
        return SafeMembrane(r)
426.109.1 by Brian Knapp
Added kivy.interactive, which contains classes to run any App instance
243
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
244
    def __setattr__(self, attr, val, osa=object.__setattr__):
245
        if (attr == '_ref'
1655.1.6 by tshirtman
pep8 fixes for kivy/interactive.py
246
                or hasattr(type(self), attr) and not attr.startswith('__')):
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
247
            osa(self, attr, val)
426.109.1 by Brian Knapp
Added kivy.interactive, which contains classes to run any App instance
248
        else:
249
            self.safeIn()
426.109.13 by Brian Knapp
Added unwrapping behavior to prevent SafeMembrane from injecting
250
            val = unwrap(val)
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
251
            setattr(self._ref, attr, val)
426.109.1 by Brian Knapp
Added kivy.interactive, which contains classes to run any App instance
252
            self.safeOut()
426.109.9 by Brian Knapp
reST docs do not generate errors on make html.
253
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
254
    def __delattr__(self, attr, oda=object.__delattr__):
426.109.9 by Brian Knapp
reST docs do not generate errors on make html.
255
        self.safeIn()
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
256
        delattr(self._ref, attr)
426.109.9 by Brian Knapp
reST docs do not generate errors on make html.
257
        self.safeOut()
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
258
899.37.1 by Mathieu Virbel
first 2to3 pass + manual fix for metaclass, UserDict and OrderedDict
259
    def __bool__(self):
426.109.9 by Brian Knapp
reST docs do not generate errors on make html.
260
        return bool(self._ref)
261
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
262
    def __getitem__(self, arg):
426.109.12 by Brian Knapp
All SafeMembrane returns, including functions, converted to return
263
        return SafeMembrane(self._ref[arg])
426.109.9 by Brian Knapp
reST docs do not generate errors on make html.
264
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
265
    def __setitem__(self, arg, val):
426.109.9 by Brian Knapp
reST docs do not generate errors on make html.
266
        self.safeIn()
426.109.13 by Brian Knapp
Added unwrapping behavior to prevent SafeMembrane from injecting
267
        val = unwrap(val)
426.109.9 by Brian Knapp
reST docs do not generate errors on make html.
268
        self._ref[arg] = val
269
        self.safeOut()
270
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
271
    def __delitem__(self, arg):
426.109.9 by Brian Knapp
reST docs do not generate errors on make html.
272
        self.safeIn()
273
        del self._ref[arg]
274
        self.safeOut()
275
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
276
    def __getslice__(self, i, j):
426.109.12 by Brian Knapp
All SafeMembrane returns, including functions, converted to return
277
        return SafeMembrane(self._ref[i:j])
426.109.9 by Brian Knapp
reST docs do not generate errors on make html.
278
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
279
    def __setslice__(self, i, j, val):
426.109.9 by Brian Knapp
reST docs do not generate errors on make html.
280
        self.safeIn()
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
281
        val = unwrap(val)
426.109.9 by Brian Knapp
reST docs do not generate errors on make html.
282
        self._ref[i:j] = val
283
        self.safeOut()
284
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
285
    def __delslice__(self, i, j):
426.109.9 by Brian Knapp
reST docs do not generate errors on make html.
286
        self.safeIn()
287
        del self._ref[i:j]
288
        self.safeOut()
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
289
426.109.16 by Brian Knapp
Added support for context managers by adding __enter__ and __exit__
290
    def __enter__(self, *args, **kwargs):
426.109.17 by Brian Knapp
forgot safing lines
291
        self.safeIn()
426.109.16 by Brian Knapp
Added support for context managers by adding __enter__ and __exit__
292
        self._ref.__enter__(*args, **kwargs)
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
293
426.109.16 by Brian Knapp
Added support for context managers by adding __enter__ and __exit__
294
    def __exit__(self, *args, **kwargs):
295
        self._ref.__exit__(*args, **kwargs)
426.109.17 by Brian Knapp
forgot safing lines
296
        self.safeOut()
426.109.9 by Brian Knapp
reST docs do not generate errors on make html.
297
426.109.14 by Brian Knapp
updated docs.
298
426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
299
class InteractiveLauncher(SafeMembrane):
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
300
    '''
301
    Proxy to an application instance that launches it in a thread and
1499 by Zen-CODE
doc: revisions to interactive.py
302
    then returns and acts as a proxy to the application in the thread.
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
303
    '''
304
305
    __slots__ = ('_ref', 'safe', 'confirmed', 'thread', 'app')
306
3339.1.1 by dessant
deprecate the interactive launcher
307
    @deprecated
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
308
    def __init__(self, app=None, *args, **kwargs):
309
        if app is None:
310
            app = App()
426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
311
        EventLoop.safe = Event()
312
        self.safe = EventLoop.safe
313
        self.safe.set()
314
        EventLoop.confirmed = Event()
315
        self.confirmed = EventLoop.confirmed
316
        self.app = app
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
317
426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
318
        def startApp(app=app, *args, **kwargs):
319
            app.run(*args, **kwargs)
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
320
426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
321
        self.thread = Thread(target=startApp, *args, **kwargs)
322
323
    def run(self):
324
        self.thread.start()
3773.4.12 by Meet Udeshi
Remove pep8 E265 from all files
325
        # Proxy behavior starts after this is set. Before this point, attaching
326
        # widgets etc can only be done through the Launcher's app attribute
426.109.8 by Brian Knapp
Tried to debug the reST docs. make html doesn't explicitly give any
327
        self._ref = self.app
426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
328
329
    def stop(self):
330
        EventLoop.quit = True
331
        self.thread.join()
426.106.9 by Mathieu Virbel
fixes for kivy.interactive
332
3773.4.12 by Meet Udeshi
Remove pep8 E265 from all files
333
    # Act like the app instance even before _ref is set
426.109.2 by Brian Knapp
Re-wrote using kivy.Clock and making InteractiveLauncher itself into the
334
    def __repr__(self):
335
        return self.app.__repr__()