mwxlib 0.97.4__py3-none-any.whl → 0.97.6__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
@@ -48,7 +48,7 @@ class Param(object):
48
48
  self.knobs = []
49
49
  self.name = name
50
50
  self.range = range
51
- self.__std_value = value
51
+ self.__std_value = value if value is not None else nan
52
52
  self.__value = value if value is not None else self.min
53
53
  self.__check = False
54
54
  if fmt is hex:
@@ -69,7 +69,8 @@ class Param(object):
69
69
  self._tooltip = _Tip(handler.__doc__, updater.__doc__)
70
70
 
71
71
  def __str__(self, v=None):
72
- v = self.value if v is None else v
72
+ if v is None:
73
+ v = self.value
73
74
  try:
74
75
  return self.__format(v)
75
76
  except ValueError:
@@ -84,45 +85,22 @@ class Param(object):
84
85
  def __len__(self):
85
86
  return len(self.range)
86
87
 
87
- def reset(self, v=None, backcall=True):
88
+ def reset(self, v=None, internal_callback=True):
88
89
  """Reset value when indexed (by knobs) with callback."""
89
- if v is None or v == '':
90
+ if v is None:
90
91
  v = self.std_value
91
- if v is None:
92
+ if np.isnan(v):
92
93
  return
93
- if isinstance(v, str):
94
- v = self.__eval(v.replace(',', '')) # eliminates commas; includes nan, inf
95
- self._set_value(v)
96
- if backcall:
94
+ elif isinstance(v, str):
95
+ try:
96
+ v = self.__eval(v.replace(',', '')) # eliminates commas; includes nan, inf
97
+ except Exception:
98
+ v = self.value
99
+ internal_callback = False
100
+ self.value = v
101
+ if internal_callback:
97
102
  self.callback('control', self)
98
103
 
99
- def _set_value(self, v):
100
- """Set value and check the limit.
101
- If the value is out of range, modify the value.
102
- """
103
- if v is None:
104
- v = nan
105
-
106
- if np.isnan(v) or np.isinf(v):
107
- self.__value = v
108
- for knob in self.knobs:
109
- knob.update_ctrl(None, notify=False)
110
- return
111
- elif v == self.__value:
112
- return
113
-
114
- valid = (self.min <= v <= self.max)
115
- if valid:
116
- self.__value = v
117
- elif v < self.min:
118
- self.__value = self.min
119
- self.callback('underflow', self)
120
- else:
121
- self.__value = self.max
122
- self.callback('overflow', self)
123
- for knob in self.knobs:
124
- knob.update_ctrl(valid, notify=True)
125
-
126
104
  @property
127
105
  def check(self):
128
106
  """A knob check property (user defined)."""
@@ -152,7 +130,30 @@ class Param(object):
152
130
 
153
131
  @value.setter
154
132
  def value(self, v):
155
- self._set_value(v)
133
+ if v is None:
134
+ v = nan
135
+ if np.isnan(v) or np.isinf(v):
136
+ self.__value = v
137
+ for knob in self.knobs:
138
+ knob.update_ctrl(None, notify=False)
139
+ return
140
+ elif v == self.__value:
141
+ for knob in self.knobs:
142
+ knob.update_ctrl(True, notify=False)
143
+ return
144
+
145
+ ## If the value is out of range, it will be modified.
146
+ valid = (self.min <= v <= self.max)
147
+ if valid:
148
+ self.__value = v
149
+ elif v < self.min:
150
+ self.__value = self.min
151
+ self.callback('underflow', self)
152
+ else:
153
+ self.__value = self.max
154
+ self.callback('overflow', self)
155
+ for knob in self.knobs:
156
+ knob.update_ctrl(valid, notify=True)
156
157
 
157
158
  @property
158
159
  def std_value(self):
@@ -161,6 +162,8 @@ class Param(object):
161
162
 
162
163
  @std_value.setter
163
164
  def std_value(self, v):
