mwxlib 1.6.10__py3-none-any.whl → 1.7.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of mwxlib might be problematic. Click here for more details.

mwx/controls.py CHANGED
@@ -4,6 +4,7 @@
4
4
  from contextlib import contextmanager
5
5
  from itertools import chain
6
6
  import io
7
+ import re
7
8
  import wx
8
9
  import wx.lib.platebtn as pb
9
10
  import wx.lib.scrolledpanel as scrolled
@@ -23,7 +24,7 @@ def _Tip(*tips):
23
24
 
24
25
 
25
26
  class Param:
26
- """Standard Parameter
27
+ """Standard Parameter.
27
28
 
28
29
  Args:
29
30
  name: label
@@ -72,7 +73,7 @@ class Param:
72
73
  })
73
74
  self._tooltip = _Tip(handler.__doc__,
74
75
  updater.__doc__)
75
-
76
+
76
77
  def __str__(self, v=None):
77
78
  if v is None:
78
79
  v = self.value
@@ -80,16 +81,16 @@ class Param:
80
81
  return self.__format(v)
81
82
  except (TypeError, ValueError):
82
83
  return str(v)
83
-
84
+
84
85
  def __int__(self):
85
86
  return int(self.value)
86
-
87
+
87
88
  def __float__(self):
88
89
  return float(self.value)
89
-
90
+
90
91
  def __len__(self):
91
92
  return len(self.range)
92
-
93
+
93
94
  def reset(self, v=None, internal_callback=True):
94
95
  """Reset value when indexed (by knobs) with callback."""
95
96
  if v is None:
@@ -105,32 +106,32 @@ class Param:
105
106
  self.value = v
106
107
  if internal_callback:
107
108
  self.callback('control', self)
108
-
109
+
109
110
  @property
110
111
  def check(self):
111
112
  """A knob check-flag (user defined)."""
112
113
  return self.__check
113
-
114
+
114
115
  @check.setter
115
116
  def check(self, v):
116
117
  self.__check = bool(v)
117
118
  self.callback('checked', self)
118
-
119
+
119
120
  @property
120
121
  def name(self):
121
122
  return self.__name
122
-
123
+
123
124
  @name.setter
124
125
  def name(self, v):
125
126
  self.__name = v
126
127
  for knob in self.knobs:
127
128
  knob.update_label()
128
-
129
+
129
130
  @property
130
131
  def value(self):
131
132
  """Current value := std_value + offset."""
132
133
  return self.__value
133
-
134
+
134
135
  @value.setter
135
136
  def value(self, v):
136
137
  if v is None:
@@ -138,11 +139,11 @@ class Param:
138
139
  if np.isnan(v) or np.isinf(v): # Skip events for nan and inf.
139
140
  self.__value = v
140
141
  for knob in self.knobs:
141
- knob.update_ctrl(None)
142
+ knob.update_control(None)
142
143
  return
143
144
  elif v == self.__value:
144
145
  for knob in self.knobs:
145
- knob.update_ctrl()
146
+ knob.update_control()
146
147
  return
147
148
 
148
149
  ## If the value is out of range, it will be modified.
@@ -156,14 +157,14 @@ class Param:
156
157
  self.__value = self.max
157
158
  self.callback('overflow', self)
158
159
  for knob in self.knobs:
159
- knob.update_ctrl(valid, notify=True)
160
+ knob.update_control(valid, notify=True)
160
161
  self.callback('notified', self)
161
-
162
+
162
163
  @property
163
164
  def std_value(self):
164
165
  """A standard value (default None)."""
165
166
  return self.__std_value
166
-
167
+
167
168
  @std_value.setter
168
169
  def std_value(self, v):
169
170
  if v is None:
@@ -171,7 +172,7 @@ class Param:
171
172
  self.__std_value = v
172
173
  for knob in self.knobs:
173
174
  knob.update_label()
174
-
175
+
175
176
  @property
176
177
  def offset(self):
177
178
  """Offset value
@@ -180,21 +181,21 @@ class Param:
180
181
  if not np.isnan(self.std_value):
181
182
  return self.value - self.std_value
182
183
  return self.value
183
-
184
+
184
185
  @offset.setter
185
186
  def offset(self, v):
186
187
  if not np.isnan(self.std_value):
187
188
  v += self.std_value
188
189
  self.value = v
189
-
190
+
190
191
  min = property(lambda self: self.__range[0] if self else nan)
191
192
  max = property(lambda self: self.__range[-1] if self else nan)
192
-
193
+
193
194
  @property
194
195
  def range(self):
195
196
  """Index range."""
196
197
  return self.__range
197
-
198
+
198
199
  @range.setter
199
200
  def range(self, v):
200
201
  if v is None:
@@ -203,7 +204,7 @@ class Param:
203
204
  self.__range = sorted(v)
204
205
  for knob in self.knobs:
205
206
  knob.update_range() # list range of related knobs
206
-
207
+
207
208
  @property
208
209
  def index(self):
209
210
  """A knob index -> value.
