File: toolkit_dialog.py

package info (click to toggle)
python-enaml 0.19.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 13,284 kB
  • sloc: python: 31,443; cpp: 4,499; makefile: 140; javascript: 68; lisp: 53; sh: 20
file content (174 lines) | stat: -rw-r--r-- 5,255 bytes parent folder | download
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#------------------------------------------------------------------------------
# Copyright (c) 2013-2025, Nucleic Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file LICENSE, distributed with this software.
#------------------------------------------------------------------------------
from atom.api import Bool, Str, Typed, ForwardTyped, Event, Callable

from enaml.application import deferred_call
from enaml.core.declarative import d_, observe

from .toolkit_object import ToolkitObject, ProxyToolkitObject


class ProxyToolkitDialog(ProxyToolkitObject):
    """ The abstract definition of a proxy ToolkitDialog object.

    """
    #: A reference to the ToolkitDialog declaration.
    declaration = ForwardTyped(lambda: ToolkitDialog)

    def set_title(self, title):
        raise NotImplementedError

    def show(self):
        raise NotImplementedError

    def open(self):
        raise NotImplementedError

    def exec_(self):
        raise NotImplementedError

    def accept(self):
        raise NotImplementedError

    def reject(self):
        raise NotImplementedError


class ToolkitDialog(ToolkitObject):
    """ A base class for defining toolkit dialogs.

    A toolkit dialog is a dialog where the content is defined by the
    toolkit rather than the user. Customary examples would be a file
    dialog or a color selection dialog, where the implementation can
    often be a native operating system dialog.

    """
    #: The title of the dialog window.
    title = d_(Str())

    #: An optional callback which will be invoked when the dialog is
    #: closed. This is a convenience to make it easier to handle a
    #: dialog opened in non-blocking mode. The callback must accept
    #: a single argument, which will be the dialog instance.
    callback = d_(Callable())

    #: Whether to destroy the dialog widget on close. The default is
    #: True since dialogs are typically used in a transitory fashion.
    destroy_on_close = d_(Bool(True))

    #: An event fired if the dialog is accepted. It has no payload.
    accepted = d_(Event(), writable=False)

    #: An event fired when the dialog is rejected. It has no payload.
    rejected = d_(Event(), writable=False)

    #: An event fired when the dialog is finished. The payload is the
    #: boolean result of the dialog.
    finished = d_(Event(bool), writable=False)

    #: Whether or not the dialog was accepted by the user. It will be
    #: updated when the dialog is closed. This value is output only.
    result = Bool(False)

    #: A reference to the ProxyToolkitDialog object.
    proxy = Typed(ProxyToolkitDialog)

    def show(self):
        """ Open the dialog as a non modal dialog.

        """
        if not self.is_initialized:
            self.initialize()
        if not self.proxy_is_active:
            self.activate_proxy()
        self._prepare()
        self.proxy.show()

    def open(self):
        """ Open the dialog as a window modal dialog.

        """
        if not self.is_initialized:
            self.initialize()
        if not self.proxy_is_active:
            self.activate_proxy()
        self._prepare()
        self.proxy.open()

    def exec_(self):
        """ Open the dialog as an application modal dialog.

        Returns
        -------
        result : bool
            Whether or not the dialog was accepted.

        """
        if not self.is_initialized:
            self.initialize()
        if not self.proxy_is_active:
            self.activate_proxy()
        self._prepare()
        self.proxy.exec_()
        return self.result

    def accept(self):
        """ Accept the current state and close the dialog.

        """
        if self.proxy_is_active:
            self.proxy.accept()

    def reject(self):
        """ Reject the current state and close the dialog.

        """
        if self.proxy_is_active:
            self.proxy.reject()

    #--------------------------------------------------------------------------
    # Observers
    #--------------------------------------------------------------------------
    @observe('title')
    def _update_proxy(self, change):
        """ An observer which updates the proxy when the data changes.

        """
        # The superclass implementation is sufficient.
        super(ToolkitDialog, self)._update_proxy(change)

    #--------------------------------------------------------------------------
    # Utility Methods
    #--------------------------------------------------------------------------
    def _proxy_finished(self, result):
        """ Called by the proxy object when the dialog is finished.

        Parameters
        ----------
        result : bool
            Wether or not the dialog was accepted.

        """
        self.result = result
        self.finished(result)
        if result:
            self.accepted()
        else:
            self.rejected()
        if self.callback:
            self.callback(self)
        if self.destroy_on_close:
            deferred_call(self.destroy)

    def _prepare(self):
        """ Prepare the dialog to be shown.

        This method can be reimplemented by subclasses.

        """
        self.result = False