165
+ if v is None:
166
+ v = nan
164
167
  self.__std_value = v
165
168
  for knob in self.knobs:
166
169
  knob.update_label()
@@ -168,21 +171,20 @@ class Param(object):
168
171
  @property
169
172
  def offset(self):
170
173
  """Offset value
171
- If std_value is None, this is the same as value.
174
+ If std_value is nan, this is the same as value.
172
175
  """
173
- if self.std_value is not None:
176
+ if not np.isnan(self.std_value):
174
177
  return self.value - self.std_value
175
178
  return self.value
176
179
 
177
180
  @offset.setter
178
181
  def offset(self, v):
179
- if self.std_value is not None:
180
- if not np.isnan(v):
181
- v += self.std_value
182
- self._set_value(v)
182
+ if not np.isnan(self.std_value):
183
+ v += self.std_value
184
+ self.value = v
183
185
 
184
- min = property(lambda self: self.__range[0])
185
- max = property(lambda self: self.__range[-1])
186
+ min = property(lambda self: self.__range[0] if self else nan)
187
+ max = property(lambda self: self.__range[-1] if self else nan)
186
188
 
187
189
  @property
188
190
  def range(self):
@@ -192,7 +194,7 @@ class Param(object):
192
194
  @range.setter
193
195
  def range(self, v):
194
196
  if v is None:
195
- self.__range = [nan] # dummy data
197
+ self.__range = [] # dummy data
196
198
  else:
197
199
  self.__range = sorted(v)
198
200
  for knob in self.knobs:
@@ -200,14 +202,17 @@ class Param(object):
200
202
 
201
203
  @property
202
204
  def index(self):
203
- """A knob index -> value."""
204
- return int(np.searchsorted(self.range, self.value))
205
+ """A knob index -> value.
206
+ Returns -1 if the value is not defined."""
207
+ if self:
208
+ return int(np.searchsorted(self.range, self.value))
209
+ return -1
205
210
 
206
211
  @index.setter
207
212
  def index(self, j):
208
- n = len(self)
209
- i = (0 if j<0 else j if j<n else -1)
210
- self._set_value(self.range[i])
213
+ if self:
214
+ i = (0 if j < 0 else j if j < len(self) else -1)
215
+ self.value = self.range[i]
211
216
 
212
217
 
213
218
  class LParam(Param):
@@ -266,7 +271,7 @@ class LParam(Param):
266
271
 
267
272
  @index.setter
268
273
  def index(self, j):
269
- return self._set_value(self.min + j * self.step)
274
+ self.value = self.min + j * self.step
270
275
 
271
276
 
272
277
  ## --------------------------------
@@ -430,28 +435,20 @@ class Knob(wx.Panel):
430
435
  if isinstance(self.label, wx.CheckBox):
431
436
  self.label.SetValue(v.check)
432
437
 
433
- if self.label.IsEnabled():
434
- t = ' ' if v.std_value is None or v.value == v.std_value else '*'
435
- self.label.SetLabel(v.name + t)
436
- self.label.Refresh()
438
+ t = ' ' if np.isnan(v.std_value) or v.value == v.std_value else '*'
439
+ self.label.SetLabel(v.name + t)
440
+ self.label.Refresh()
437
441
 
438
442
  def update_ctrl(self, valid=True, notify=False):
439
443
  """Called when value is being changed (internal use only)."""
440
444
  v = self.__par
441
- try:
442
- j = v.index
443
- except (OverflowError, ValueError):
444
- ## OverflowError: cannot convert float infinity to integer
445
- ## ValueError: cannot convert float NaN to integer
446
- j = -1
447
-
448
- self.ctrl.SetValue(j)
445
+ self.ctrl.SetValue(v.index)
449
446
  self.text.SetValue(str(v))
450
447
  if valid:
451
448
  if notify:
452
449
  if self.text.BackgroundColour != '#ffff80':