@@ -213,7 +214,7 @@ class Param:
213
214
  if np.isnan(v) or np.isinf(v):
214
215
  return -1
215
216
  return int(np.searchsorted(self.range, v))
216
-
217
+
217
218
  @index.setter
218
219
  def index(self, j):
219
220
  if self:
@@ -222,7 +223,7 @@ class Param:
222
223
 
223
224
 
224
225
  class LParam(Param):
225
- """Linear Parameter
226
+ """Linear Parameter.
226
227
 
227
228
  Args:
228
229
  name: label
@@ -248,15 +249,15 @@ class LParam(Param):
248
249
  min = property(lambda self: self.__min)
249
250
  max = property(lambda self: self.__max)
250
251
  step = property(lambda self: self.__step)
251
-
252
+
252
253
  def __len__(self):
253
254
  return 1 + int(round((self.max - self.min) / self.step)) # includes [min,max]
254
-
255
+
255
256
  @property
256
257
  def range(self):
257
258
  """Index range."""
258
259
  return np.arange(self.min, self.max + self.step, self.step)
259
-
260
+
260
261
  @range.setter
261
262
  def range(self, v):
262
263
  assert v is None or len(v) <= 3, "The range must be of length <= 3 or None"
@@ -267,7 +268,7 @@ class LParam(Param):
267
268
  self.__step = v[2] if len(v) > 2 else 1
268
269
  for knob in self.knobs:
269
270
  knob.update_range() # linear range of related knobs
270
-
271
+
271
272
  @property
272
273
  def index(self):
