enthought / traitsui
1
# ------------------------------------------------------------------------------
2
#
3
#  Copyright (c) 2005-19, Enthought, Inc.
4
#  All rights reserved.
5
#
6
#  This software is provided without warranty under the terms of the BSD
7
#  license included in LICENSE.txt and may be redistributed only
8
#  under the conditions described in the aforementioned license.  The license
9
#  is also available online at http://www.enthought.com/licenses/BSD.txt
10
#
11
#  Thanks for using Enthought open source!
12
#
13
#  Author: David C. Morrill
14
#  Date:   10/25/2004
15
#
16
# ------------------------------------------------------------------------------
17

18 4
""" Defines various helper functions that are useful for creating Traits-based
19
    user interfaces.
20
"""
21

22 4
from operator import itemgetter
23

24 4
from traits.api import BaseTraitHandler, CTrait, Enum, TraitError
25

26

27
# -------------------------------------------------------------------------
28
#  Trait definitions:
29
# -------------------------------------------------------------------------
30

31
# Layout orientation for a control and its associated editor
32 4
Orientation = Enum("horizontal", "vertical")
33

34
# Docking drag bar style:
35 4
DockStyle = Enum("horizontal", "vertical", "tab", "fixed")
36

37

38 4
def user_name_for(name):
39
    """ Returns a "user-friendly" name for a specified trait.
40
    """
41 4
    name = name.replace("_", " ")
42 4
    name = name[:1].upper() + name[1:]
43 4
    result = ""
44 4
    last_lower = 0
45 4
    for c in name:
46 4
        if c.isupper() and last_lower:
47 0
            result += " "
48 4
        last_lower = c.islower()
49 4
        result += c
50 4
    return result
51

52

53 4
def commatize(value):
54
    """ Formats a specified value as an integer string with embedded commas.
55
        For example: commatize( 12345 ) returns "12,345".
56
    """
57 0
    s = str(abs(value))
58 0
    s = s.rjust(((len(s) + 2) / 3) * 3)
59 4
    result = ",".join([s[i: i + 3] for i in range(0, len(s), 3)]).lstrip()
60 4
    if value >= 0:
61 0
        return result
62

63 0
    return "-" + result
64

65

66 4
def enum_values_changed(values, strfunc=str):
67
    """ Recomputes the mappings for a new set of enumeration values.
68
    """
69

70 4
    if isinstance(values, dict):
71 4
        data = [(strfunc(v), n) for n, v in values.items()]
72 4
        if len(data) > 0:
73 0
            data.sort(key=itemgetter(0))
74 0
            col = data[0][0].find(":") + 1
75 4
            if col > 0:
76 4
                data = [(n[col:], v) for n, v in data]
77 4
    elif not isinstance(values, SequenceTypes):
78 1
        handler = values
79 4
        if isinstance(handler, CTrait):
80 0
            handler = handler.handler
81 4
        if not isinstance(handler, BaseTraitHandler):
82 0
            raise TraitError("Invalid value for 'values' specified")
83 4
        if handler.is_mapped:
84 4
            data = [(strfunc(n), n) for n in handler.map.keys()]
85 0
            data.sort(key=itemgetter(0))
86
        else:
87 4
            data = [(strfunc(v), v) for v in handler.values]
88
    else:
89 4
        data = [(strfunc(v), v) for v in values]
90

91 4
    names = [x[0] for x in data]
92 4
    mapping = {}
93 4
    inverse_mapping = {}
94 4
    for name, value in data:
95 4
        mapping[name] = value
96 4
        inverse_mapping[value] = name
97

98 4
    return (names, mapping, inverse_mapping)
99

100

101 4
def compute_column_widths(available_space, requested, min_widths, user_widths):
102
    """ Distribute column space amongst columns based on requested space.
103

104
    Widths requests can be specified as one of the following:
105

106
    - a value greater than 1.0 is treated as a fixed width with no flexibility
107
      (ie. a minimum width as specified and a weight of 0.0)
108

109
    - a value between 0.0 and 1.0 is treaded as a flexible width column with
110
      the specified width as a weight and a minimum width provided by the
111
      min_widths entry.
112

113
    - a value less than or equal to 0.0 is treated as a flexible width column
114
      with a weight of 0.1 and a minimum width provided by the min_widths
115
      parameter.
116

117
    If user widths are supplied then any non-None values override the
118
    requested widths, and are treated as having a flexibility of 0.
119

120
    Space is distributed by evaluating each column from smallest weight to
121
    largest and seeing if the weighted proportion of the remaining space is
122
    more than the minimum, and if so replacing the width with the weighted
123
    width.  The column is then removed from the available width and the
124
    total weight and the analysis continues.
125

126
    Parameters
127
    ----------
128
    available_space : int
129
        The available horizontal space.
130
    requested : list of numbers
131
        The requested width or weight for each column.
132
    min_widths : None or list of ints
133
        The minimum width for each flexible column
134
    user_widths : None or list of int or None
135
        Any widths specified by the user resizing the columns manually.
136

137
    Returns
138
    -------
139
    widths : list of ints
140
        The assigned width for each column
141
    """
142 4
    widths = []
143 4
    weights = []
144 4
    if min_widths is None:
145 4
        min_widths = [30] * len(requested)
146

147
    # determine flexibility and default width of each column
148 4
    for request, min_width in zip(requested, min_widths):
149 4
        if request >= 1.0:
150 4
            weights.append(0.0)
151 4
            widths.append(int(request))
152
        else:
153 4
            if request <= 0:
154 4
                weights.append(0.1)
155
            else:
156 4
                weights.append(request)
157 4
            widths.append(min_width)
158

159
    # if the user has changed the width of a column manually respect that
160 4
    if user_widths is not None:
161 4
        for i, user_width in enumerate(user_widths):
162 4
            if user_width is not None:
163 4
                widths[i] = user_width
164 4
                weights[i] = 0.0
165

166 4
    total_weight = sum(weights)
167 4
    if sum(widths) < available_space and total_weight > 0:
168
        # do inflexible first, then work up from smallest to largest
169 4
        for i, weight in sorted(enumerate(weights), key=itemgetter(1, 0)):
170 4
            total_weight = sum(weights)
171 4
            stretched = int(weight / total_weight * available_space)
172 4
            widths[i] = max(stretched, widths[i])
173

174
            # once we have dealt with a column, it no longer counts as flexible
175
            # and its space is no longer available
176 4
            weights[i] = 0.0
177 4
            available_space -= widths[i]
178

179 4
    return widths
180

181

182
# -------------------------------------------------------------------------
183
#  Other definitions:
184
# -------------------------------------------------------------------------
185

186 4
SequenceTypes = (tuple, list)
187

188

189
# -------------------------------------------------------------------------
190
#  Wrapper for TraitPrefixList deprecation:
191
# -------------------------------------------------------------------------
192

193 4
try:
194 4
    from traits.api import PrefixList
195 1
except ImportError:
196 1
    def PrefixList(list_, default_value=None, **kwargs):
197 1
        from traits.api import Trait, TraitPrefixList
198 4
        if default_value is None:
199 1
            default_value = list_[0]
200 1
        return Trait(default_value, TraitPrefixList(list_), **kwargs)

Read our documentation on viewing source code .

Loading