453
450
  wx.CallAfter(wx.CallLater, 1000,
454
- self.set_textcolour, '#ffffff')
451
+ self.set_textcolour, '#ffffff')
455
452
  self.set_textcolour('#ffff80') # light-yellow
456
453
  else:
457
454
  self.set_textcolour('#ffffff') # True: white
@@ -465,8 +462,7 @@ class Knob(wx.Panel):
465
462
 
466
463
  def set_textcolour(self, c):
467
464
  if self:
468
- if self.text.IsEditable():
469
- self.text.BackgroundColour = c
465
+ self.text.BackgroundColour = c
470
466
  self.text.Refresh()
471
467
 
472
468
  def shift(self, evt, bit):
@@ -497,15 +493,15 @@ class Knob(wx.Panel):
497
493
  if key == wx.WXK_LEFT: return self.shift(evt, -1)
498
494
  if key == wx.WXK_RIGHT: return self.shift(evt, 1)
499
495
 
500
- def focus(c):
496
+ def _focus(c):
501
497
  if isinstance(c, Knob) and c.ctrl.IsEnabled():
502
498
  c.ctrl.SetFocus()
503
499
  return True
504
500
 
505
501
  ls = next(x for x in self.Parent.layout_groups if self in x)
506
502
  i = ls.index(self)
507
- if key == wx.WXK_DOWN: return any(focus(c) for c in ls[i+1:])
508
- if key == wx.WXK_UP: return any(focus(c) for c in ls[i-1::-1])
503
+ if key == wx.WXK_DOWN: return any(_focus(c) for c in ls[i+1:])
504
+ if key == wx.WXK_UP: return any(_focus(c) for c in ls[i-1::-1])
509
505
 
510
506
  def OnTextKeyUp(self, evt): #<wx._core.KeyEvent>
511
507
  evt.Skip()
@@ -515,7 +511,7 @@ class Knob(wx.Panel):
515
511
  if key == wx.WXK_DOWN: return self.shift(evt, -1)
516
512
  if key == wx.WXK_UP: return self.shift(evt, 1)
517
513
  if key == wx.WXK_ESCAPE:
518
- self.__par.reset(self.__par.value, backcall=None) # restore value
514
+ self.__par.reset(self.__par.value, internal_callback=None) # restore value
519
515
  evt.Skip()
520
516
 
521
517
  def OnTextEnter(self, evt): #<wx._core.CommandEvent>
@@ -526,11 +522,7 @@ class Knob(wx.Panel):
526
522
  def OnTextExit(self, evt): #<wx._core.FocusEvent>
527
523
  x = self.text.Value.strip()
528
524
  if x != str(self.__par):
529
- try:
530
- self.__par.reset(x) # reset value if focus out
531
- except Exception:
532
- self.text.SetValue(str(self.__par))
533
- self.__par.reset(self.__par.value, backcall=None) # restore value
525
+ self.__par.reset(x)
534
526
  evt.Skip()
535
527
 
536
528
  def OnCheck(self, evt): #<wx._core.CommandEvent>
@@ -1359,7 +1351,7 @@ class Gauge(wx.Control):
1359
1351
  dc.Clear()
1360
1352
  dc.SetPen(wx.TRANSPARENT_PEN)
1361
1353
 
1362
- def gradients(x):
1354
+ def _gradients(x):
1363
1355
  y = 4 * x
1364
1356
  if y < 1: rgb = (0, y, 1)
1365
1357
  elif y < 2: rgb = (0, 1, 2-y)
@@ -1373,7 +1365,7 @@ class Gauge(wx.Control):
1373
1365
  for i in range(N):
1374
1366
  x = int(i * w / N)
1375
1367
  if i < self.__value:
1376
- dc.SetBrush(wx.Brush(gradients(i/N)))
1368
+ dc.SetBrush(wx.Brush(_gradients(i/N)))
1377
1369
  else:
1378
1370
  dc.SetBrush(wx.Brush('white'))
1379
1371
  dc.DrawRectangle(x, 0, d, h)