273
274
  """A knob index -> value
@@ -277,7 +278,7 @@ class LParam(Param):
277
278
  if np.isnan(v) or np.isinf(v):
278
279
  return -1
279
280
  return int(round((v - self.min) / self.step))
280
-
281
+
281
282
  @index.setter
282
283
  def index(self, j):
283
284
  self.value = self.min + j * self.step
@@ -288,7 +289,7 @@ class LParam(Param):
288
289
  ## --------------------------------
289
290
 
290
291
  class Knob(wx.Panel):
291
- """Parameter controller unit
292
+ """Parameter controller unit.
292
293
 
293
294
  In addition to direct key input to the textctrl,
294
295
  [up][down][wheelup][wheeldown] keys can be used,
@@ -311,24 +312,24 @@ class Knob(wx.Panel):
311
312
  def param(self):
312
313
  """Param object referred from knobs."""
313
314
  return self.__par
314
-
315
+
315
316
  @param.setter
316
317
  def param(self, v):
317
318
  self.__par.knobs.remove(self)
318
319
  self.__par = v
319
320
  self.__par.knobs.append(self)
320
321
  self.update_range()
321
- self.update_ctrl()
322
-
322
+ self.update_control()
323
+
323
324
  @property
324
325
  def button(self):
325
326
  if isinstance(self._label, pb.PlateButton):
326
327
  return self._label
327
-
328
+
328
329
  @property
329
330
  def control(self):
330
331
  return self._ctrl
331
-
332
+
332
333
  def __init__(self, parent, param, type=None,
333
334
  style=None, cw=-1, lw=-1, tw=-1, h=22, **kwargs):
334
335
  wx.Panel.__init__(self, parent, **kwargs)
@@ -422,14 +423,14 @@ class Knob(wx.Panel):
422
423
  ))
423
424
  )
424
425
  self.update_range()
425
- self.update_ctrl()
426
+ self.update_control()
426
427
 
427
428
  self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy)
428
-
429
+
429
430
  def OnDestroy(self, evt):
430
431
  self.__par.knobs.remove(self) # パラメータの関連付けを解除する
431
432
  evt.Skip()
432
-
433
+
433
434
  def update_range(self):
434
435
  """Called when range is being changed (internal use only)."""
435
436
  v = self.__par
@@ -440,7 +441,7 @@ class Knob(wx.Panel):
440
441
  self._ctrl.SetStringSelection(str(v))
441
442
  else:
442
443
  self._ctrl.SetRange(0, len(v)-1) #<wx.Slider> #<wx.SpinButton>
443
-
444
+
444
445
  def update_label(self):
445
446
  """Called when label is being changed (internal use only)."""
446
447
  v = self.__par
@@ -451,8 +452,8 @@ class Knob(wx.Panel):
451
452
  self._label.SetLabel(v.name + t)
452
453
  self._label.Refresh()
453
454
  self.Refresh()
454
-
455
- def update_ctrl(self, valid=True, notify=False):
455
+
456
+ def update_control(self, valid=True, notify=False):
456
457
  """Called when value is being changed (internal use only)."""
457
458
  v = self.__par
458
459
  self._ctrl.SetValue(v.index)
@@ -472,19 +473,17 @@ class Knob(wx.Panel):
472
473
  else:
473
474
  self.set_textcolour('#ff8080') # False: light-red
474
475
  self.update_label()
475
-
476
+
476
477
  def set_textcolour(self, c):
477
478
  if self:
478
479
  self._text.BackgroundColour = c
479
480
  self._text.Refresh()
480
-
481
- def shift_ctrl(self, evt, bit):
482
- """Called when a key/mouse wheel is pressed/scrolled.
483
-
484
- In addition to direct key input to the textctrl,
485
- [up][down][wheelup][wheeldown] keys can be used,
486
- with modifiers S- 2x, C- 16x, and M- 256x steps.
487
- """
481
+
482
+ def _shift_control(self, evt, bit):
483
+ ## Called when a key/mouse wheel is pressed/scrolled (internal use only).
484
+ ## In addition to direct key input to the textctrl,
485
+ ## [up][down][wheelup][wheeldown] keys can be used,
486
+ ## with modifiers S- 2x, C- 16x, and M- 256x steps.
488
487
  if bit:
489
488
  if evt.ShiftDown(): bit *= 2
490
489
  if evt.ControlDown(): bit *= 16
@@ -494,7 +493,7 @@ class Knob(wx.Panel):
494
493
  if j != v.index:
495
494
  v.index = j
496
495
  v.reset(v.value)
497
-
496
+
498
497
  def OnScroll(self, evt): #<wx._core.ScrollEvent> #<wx._controls.SpinEvent> #<wx._core.CommandEvent>
499
498
  v = self.__par
500
499
  j = self._ctrl.GetValue()
@@ -502,15 +501,15 @@ class Knob(wx.Panel):
502
501
  v.index = j
503
502
  v.reset(v.value)
504
503
  evt.Skip()
505
-
504
+
506
505
  def OnMouseWheel(self, evt): #<wx._core.MouseEvent>
507
- self.shift_ctrl(evt, (1 if evt.WheelRotation > 0 else -1))
506
+ self._shift_control(evt, (1 if evt.WheelRotation > 0 else -1))
508
507
  evt.Skip(False)
509
-
508
+
510
509
  def OnCtrlKeyDown(self, evt): #<wx._core.KeyEvent>
511
510
  key = evt.GetKeyCode()
512
- if key == wx.WXK_LEFT: return self.shift_ctrl(evt, -1)
513
- if key == wx.WXK_RIGHT: return self.shift_ctrl(evt, 1)
511
+ if key == wx.WXK_LEFT: return self._shift_control(evt, -1)
512
+ if key == wx.WXK_RIGHT: return self._shift_control(evt, 1)
514
513
 
515
514
  def _focus(c):
516
515
  if isinstance(c, Knob) and c._ctrl.IsEnabled():
@@ -521,37 +520,37 @@ class Knob(wx.Panel):
521
520
  i = ls.index(self)
522
521
  if key == wx.WXK_DOWN: return any(_focus(c) for c in ls[i+1:])
523
522
  if key == wx.WXK_UP: return any(_focus(c) for c in ls[i-1::-1])
524
-
523
+
525
524
  def OnTextKeyUp(self, evt): #<wx._core.KeyEvent>
526
525
  evt.Skip()
527
-
526
+
528
527
  def OnTextKeyDown(self, evt): #<wx._core.KeyEvent>
529
528
  key = evt.GetKeyCode()
530
- if key == wx.WXK_DOWN: return self.shift_ctrl(evt, -1)
531
- if key == wx.WXK_UP: return self.shift_ctrl(evt, 1)
529
+ if key == wx.WXK_DOWN: return self._shift_control(evt, -1)
530
+ if key == wx.WXK_UP: return self._shift_control(evt, 1)
532
531
  if key == wx.WXK_ESCAPE:
533
532
  self.__par.reset(self.__par.value, internal_callback=None) # restore value
534
533
  evt.Skip()
535
-
534
+
536
535
  def OnTextEnter(self, evt): #<wx._core.CommandEvent>
537
536
  evt.Skip()
538
537
  x = self._text.Value.strip()
539
538
  self.__par.reset(x)
540
-
539
+
541
540
  def OnTextExit(self, evt): #<wx._core.FocusEvent>
542
541
  x = self._text.Value.strip()
543
542
  if x != str(self.__par):
544
543
  self.__par.reset(x)
545
544
  evt.Skip()
546
-
545
+
547
546
  def OnCheck(self, evt): #<wx._core.CommandEvent>
548
547
  self.__par.check = evt.IsChecked()
549
548
  evt.Skip()
550
-
549
+
551
550
  def OnPress(self, evt): #<wx._core.CommandEvent>
552
551
  self.__par.callback('updated', self.__par)
553
552
  evt.Skip()
554
-
553
+
555
554
  def Enable(self, p=True):
556
555
  self._label.Enable(p)
557
556
  self._ctrl.Enable(p)
@@ -559,7 +558,7 @@ class Knob(wx.Panel):
559
558
 
560
559
 
561
560
  class KnobCtrlPanel(scrolled.ScrolledPanel):
562
- """Scrollable Control Panel
561
+ """Scrollable Control Panel.
563
562
  """
