1 0
import wx
2

3 0
from traits.api import Float, Any, Str, Either
4 0
from traitsui.editors.api import RangeEditor
5 0
from traitsui.wx.editor import Editor
6 0
from traitsui.wx.helper import TraitsUIPanel, Slider
7

8

9

10 0
class _BoundsEditor(Editor):
11

12 0
    evaluate = Any()
13

14 0
    min = Any()
15 0
    max = Any()
16 0
    low = Any()
17 0
    high = Any()
18 0
    format = Str()
19

20 0
    def init(self, parent):
21
        """ Finishes initializing the editor by creating the underlying toolkit
22
            widget.
23
        """
24 0
        factory = self.factory
25 11
        if not factory.low_name:
26 0
            self.low = factory.low
27 0
            self.min = self.low
28

29 11
        if not factory.high_name:
30 0
            self.high = factory.high
31 0
            self.max = self.high
32

33 0
        self.max = factory.max
34 0
        self.min = factory.min
35

36 0
        self.format = factory.format
37

38 0
        self.evaluate = factory.evaluate
39 0
        self.sync_value(factory.evaluate_name, "evaluate", "from")
40

41 0
        self.sync_value(factory.low_name, "low", "both")
42 0
        self.sync_value(factory.high_name, "high", "both")
43

44 0
        self.control = panel = TraitsUIPanel(parent, -1)
45 0
        sizer = wx.FlexGridSizer(2, 3, 0, 0)
46

47
        # low text box
48 0
        self._label_lo = wx.TextCtrl(
49
            panel,
50
            -1,
51
            self.format % self.low,
52
            size=wx.Size(56, 20),
53
            style=wx.TE_PROCESS_ENTER,
54
        )
55 0
        sizer.Add(self._label_lo, 0, wx.ALIGN_CENTER)
56 0
        self._label_lo.Bind(wx.EVT_TEXT_ENTER, self.update_low_on_enter)
57 0
        self._label_lo.Bind(wx.EVT_KILL_FOCUS, self.update_low_on_enter)
58

59
        # low slider
60 0
        self.control.lslider = Slider(
61
            panel,
62
            -1,
63
            0,
64
            0,
65
            10000,
66
            size=wx.Size(100, 20),
67
            style=wx.SL_HORIZONTAL | wx.SL_AUTOTICKS,
68
        )
69 0
        self.control.lslider.SetValue(self._convert_to_slider(self.low))
70 0
        self.control.lslider.SetTickFreq(1000, 1)
71 0
        self.control.lslider.SetPageSize(1000)
72 0
        self.control.lslider.SetLineSize(100)
73 0
        self.control.lslider.Bind(wx.EVT_SCROLL, self.update_object_on_scroll)
74 0
        sizer.Add(self.control.lslider, 1, wx.EXPAND)
75 0
        sizer.AddStretchSpacer(0)
76

77
        # high slider
78 0
        sizer.AddStretchSpacer(0)
79 0
        self.control.rslider = Slider(
80
            panel,
81
            -1,
82
            self._convert_to_slider(self.high),
83
            0,
84
            10000,
85
            size=wx.Size(100, 20),
86
            style=wx.SL_HORIZONTAL | wx.SL_AUTOTICKS,
87
        )
88 0
        self.control.rslider.SetTickFreq(1000, 1)
89 0
        self.control.rslider.SetPageSize(1000)
90 0
        self.control.rslider.SetLineSize(100)
91 0
        self.control.rslider.Bind(wx.EVT_SCROLL, self.update_object_on_scroll)
92 0
        sizer.Add(self.control.rslider, 1, wx.EXPAND)
93

94
        # high text box
95 0
        self._label_hi = wx.TextCtrl(
96
            panel,
97
            -1,
98
            self.format % self.high,
99
            size=wx.Size(56, 20),
100
            style=wx.TE_PROCESS_ENTER,
101
        )
102 0
        sizer.Add(self._label_hi, 0, wx.ALIGN_CENTER)
103 0
        self._label_hi.Bind(wx.EVT_TEXT_ENTER, self.update_high_on_enter)
104 0
        self._label_hi.Bind(wx.EVT_KILL_FOCUS, self.update_high_on_enter)
105

106 0
        self.set_tooltip(self.control.lslider)
107 0
        self.set_tooltip(self.control.rslider)
108 0
        self.set_tooltip(self._label_lo)
109 0
        self.set_tooltip(self._label_hi)
110

111
        # Set-up the layout:
112 0
        panel.SetSizerAndFit(sizer)
113

114 0
    def dispose(self):
115 0
        self._label_hi.Unbind(wx.EVT_TEXT_ENTER)