mwx/framework.py CHANGED
@@ -1,7 +1,7 @@
1
1
  #! python3
2
2
  """mwxlib framework.
3
3
  """
4
- __version__ = "0.97.4"
4
+ __version__ = "0.97.6"
5
5
  __author__ = "Kazuya O'moto <komoto@jeol.co.jp>"
6
6
 
7
7
  from contextlib import contextmanager
@@ -513,11 +513,8 @@ def pack(self, items, orient=wx.HORIZONTAL, style=None, label=None):
513
513
  else:
514
514
  sizer = wx.BoxSizer(orient)
515
515
  for item in items:
516
- if not item:
517
- if item is None:
518
- item = (0,0), 0,0,0, # null space
519
- else:
520
- item = (0,0) # padding space
516
+ if item is None:
517
+ item = ((0, 0), 0, 0, 0) # null space
521
518
  try:
522
519
  try:
523
520
  sizer.Add(item, *style)
@@ -849,7 +846,7 @@ class MiniFrame(wx.MiniFrame, KeyCtrlInterfaceMixin):
849
846
  class AuiNotebook(aui.AuiNotebook):
850
847
  """AuiNotebook extension class.
851
848
  """
852
- def __init__(self, *args, **kwargs):
849
+ def __init__(self, *args, name=None, **kwargs):
853
850
  kwargs.setdefault('style',
854
851
  (aui.AUI_NB_DEFAULT_STYLE | aui.AUI_NB_BOTTOM)
855
852
  ^ aui.AUI_NB_CLOSE_ON_ACTIVE_TAB
@@ -858,6 +855,8 @@ class AuiNotebook(aui.AuiNotebook):
858
855
  aui.AuiNotebook.__init__(self, *args, **kwargs)
859
856
 
860
857
  self._mgr = self.EventHandler
858
+ if name:
859
+ self.Name = name
861
860
 
862
861
  def tab_menu(evt):
863
862
  tabs = evt.EventObject #<AuiTabCtrl>
@@ -1144,37 +1143,35 @@ class ShellFrame(MiniFrame):
1144
1143
  self.ginfo = LocalsWatcher(self, name="globals")
1145
1144
  self.linfo = LocalsWatcher(self, name="locals")
1146
1145
 
1147
- self.console = AuiNotebook(self, size=(600,400))
1146
+ self.console = AuiNotebook(self, size=(600,400), name='console')
1148
1147
  self.console.AddPage(self.__shell, "root", bitmap=Icon('core'))
1149
1148
  self.console.TabCtrlHeight = 0
1150
- self.console.Name = "console"
1149
+ ## self.console.Name = "console"
1151
1150
 
1152
1151
  ## self.console.Bind(aui.EVT_AUINOTEBOOK_BUTTON, self.OnConsoleCloseBtn)
1153
1152
  self.console.Bind(aui.EVT_AUINOTEBOOK_PAGE_CLOSE, self.OnConsolePageClose)
1154
1153
  self.console.Bind(aui.EVT_AUINOTEBOOK_PAGE_CHANGED, self.OnConsolePageChanged)
1155
1154
 
1156
- self.ghost = AuiNotebook(self, size=(600,400))
1155
+ self.ghost = AuiNotebook(self, size=(600,400), name="ghost")
1157
1156
  self.ghost.AddPage(self.Scratch, "Scratch", bitmap=Icon('ghost'))
1158
1157
  self.ghost.AddPage(self.Log, "Log")
1159
1158
  self.ghost.AddPage(self.Help, "Help")
1160
- self.ghost.Name = "ghost"
1161
1159
 
1162
1160
  self.ghost.AddPage(self.Bookshelf, "Bookshelf", bitmap=Icon('book'))
1163
1161
 
1164
1162
  self.ghost.SetDropTarget(FileDropLoader(self.Scratch))
1165
1163
 
1166
- self.watcher = AuiNotebook(self, size=(600,400))
1164
+ self.watcher = AuiNotebook(self, size=(600,400), name="watcher")
1167
1165
  self.watcher.AddPage(self.ginfo, "globals")
1168
1166
  self.watcher.AddPage(self.linfo, "locals")
1169
1167
  self.watcher.AddPage(self.monitor, "Monitor", bitmap=Icon('tv'))
1170
1168
  self.watcher.AddPage(self.inspector, "Inspector", bitmap=Icon('inspect'))
1171
- self.watcher.Name = "watcher"
1172
1169
 
1173
1170
  self.watcher.Bind(wx.EVT_SHOW, self.OnGhostShow)
1174
1171
 
1175
1172
  self._mgr = aui.AuiManager()
1176
1173
  self._mgr.SetManagedWindow(self)
1177
- self._mgr.SetDockSizeConstraint(0.5, 0.5) # (w, h)/N
1174
+ self._mgr.SetDockSizeConstraint(1, 1)
1178
1175
 
1179
1176
  self._mgr.AddPane(self.console,
1180
1177
  aui.AuiPaneInfo().Name("console").CenterPane()
@@ -1465,27 +1462,23 @@ class ShellFrame(MiniFrame):
1465
1462
 
1466
1463
  def OnShow(self, evt):
1467
1464
  pane = self._mgr.GetPane(self.watcher)
1468
- def _watch(show):
1469
- if show:
1470
- if pane.IsShown():
1471
- self.inspector.watch() # restart
1472
- self.monitor.watch()
1473
- else:
1474
- if pane.IsDocked():
1475
- self.inspector.unwatch()
1476
- self.monitor.unwatch()
1477
- wx.CallAfter(_watch, evt.IsShown())
1478
- evt.Skip()
1479
-
1480
- def OnGhostShow(self, evt):
1481
- def _watch(show):
1482
- if show:
1483
- self.inspector.watch() # restart
1465
+ if evt.IsShown():
1466
+ if pane.IsShown():
1467
+ self.inspector.watch()
1484
1468
  self.monitor.watch()
1485
- else:
1469
+ else:
1470
+ if pane.IsDocked():
1486
1471
  self.inspector.unwatch()
1487
1472
  self.monitor.unwatch()
1488
- wx.CallAfter(_watch, evt.IsShown())
1473
+ evt.Skip()
1474
+
1475
+ def OnGhostShow(self, evt):
1476
+ if evt.IsShown():
1477
+ self.inspector.watch()
1478
+ self.monitor.watch()
1479
+ else:
1480
+ self.inspector.unwatch()
1481
+ self.monitor.unwatch()
1489
1482
  evt.Skip()
1490
1483
 
1491
1484
  def OnConsolePageChanged(self, evt): #<wx._aui.AuiNotebookEvent>
@@ -1553,6 +1546,8 @@ class ShellFrame(MiniFrame):
1553
1546
  self._mgr.RestoreMaximizedPane()
1554
1547
  self._mgr.Update()
1555
1548
  return
1549
+ if pane.IsShown():
1550
+ pane.best_size = win.Size
1556
1551
  self.popup_window(win, not pane.IsShown())
1557
1552
 
1558
1553
  @save_focus_excursion()
mwx/graphman.py CHANGED
@@ -1242,8 +1242,7 @@ class Frame(mwx.Frame):
1242
1242
  nb.AddPage(plug, caption)
1243
1243
  else:
1244
1244
  size = plug.GetSize() + (2,30) # padding for notebook
1245
- nb = AuiNotebook(self)
1246
- nb.Name = title
1245
+ nb = AuiNotebook(self, name=title)
1247
1246
  nb.AddPage(plug, caption)
1248
1247
  self._mgr.AddPane(nb, aui.AuiPaneInfo()
1249
1248
  .Name(title).Caption(title)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mwxlib
3
- Version: 0.97.4
3
+ Version: 0.97.6
4
4
  Summary: A wrapper of matplotlib and wxPython (phoenix)
5
5
  Home-page: https://github.com/komoto48g/mwxlib
6
6
  Author: Kazuya O'moto
@@ -1,8 +1,8 @@
1
1
  mwx/__init__.py,sha256=nN62CGTWjME7Zz2h-jIRB8MxwuErIkHPGrlBzydkF0o,643
2
2
  mwx/bookshelf.py,sha256=Y4xI2SrEO22DrI1hyyfFx7DfFZA8znOzX9RWMPsA2BE,5137
3
- mwx/controls.py,sha256=YtcFqSFRZaFyVOCF1RI33F3-BA_r6L75--izYXSLNt8,47843
4
- mwx/framework.py,sha256=RrwPw08G26GbJFemxqZU1W1SZ1x-Txau8y9F-6qOU8w,75416
5
- mwx/graphman.py,sha256=SdGWKWqOAkScRzkd3D0yZI44czBnHjFimYxqoEYZbDw,70483
3
+ mwx/controls.py,sha256=LAPGoi_bpiGu6eGhPVHBzv2hx162kWxYBmzlZouMOdk,47582
4
+ mwx/framework.py,sha256=r9nbxrRta0lQat7wWzgBOlHkNay9TYSHHikm1gDRhuk,75209
5
+ mwx/graphman.py,sha256=Cyhl_Da_HGBfk721gu1r5iwSH9L3yPEG8Fzmc2gx-EU,70462
6
6
  mwx/images.py,sha256=_-Eh3xF7Khu42ivkYp97NXIzSNGbjcidqtWjZQFGtqE,47827
7
7
  mwx/matplot2.py,sha256=xCJ_ZzdDEWmzctpPaOrzTnwXyHINP4nfFHweoTZa6ug,32899
8
8
  mwx/matplot2g.py,sha256=wiZFDFuQe3ax71fmyeR_9hvAmgT-4nVfZ30UByv8Nv8,64379
@@ -21,8 +21,8 @@ mwx/plugins/frame_listview.py,sha256=hbApzZWa9-BmQthu7uZBlBbGbtf4iJ_prO8IhxoGMs8
21
21
  mwx/plugins/line_profile.py,sha256=--9NIc3x5EfRB3L59JvD7rzENQHyiYfu7wWJo6AuMkA,820
22
22
  mwx/py/__init__.py,sha256=xykgfOytOwNuvXsfkLoumFZSTN-iBsHOjczYXngjmUE,12
23
23
  mwx/py/filling.py,sha256=fumUG1F5M9TL-Dfqni4G85uk7TmvnUunTbdcPDV0vfo,16857
24
- mwxlib-0.97.4.dist-info/LICENSE,sha256=PGtRKCaTkmUDlBQwpptJAxJtdqxIUtAmdBsaT9nUVkA,1091
25
- mwxlib-0.97.4.dist-info/METADATA,sha256=QKmoaVt-Lsr7Ra6T8Z8YPpKtkWDNGDG2fgW1L9E5jdM,1880
26
- mwxlib-0.97.4.dist-info/WHEEL,sha256=Wyh-_nZ0DJYolHNn1_hMa4lM7uDedD_RGVwbmTjyItk,91
27
- mwxlib-0.97.4.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
28
- mwxlib-0.97.4.dist-info/RECORD,,
24
+ mwxlib-0.97.6.dist-info/LICENSE,sha256=PGtRKCaTkmUDlBQwpptJAxJtdqxIUtAmdBsaT9nUVkA,1091
25
+ mwxlib-0.97.6.dist-info/METADATA,sha256=j9v4RwJ93aqB5yYTBlE1i0oENtFExZ5GTIoi_rFIo7E,1880
26
+ mwxlib-0.97.6.dist-info/WHEEL,sha256=Rp8gFpivVLXx-k3U95ozHnQw8yDcPxmhOpn_Gx8d5nc,91
27
+ mwxlib-0.97.6.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
28
+ mwxlib-0.97.6.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (71.1.0)
2
+ Generator: setuptools (72.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5