564
563
  def __init__(self, *args, **kwargs):
565
564
  scrolled.ScrolledPanel.__init__(self, *args, **kwargs)
@@ -591,11 +590,11 @@ class KnobCtrlPanel(scrolled.ScrolledPanel):
591
590
  self.Bind(wx.EVT_SCROLLWIN_THUMBRELEASE, self.OnRecalcLayout)
592
591
  self.Bind(wx.EVT_MOUSEWHEEL, self.OnRecalcLayout)
593
592
  self.Bind(wx.EVT_LEFT_DOWN, self.OnRecalcLayout)
594
-
593
+
595
594
  def OnRecalcLayout(self, evt): #<wx._core.ScrollWinEvent>
596
595
  self.Layout()
597
596
  evt.Skip()
598
-
597
+
599
598
  def OnToggleFold(self, evt): #<wx._core.MouseEvent>
600
599
  x, y = evt.Position
601
600
  for child in self.Sizer.Children: # child <wx._core.SizerItem>
@@ -610,37 +609,37 @@ class KnobCtrlPanel(scrolled.ScrolledPanel):
610
609
  self.SendSizeEvent()
611
610
  break
612
611
  evt.Skip()
613
-
612
+
614
613
  ## --------------------------------
615
614
  ## Layout commands and attributes
616
615
  ## --------------------------------
617
616
  @property
618
617
  def layout_groups(self):
619
618
  return self.__groups
620
-
619
+
621
620
  def is_enabled(self, groupid, pred=all):
622
621
  return pred(win.Enabled for win in self.__groups[groupid])
623
-
622
+
624
623
  def enable(self, groupid, p=True):
625
624
  for win in self.__groups[groupid]: # child could be deep nesting
626
625
  win.Enable(p)
627
-
626
+
628
627
  def is_shown(self, groupid):
629
628
  ## child = self.Sizer.Children[groupid]
630
629
  ## return child.IsShown()
631
630
  return self.Sizer.IsShown(groupid % len(self.__groups))
632
-
631
+
633
632
  def show(self, groupid, p=True):
634
633
  """Show/hide all including the box."""
635
634
  ## child = self.Sizer.Children[groupid]
636
635
  ## child.Show(p)
637
636
  self.Sizer.Show(groupid % len(self.__groups), p)
638
637
  self.Layout()
639
-
638
+
640
639
  def is_folded(self, groupid):
641
640
  child = self.Sizer.Children[groupid]
642
641
  return not any(cc.IsShown() for cc in child.Sizer.Children)
643
-
642
+
644
643
  def fold(self, groupid, p=True):
645
644
  """Fold/unfold the boxed group."""
646
645
  child = self.Sizer.Children[groupid]
@@ -648,7 +647,7 @@ class KnobCtrlPanel(scrolled.ScrolledPanel):
648
647
  for cc in child.Sizer.Children: # child of child <wx._core.SizerItem>
649
648
  cc.Show(not p)
650
649
  self.Layout()
