File: i_field.py

package info (click to toggle)
python-pyface 6.1.2-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 11,756 kB
  • sloc: python: 39,728; makefile: 79
file content (175 lines) | stat: -rw-r--r-- 6,314 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
175
#------------------------------------------------------------------------------
# Copyright (c) 2017-19, Enthought, Inc.
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in enthought/LICENSE.txt and may be redistributed only
# under the conditions described in the aforementioned license.  The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
# Thanks for using Enthought open source!
#
# Author: Enthought, Inc.
# Description: <Enthought pyface package component>
#------------------------------------------------------------------------------
""" The text field interface. """

from __future__ import (
    absolute_import, division, print_function, unicode_literals
)

from traits.api import Any, HasTraits, Instance, Unicode

from pyface.i_widget import IWidget


class IField(IWidget):
    """ The field interface.

    A field is a widget that displays a value and (potentially) allows a user
    to interact with it.
    """

    #: The value held by the field.
    value = Any

    #: A tooltip for the field.
    tooltip = Unicode

    #: An optional context menu for the field.
    context_menu = Instance('pyface.action.menu_manager.MenuManager')

    def show_context_menu(self, x, y):
        """ Create and show the context menu at a position. """

    def _initialize_control(self, control):
        """ Perform any toolkit-specific initialization for the control. """


class MField(HasTraits):
    """ The field mix-in. """

    #: The value held by the field.
    value = Any

    #: A tooltip for the field.
    tooltip = Unicode

    #: An optional context menu for the field.
    context_menu = Instance('pyface.action.menu_manager.MenuManager')

    # ------------------------------------------------------------------------
    # IWidget interface
    # ------------------------------------------------------------------------

    def _add_event_listeners(self):
        """ Set up toolkit-specific bindings for events """
        super(MField, self)._add_event_listeners()
        self.on_trait_change(self._value_updated, 'value', dispatch='ui')
        self.on_trait_change(self._tooltip_updated, 'tooltip', dispatch='ui')
        self.on_trait_change(self._context_menu_updated, 'context_menu',
                             dispatch='ui')
        if self.control is not None and self.context_menu is not None:
            self._observe_control_context_menu()

    def _remove_event_listeners(self):
        """ Remove toolkit-specific bindings for events """
        if self.control is not None and self.context_menu is not None:
            self._observe_control_context_menu(remove=True)
        self.on_trait_change(self._value_updated, 'value', dispatch='ui',
                             remove=True)
        self.on_trait_change(self._tooltip_updated, 'tooltip', dispatch='ui',
                             remove=True)
        self.on_trait_change(self._context_menu_updated, 'context_menu',
                             dispatch='ui', remove=True)
        super(MField, self)._remove_event_listeners()

    # ------------------------------------------------------------------------
    # Private interface
    # ------------------------------------------------------------------------

    def _create(self):
        """ Creates the toolkit specific control.

        This method should create the control and assign it to the
        :py:attr:``control`` trait.
        """
        self.control = self._create_control(self.parent)
        self._initialize_control()
        self._add_event_listeners()

        self.show(self.visible)
        self.enable(self.enabled)

    def _initialize_control(self):
        """ Perform any toolkit-specific initialization for the control. """
        self._set_control_tooltip(self.tooltip)

    def _update_value(self, value):
        """ Handle a change to the value from user interaction

        This is a method suitable for calling from a toolkit event handler.
        """
        self.value = self._get_control_value()

    def _get_control(self):
        """ If control is not passed directly, get it from the trait. """
        control = self.control
        if control is None:
            raise RuntimeError("Toolkit control does not exist.")
        return control

    # Toolkit control interface ---------------------------------------------

    def _get_control_value(self):
        """ Toolkit specific method to get the control's value. """
        raise NotImplementedError

    def _set_control_value(self, value):
        """ Toolkit specific method to set the control's value. """
        raise NotImplementedError

    def _observe_control_value(self, remove=False):
        """ Toolkit specific method to change the control value observer. """
        raise NotImplementedError

    def _get_control_tooltip(self):
        """ Toolkit specific method to get the control's tooltip. """
        raise NotImplementedError

    def _set_control_tooltip(self, tooltip):
        """ Toolkit specific method to set the control's tooltip. """
        raise NotImplementedError

    def _observe_control_context_menu(self, remove=False):
        """ Toolkit specific method to change the control menu observer.

        This should use _handle_control_context_menu as the event handler.
        """
        raise NotImplementedError

    def _handle_control_context_menu(self, event):
        """ Handle a context menu event.

        This should call show_context_menu with appropriate position x and y
        arguments.

        The function signature will likely vary from toolkit to toolkit.
        """
        raise NotImplementedError

    # Trait change handlers -------------------------------------------------

    def _value_updated(self, value):
        if self.control is not None:
            self._set_control_value(value)

    def _tooltip_updated(self, tooltip):
        if self.control is not None:
            self._set_control_tooltip(tooltip)

    def _context_menu_updated(self, old, new):
        if self.control is not None:
            if new is None:
                self._observe_control_context_menu(remove=True)
            if old is None:
                self._observe_control_context_menu()