116 0
        self._label_hi.Unbind(wx.EVT_KILL_FOCUS)
117 0
        self._label_lo.Unbind(wx.EVT_TEXT_ENTER)
118 0
        self._label_lo.Unbind(wx.EVT_KILL_FOCUS)
119

120 0
    def update_low_on_enter(self, event):
121 11
        if isinstance(event, wx.FocusEvent):
122 0
            event.Skip()
123 0
        try:
124 0
            try:
125 0
                low = eval(str(self._label_lo.GetValue()).strip())
126 11
                if self.evaluate is not None:
127 0
                    low = self.evaluate(low)
128 0
            except Exception as ex:
129 0
                low = self.low
130 0
                self._label_lo.SetValue(self.format % self.low)
131

132 11
            if not self.factory.is_float:
133 0
                low = int(low)
134

135 11
            if low > self.high:
136 0
                low = self.high - self._step_size()
137 0
                self._label_lo.SetValue(self.format % low)
138

139 0
            self.control.lslider.SetValue(self._convert_to_slider(low))
140 0
            self.low = low
141 0
        except:
142 0
            pass
143

144 0
    def update_high_on_enter(self, event):
145 11
        if isinstance(event, wx.FocusEvent):
146 0
            event.Skip()
147 0
        try:
148 0
            try:
149 0
                high = eval(str(self._label_hi.GetValue()).strip())
150 11
                if self.evaluate is not None:
151 0
                    high = self.evaluate(high)
152 0
            except:
153 0
                high = self.high
154 0
                self._label_hi.SetValue(self.format % self.high)
155

156 11
            if not self.factory.is_float:
157 0
                high = int(high)
158

159 11
            if high < self.low:
160 0
                high = self.low + self._step_size()
161 0
                self._label_hi.SetValue(self.format % high)
162

163 0
            self.control.rslider.SetValue(self._convert_to_slider(high))
164 0
            self.high = high
165 0
        except:
166 0
            pass
167

168 0
    def update_object_on_scroll(self, evt):
169 0
        low = self._convert_from_slider(self.control.lslider.GetValue())
170 0
        high = self._convert_from_slider(self.control.rslider.GetValue())
171

172 11
        if low >= high:
173 11
            if evt.Position == self.control.lslider.GetValue():
174 0
                low = self.high - self._step_size()
175
            else:
176 0
                high = self.low + self._step_size()
177

178 11
        if self.factory.is_float:
179 0
            self.low = low
180 0
            self.high = high
181
        else:
182 0
            self.low = int(low)
183 0
            self.high = int(high)
184

185
            # update the sliders to the int values or the sliders
186
            # will jiggle
187 0
            self.control.lslider.SetValue(self._convert_to_slider(low))
188 0
            self.control.rslider.SetValue(self._convert_to_slider(high))
189

190 0
    def update_editor(self):
191 0
        return
192

193 0
    def _check_max_and_min(self):
194
        # check if max & min have been defined:
195 11
        if self.max is None:
196 0
            self.max = self.high
197 11
        if self.min is None:
198 0
            self.min = self.low
199

200 0
    def _step_size(self):
201 0
        slider_delta = (
202
            self.control.lslider.GetMax() - self.control.lslider.GetMin()
203
        )
204 0
        range_delta = self.max - self.min
205

206 0
        return float(range_delta) / slider_delta
207

208 0
    def _convert_from_slider(self, slider_val):
209 0
        self._check_max_and_min()
210 0
        return self.min + slider_val * self._step_size()
211

212 0
    def _convert_to_slider(self, value):
213 0
        self._check_max_and_min()
214 0
        return (
215
            self.control.lslider.GetMin()
216
            + (value - self.min) / self._step_size()
217
        )
218

219 0
    def _low_changed(self, low):
220 11
        if self.control is None:
221 0
            return
222 11
        if self._label_lo is not None:
223 0
            self._label_lo.SetValue(self.format % low)
224

225 0
        self.control.lslider.SetValue(self._convert_to_slider(low))
226

227 0
    def _high_changed(self, high):
228 11
        if self.control is None:
229 0
            return
230 11
        if self._label_hi is not None:
231 0
            self._label_hi.SetValue(self.format % high)
232

233 0
        self.control.rslider.SetValue(self._convert_to_slider(self.high))
234

235

236 0
class BoundsEditor(RangeEditor):
237

238 0
    min = Either(None, Float)
239 0
    max = Either(None, Float)
240

241 0
    def _get_simple_editor_class(self):
242 0
        return _BoundsEditor
243

244 0
    def _get_custom_editor_class(self):
245 0
        return _BoundsEditor

Read our documentation on viewing source code .

Loading