651
-
650
+
652
651
  def layout(self, items, title=None,
653
652
  row=0, expand=0, border=2, hspacing=1, vspacing=1,
654
653
  show=True, visible=True, align=wx.ALIGN_LEFT, **kwargs):
@@ -711,24 +710,24 @@ class KnobCtrlPanel(scrolled.ScrolledPanel):
711
710
  self.Sizer.Fit(self)
712
711
 
713
712
  return self.__groups[-1]
714
-
713
+
715
714
  ## --------------------------------
716
715
  ## 外部入出力/クリップボード通信
717
716
  ## --------------------------------
718
717
  @property
719
718
  def parameters(self):
720
719
  return [p.value for p in self.get_params()]
721
-
720
+
722
721
  @parameters.setter
723
722
  def parameters(self, v):
724
723
  self.set_params(v)
725
-
724
+
726
725
  def get_params(self, checked_only=False):
727
726
  params = chain(*self.__params)
728
727
  if not checked_only:
729
728
  return params
730
729
  return filter(lambda c: getattr(c, 'check', None), params)
731
-
730
+
732
731
  def set_params(self, argv, checked_only=False):
733
732
  params = self.get_params(checked_only)
734
733
  for p, v in zip(params, argv):
@@ -738,7 +737,7 @@ class KnobCtrlPanel(scrolled.ScrolledPanel):
738
737
  p.value = v
739
738
  except Exception as e:
740
739
  print(f"- Failed to eval {v}:", e)
741
-
740
+
742
741
  def reset_params(self, checked_only=False):
743
742
  params = self.get_params(checked_only)
744
743
  for p in params:
@@ -748,13 +747,13 @@ class KnobCtrlPanel(scrolled.ScrolledPanel):
748
747
  ## TypeError might occur if p.reset(v) is called with
749
748
  ## missing 1 required positional argument.
750
749
  pass
751
-
750
+
752
751
  def copy_to_clipboard(self, checked_only=False):
753
752
  params = self.get_params(checked_only)
754
753
  text = '\t'.join(str(p) if isinstance(p, Param) else
755
754
  str(p.value) for p in params)
756
755
  Clipboard.write(text)
757
-
756
+
758
757
  def paste_from_clipboard(self, checked_only=False):
759
758
  text = Clipboard.read()
760
759
  if text:
@@ -770,7 +769,7 @@ class ControlPanel(CtrlInterface, KnobCtrlPanel):
770
769
 
771
770
 
772
771
  class Clipboard:
773
- """Clipboard interface of text and image
772
+ """Clipboard interface of text and image.
774
773
 
775
774
  This does not work unless wx.App instance exists.
776
775
  The clipboard data cannot be transferred unless wx.Frame exists.
@@ -780,14 +779,14 @@ class Clipboard:
780
779
  def istrstream():
781
780
  with io.StringIO(Clipboard.read()) as f:
782
781
  yield f
783
-
782
+
784
783
  @contextmanager
785
784
  @staticmethod
786
785
  def ostrstream():
787
786
  with io.StringIO() as f:
788
787
  yield f
789
788
  Clipboard.write(f.getvalue())
790
-
789
+
791
790
  @staticmethod
792
791
  def read(verbose=False):
793
792
  do = wx.TextDataObject()
@@ -801,7 +800,7 @@ class Clipboard:
801
800
  else:
802
801
  print("- Unable to open clipboard.")
803
802
  return None
804
-
803
+
805
804
  @staticmethod
806
805
  def write(text, verbose=False):
807
806
  do = wx.TextDataObject(str(text))
@@ -813,7 +812,7 @@ class Clipboard:
813
812
  print(f"To clipboard:\n{text}")
814
813
  else:
815
814
  print("- Unable to open clipboard.")
816
-
815
+
817
816
  @staticmethod
818
817
  def imread(verbose=False):
819
818
  do = wx.BitmapDataObject()
@@ -835,7 +834,7 @@ class Clipboard:
835
834
  except Exception:
836
835
  print("- Contents of the clipboard are not images.")
837
836
  return None
838
-
837
+
839
838
  @staticmethod
840
839
  def imwrite(buf, verbose=False):
841
840
  try:
@@ -929,25 +928,29 @@ class Icon(wx.Bitmap):
929
928
  key = (key.ConvertToImage()
930
929
  .Scale(*size, wx.IMAGE_QUALITY_NEAREST)
931
930
  .ConvertToBitmap())
