File: constrainable.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 (185 lines) | stat: -rw-r--r-- 5,665 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
176
177
178
179
180
181
182
183
184
185
#------------------------------------------------------------------------------
# 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 abc import ABCMeta

from atom.api import Atom, Constant, DefaultValue, Enum

import kiwisolver as kiwi


class Constrainable(object, metaclass=ABCMeta):
    """ An abstract base class for defining constrainable objects.

    Implementations must provide `top`, `bottom`, `left`, `right`,
    `width`, `height`, `v_center` and `h_center` attributes which
    are instances of 'LinearSymbolic'.

    It must also provide 'hug_width', 'hug_height', 'resist_width',
    'resist_height', 'limit_width', and 'limit_height' attributes
    which are valid PolicyEnum values.

    """


class ContentsConstrainable(Constrainable):
    """ An abstract base class for contents constrainable objects.

    A contents constrainable object has additional linear symbolic
    attributes with the prefix 'contents_' for all of the symbolic
    attributes defined by Constrainable.

    """
    pass


class ConstraintMember(Constant):
    """ A custom Constant member that generates a kiwi Variable.

    """
    __slots__ = ()

    def __init__(self):
        super(ConstraintMember, self).__init__()
        mode = DefaultValue.MemberMethod_Object
        self.set_default_value_mode(mode, 'default')

    def default(self, owner):
        return kiwi.Variable(self.name)


#: An atom enum which defines the allowable constraints strengths.
#: Clones will be made by selecting a new default via 'select'.
PolicyEnum = Enum('ignore', 'weak', 'medium', 'strong', 'required')


class ConstrainableMixin(Atom):
    """ An atom mixin class which defines constraint members.

    This class implements the Constrainable interface.

    """
    #: The symbolic left boundary of the constrainable.
    left = ConstraintMember()

    #: The symbolic top boundary of the constrainable.
    top = ConstraintMember()

    #: The symbolic width of the constrainable.
    width = ConstraintMember()

    #: The symbolic height of the constrainable.
    height = ConstraintMember()

    #: A symbolic expression representing the top boundary.
    right = Constant()

    #: A symbolic expression representing the bottom boundary.
    bottom = Constant()

    #: A symbolic expression representing the horizontal center.
    h_center = Constant()

    #: A symbolic expression representing the vertical center.
    v_center = Constant()

    #: How strongly a widget hugs it's width hint. This is equivalent
    #: to the constraint::
    #:
    #:      (width == hint) | hug_width
    hug_width = PolicyEnum('strong')

    #: How strongly a widget hugs it's height hint. This is equivalent
    #: to the constraint::
    #:
    #:      (height == hint) | hug_height
    hug_height = PolicyEnum('strong')

    #: How strongly a widget resists clipping its width hint. This is
    #: equivalent to the constraint:
    #:
    #:      (width >= hint) | resist_width
    resist_width = PolicyEnum('strong')

    #: How strongly a widget resists clipping its height hint. This is
    #: equivalent to the constraint::
    #:
    #:      (height >= hint) | resist_height
    resist_height = PolicyEnum('strong')

    #: How strongly a widget resists expanding its width hint. This is
    #: equivalent to the constraint::
    #:
    #:      (width <= hint) | limit_width
    limit_width = PolicyEnum('ignore')

    #: How strongly a widget resists expanding its height hint. This is
    #: equivalent to the constraint::
    #:
    #:      (height <= hint) | limit_height
    limit_height = PolicyEnum('ignore')

    def _default_right(self):
        return self.left + self.width

    def _default_bottom(self):
        return self.top + self.height

    def _default_h_center(self):
        return self.left + 0.5 * self.width

    def _default_v_center(self):
        return self.top + 0.5 * self.height


Constrainable.register(ConstrainableMixin)


class ContentsConstrainableMixin(ConstrainableMixin):
    """ An atom mixin class which defines contents constraint members.

    This class implements the ContentsConstrainable interface.

    """
    #: The symbolic left contents boundary of the constrainable.
    contents_left = ConstraintMember()

    #: The symbolic right contents boundary of the constrainable.
    contents_right = ConstraintMember()

    #: The symbolic top contents boundary of the constrainable.
    contents_top = ConstraintMember()

    #: The symbolic bottom contents boundary of the constrainable.
    contents_bottom = ConstraintMember()

    #: A symbolic expression representing the content width.
    contents_width = Constant()

    #: A symbolic expression representing the content height.
    contents_height = Constant()

    #: A symbolic expression representing the content horizontal center.
    contents_h_center = Constant()

    #: A symbolic expression representing the content vertical center.
    contents_v_center = Constant()

    def _default_contents_width(self):
        return self.contents_right - self.contents_left

    def _default_contents_height(self):
        return self.contents_bottom - self.contents_top

    def _default_contents_h_center(self):
        return self.contents_left + 0.5 * self.contents_width

    def _default_contents_v_center(self):
        return self.contents_top + 0.5 * self.contents_height


ContentsConstrainable.register(ContentsConstrainableMixin)