932
- return key #<wx.Bitmap>
931
+ return key #<wx.Bitmap>
933
932
  if size is None:
934
933
  size = (16, 16)
935
934
  if key:
935
+ ## Returns a bitmap of provided artwork.
936
+ ## Note: The result could be a zero-shaped bitmap.
937
+ if re.match("bullet(.*)", key):
938
+ return eval(f"Icon.{key}") # -> Icon.bullet(*v, **kw)
936
939
  try:
937
940
  art = Icon.custom_images.get(key)
938
941
  bmp = art.GetBitmap()
939
942
  except Exception:
940
943
  art = Icon.provided_arts.get(key)
941
944
  bmp = wx.ArtProvider.GetBitmap(art or key, wx.ART_OTHER, size)
942
- ## Note: The result could be a zero-shaped bitmap.
943
945
  return bmp
944
- elif key == '':
946
+ if key == '':
947
+ ## Returns dummy-sized blank bitmap.
945
948
  ## Note: A zero-shaped bitmap fails with AssertionError since wx ver 4.1.1.
946
949
  bmp = wx.Bitmap(size)
947
950
  with wx.MemoryDC(bmp) as dc:
948
951
  dc.SetBackground(wx.Brush('black'))
949
952
  dc.Clear()
950
- bmp.SetMaskColour('black') # return dummy-sized blank bitmap
953
+ bmp.SetMaskColour('black')
951
954
  return bmp
952
955
  return wx.NullBitmap # The standard wx controls accept this.
953
956
 
@@ -971,7 +974,7 @@ class Icon(wx.Bitmap):
971
974
  return back
972
975
 
973
976
  @staticmethod
974
- def bullet(colour, ec=None, size=None, radius=4):
977
+ def bullet(colour, radius=4, size=None, ec=None):
975
978
  if not size:
976
979
  size = (16, 16)
977
980
  bmp = wx.Bitmap(size)
@@ -1001,7 +1004,7 @@ class Icon(wx.Bitmap):
1001
1004
 
1002
1005
 
1003
1006
  class ClassicButton(wx.Button):
1004
- """Classic button
1007
+ """Classic button.
1005
1008
 
1006
1009
  Args:
1007
1010
  label: button label
@@ -1020,7 +1023,7 @@ class ClassicButton(wx.Button):
1020
1023
 
1021
1024
 
1022
1025
  class Button(pb.PlateButton):
1023
- """Flat button
1026
+ """Flat button.
1024
1027
 
1025
1028
  Args:
1026
1029
  label: button label
@@ -1037,7 +1040,7 @@ class Button(pb.PlateButton):
1037
1040
  self.SetToolTip(_Tip(handler.__doc__))
1038
1041
  if icon:
1039
1042
  self.SetBitmap(Icon(icon))
1040
-
1043
+
1041
1044
  def SetBitmap(self, bmp):
1042
1045
  """Set the bitmap displayed in the button.
1043
1046
 
@@ -1051,7 +1054,7 @@ class Button(pb.PlateButton):
1051
1054
 
1052
1055
 
1053
1056
  class ToggleButton(wx.ToggleButton):
1054
- """Togglable button
1057
+ """Togglable button.
1055
1058
 
1056
1059
  Args:
1057
1060
  label: button label
@@ -1077,7 +1080,7 @@ class ToggleButton(wx.ToggleButton):
1077
1080
 
1078
1081
 
1079
1082
  class TextBox(wx.Control):
1080
- """Text control
1083
+ """Text control.
1081
1084
 
1082
1085
  Args:
1083
1086
  label: button label
@@ -1088,16 +1091,15 @@ class TextBox(wx.Control):
1088
1091
  **kwargs: keywords for wx.TextCtrl
1089
1092
  e.g., value:str
1090
1093
  """
1091
- Value = property(
1094
+ Value = property( # textctrl value:str
1092
1095
  lambda self: self._ctrl.GetValue(),
1093
- lambda self, v: self._ctrl.SetValue(v),
1094
- doc="textctrl value:str")
1095
-
1096
+ lambda self, v: self._ctrl.SetValue(v))
1097
+
1096
1098
  value = Value #: internal use only
1097
-
1099
+
1098
1100
  button = property(lambda self: self._btn)
1099
1101
  control = property(lambda self: self._ctrl)
1100
-
1102
+
1101
1103
  def __init__(self, parent, label='', handler=None, updater=None,
1102
1104
  icon=None, readonly=False, size=(-1,-1), **kwargs):
1103
1105
  wx.Control.__init__(self, parent, size=size, style=wx.BORDER_NONE)
@@ -1126,14 +1128,14 @@ class TextBox(wx.Control):
1126
1128
  self._btn.SetToolTip(_Tip(updater.__doc__))
1127
1129
 
1128
1130
  self.Bind(wx.EVT_NAVIGATION_KEY, self.OnNavKey)
1129
-
1131
+
1130
1132
  def reset(self, v):
1131
1133
  try:
1132
1134
  self.Value = v
1133
1135
  self._handler(self)
1134
1136
  except AttributeError:
1135
1137
  pass
1136
-
1138
+
1137
1139
  def OnNavKey(self, evt):
1138
1140
  if evt.EventObject is self._ctrl:
1139
1141
  self.Navigate(evt.Direction)
@@ -1142,7 +1144,7 @@ class TextBox(wx.Control):
1142
1144
 
1143
1145
 
1144
1146
  class Choice(wx.Control):
1145
- """Editable Choice (ComboBox) control
1147
+ """Editable Choice (ComboBox) control.
1146
1148
 
1147
1149
  Args:
1148
1150
  label: button label
@@ -1157,26 +1159,23 @@ class Choice(wx.Control):
1157
1159
  If the input item is not found in the choices,
1158
1160
  it will be added to the list (unless readonly)
1159
1161
  """
1160
- Value = property(
1162
+ Value = property( # combobox value:str
1161
1163
  lambda self: self._ctrl.GetValue(),
1162
- lambda self, v: self._ctrl.SetValue(v),
1163
- doc="combobox value:str")
1164
-
1164
+ lambda self, v: self._ctrl.SetValue(v))
1165
+
1165
1166
  value = Value #: internal use only
1166
-
1167
- Selection = property(
1167
+
1168
+ Selection = property( # combobox selection:int or NOT_FOUND(-1)
1168
1169
  lambda self: self._ctrl.GetSelection(),
1169
- lambda self, v: self._ctrl.SetSelection(v), # int or NOT_FOUND(-1)
1170
- doc="combobox selection:int")
1171
-
1172
- Items = property(
1170
+ lambda self, v: self._ctrl.SetSelection(v))
1171
+
1172
+ Items = property( # combobox items:list
1173
1173
  lambda self: self._ctrl.GetItems(),
1174
- lambda self, v: self._ctrl.SetItems(v),
1175
- doc="combobox items:list")
1176
-
1174
+ lambda self, v: self._ctrl.SetItems(v))
1175
+
1177
1176
  button = property(lambda self: self._btn)
1178
1177
  control = property(lambda self: self._ctrl)
1179
-
1178
+
1180
1179
  def __init__(self, parent, label='', handler=None, updater=None,
1181
1180
  icon=None, readonly=False, size=(-1,-1), **kwargs):
1182
1181
  wx.Control.__init__(self, parent, size=size, style=wx.BORDER_NONE)
@@ -1207,14 +1206,14 @@ class Choice(wx.Control):
1207
1206
  self._btn.SetToolTip(_Tip(updater.__doc__))
1208
1207
 
1209
1208
  self.Bind(wx.EVT_NAVIGATION_KEY, self.OnNavKey)
1210
-
1209
+
1211
1210
  def reset(self, v):
1212
1211
  try:
1213
1212
  self.Value = v
1214
1213
  self._handler(self)
1215
1214
  except AttributeError:
1216
1215
  pass
1217
-
1216
+
1218
1217
  def OnTextEnter(self, evt):
1219
1218
  s = evt.String.strip()
1220
1219
  if not s:
@@ -1223,7 +1222,7 @@ class Choice(wx.Control):
1223
1222
  self._ctrl.Append(s)
1224
1223
  self._ctrl.SetStringSelection(s)
1225
1224
  evt.Skip()
1226
-
1225
+
1227
1226
  def OnNavKey(self, evt):
1228
1227
  if evt.EventObject is self._ctrl:
1229
1228
  self.Navigate(evt.Direction)
@@ -1232,7 +1231,7 @@ class Choice(wx.Control):
1232
1231
 
1233
1232
 
1234
1233
  class Indicator(wx.Control):
1235
- """Traffic light indicator
1234
+ """Traffic light indicator.
1236
1235
 
1237
1236
  Args:
1238
1237
  colors: list of colors (default is tricolour) cf. wx.ColourDatabase
@@ -1242,17 +1241,17 @@ class Indicator(wx.Control):
1242
1241
  @property
1243
1242
  def Value(self):
1244
1243
  return self.__value
1245
-
1244
+
1246
1245
  @Value.setter
1247
1246
  def Value(self, v):
1248
1247
  self.__value = int(v)
1249
1248
  self.Refresh()
1250
-
1249
+
1251
1250
  def redesign(self, **kwargs):
1252
1251
  """Update multiple design properties at once.
1253
1252
 
1254
1253
  This method is useful for changing colors, spacing, radius, etc.
1255
- The best size will be automatically invalidated and re-calculated.
1254
+ The best size will be automatically invalidated and recalculated.
1256
1255
 
1257
1256
  Args:
1258
1257
  **kwargs: class attributes, e.g. colors, spacing, radius.
@@ -1262,14 +1261,14 @@ class Indicator(wx.Control):
1262
1261
  """
1263
1262
  self.__dict__.update(kwargs)
1264
1263
  self.InvalidateBestSize()
1265
-
1264
+
1266
1265
  colors = ('green', 'yellow', 'red') # default tricolor style
1267
1266
  backgroundColour = 'dark gray'
1268
1267
  foregroundColour = 'light gray'
1269
1268
  spacing = 7
1270
1269
  radius = 4
1271
1270
  glow = 0
1272
-
1271
+
1273
1272
  def __init__(self, parent, colors=None, value=0,
1274
1273
  style=wx.BORDER_NONE, **kwargs):
1275
1274
  wx.Control.__init__(self, parent, style=style, **kwargs)
@@ -1287,15 +1286,15 @@ class Indicator(wx.Control):
1287
1286
 
1288
1287
  self.Bind(wx.EVT_SIZE, self.OnSize)
1289
1288
  self.Bind(wx.EVT_PAINT, self.OnPaint)
1290
-
1289
+
1291
1290
  def DoGetBestSize(self):
1292
1291
  N = len(self.colors)
1293
1292
  s = self.spacing
1294
1293
  return wx.Size((2*s-1)*N+3, 2*s+2)
1295
-
1294
+
1296
1295
  def OnSize(self, evt):
1297
1296
  self.Refresh()
1298
-
1297
+
1299
1298
  def OnPaint(self, evt):
1300
1299
  dc = wx.BufferedPaintDC(self)
1301
1300
  dc.Clear()
@@ -1331,7 +1330,7 @@ class Indicator(wx.Control):
1331
1330
  gc.DrawPath(path)
1332
1331
  dc.SetBrush(wx.Brush(name if b else self.foregroundColour))
1333
1332
  dc.DrawCircle(x, y, r)
1334
-
1333
+
1335
1334
  def blink(self, msec, mask=0):
1336
1335
  """Blinks once for given milliseconds.
1337
1336
 
@@ -1350,7 +1349,7 @@ class Indicator(wx.Control):
1350
1349
 
1351
1350
 
1352
1351
  class Gauge(wx.Control):
1353
- """Rainbow gauge
1352
+ """Rainbow gauge.
1354
1353
 
1355
1354
  Args:
1356
1355
  range: maximum value
@@ -1360,21 +1359,21 @@ class Gauge(wx.Control):
1360
1359
  @property
1361
1360
  def Value(self):
1362
1361
  return self.__value
1363
-
1362
+
1364
1363
  @Value.setter
1365
1364
  def Value(self, v):
1366
1365
  self.__value = int(v)
1367
1366
  self.Refresh()
1368
-
1367
+
1369
1368
  @property
1370
1369
  def Range(self):
1371
1370
  return self.__range
1372
-
1371
+
1373
1372
  @Range.setter
1374
1373
  def Range(self, v):
1375
1374
  self.__range = int(v)
1376
1375
  self.Refresh()
1377
-
1376
+
1378
1377
  def __init__(self, parent, range=24, value=0,
1379
1378
  style=wx.BORDER_NONE, **kwargs):
1380
1379
  wx.Control.__init__(self, parent, style=style, **kwargs)
@@ -1386,10 +1385,10 @@ class Gauge(wx.Control):
1386
1385
 
1387
1386
  self.Bind(wx.EVT_SIZE, self.OnSize)
1388
1387
  self.Bind(wx.EVT_PAINT, self.OnPaint)
1389
-
1388
+
1390
1389
  def OnSize(self, evt):
1391
1390
  self.Refresh()
1392
-
1391
+
1393
1392
  def OnPaint(self, evt):
1394
1393
  dc = wx.BufferedPaintDC(self)
1395
1394
  dc.Clear()