mwxlib 0.96.7__py3-none-any.whl → 0.97.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/bookshelf.py CHANGED
@@ -1,8 +1,8 @@
1
1
  #! python3
2
- from functools import partial
3
2
  import re
4
3
  import wx
5
4
 
5
+ from .utilus import funcall as _F
6
6
  from .framework import CtrlInterface, postcall
7
7
 
8
8
 
@@ -20,7 +20,7 @@ class EditorTreeCtrl(wx.TreeCtrl, CtrlInterface):
20
20
  self.parent = parent
21
21
  self.target = None
22
22
 
23
- self.context = { # DNA<EditorTreeCtrl>
23
+ self.context = { # DNA<EditorBook>
24
24
  None : {
25
25
  'buffer_new' : [ None, self.on_buffer_new ],
26
26
  'buffer_saved' : [ None, ],
@@ -36,34 +36,41 @@ class EditorTreeCtrl(wx.TreeCtrl, CtrlInterface):
36
36
  self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged)
37
37
  self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy)
38
38
 
39
- @self.handler.bind('enter pressed')
40
39
  def enter(evt):
41
40
  data = self.GetItemData(self.Selection)
42
41
  if data:
43
42
  data.SetFocus()
44
43
 
45
- @self.handler.bind('f5 pressed')
46
44
  def refresh(evt, clear=False):
47
45
  self.build_tree(clear)
48
46
  if self.target:
49
47
  self.target.current_editor.SetFocus()
50
48
  wx.CallAfter(self.SetFocus)
51
49
 
52
- self.handler.bind('S-f5 pressed', partial(refresh, clear=1))
53
-
54
- @self.handler.bind('delete pressed')
55
50
  def delete(evt):
56
51
  data = self.GetItemData(self.Selection)
57
52
  if data:
58
- data.parent.kill_buffer(data) # -> focus moves
53
+ if data.mtdelta or data.Text:
54
+ data.parent.kill_buffer(data) # -> focus moves
59
55
  wx.CallAfter(self.SetFocus)
60
56
 
61
- @self.handler.bind('*button* pressed')
62
- @self.handler.bind('*button* released')
63
57
  def dispatch(evt):
64
- """Fork mouse events to the parent."""
58
+ """Fork events to the parent."""
65
59
  self.parent.handler(self.handler.current_event, evt)
66
60
  evt.Skip()
61
+
62
+ self.handler.update({ # DNA<EditorTreeCtrl>
63
+ None : {
64
+ '*button* pressed' : [ None, dispatch ],
65
+ '*button* released' : [ None, dispatch ],
66
+ },
67
+ 0 : {
68
+ 'enter pressed' : (0, enter),
69
+ 'delete pressed' : (0, delete),
70
+ 'f5 pressed' : (0, refresh),
71
+ 'S-f5 pressed' : (0, _F(refresh, clear=1)),
72
+ },
73
+ })
67
74
 
68
75
  def OnDestroy(self, evt):
69
76
  if evt.EventObject is self:
mwx/framework.py CHANGED
@@ -1,7 +1,7 @@
1
1
  #! python3
2
2
  """mwxlib framework.
3
3
  """
4
- __version__ = "0.96.7"
4
+ __version__ = "0.97.0"
5
5
  __author__ = "Kazuya O'moto <komoto@jeol.co.jp>"
6
6
 
7
7
  from functools import wraps, partial
@@ -19,7 +19,7 @@ from wx import stc
19
19
  from wx.py import dispatcher
20
20
 
21
21
  from .utilus import funcall as _F
22
- from .utilus import get_rootpath, ignore, warn # noqa
22
+ from .utilus import get_rootpath, ignore, warn
23
23
  from .utilus import FSM, TreeList, apropos, typename, where, mro, pp
24
24
 
25
25
 
@@ -193,10 +193,9 @@ def hotkey(evt):
193
193
 
194
194
 
195
195
  def regulate_key(key):
196
- return (key.replace("ctrl+", "C-") # modifier keys abbreviation
197
- .replace("alt+", "M-")
198
- .replace("shift+", "S-")
199
- .replace("win+", "win-")
196
+ return (key.replace("ctrl-", "C-") # modifier keys abbreviation
197
+ .replace("alt-", "M-")
198
+ .replace("shift-", "S-")
200
199
  .replace("M-C-", "C-M-") # modifier key regulation C-M-S-
201
200
  .replace("S-M-", "M-S-")
202
201
  .replace("S-C-", "C-S-"))
@@ -310,6 +309,11 @@ class KeyCtrlInterfaceMixin:
310
309
  else:
311
310
  self.handler.update({map: {key: [state, f]}})
312
311
  return action
312
+
313
+ @ignore(UserWarning)
314
+ def undefine_key(self, keymap):
315
+ """Delete [map key (pressed)] context."""
316
+ self.define_key(keymap, None)
313
317
 
314
318
 
315
319
  class CtrlInterface(KeyCtrlInterfaceMixin):
@@ -343,8 +347,8 @@ class CtrlInterface(KeyCtrlInterfaceMixin):
343
347
  self.Bind(wx.EVT_KILL_FOCUS, inactivate)
344
348
 
345
349
  self.Bind(wx.EVT_CHAR_HOOK, self.on_hotkey_press)
346
- self.Bind(wx.EVT_KEY_DOWN, self.on_hotkey_dndrag)
347
- self.Bind(wx.EVT_KEY_UP, self.on_hotkey_release)
350
+ self.Bind(wx.EVT_KEY_DOWN, self.on_hotkey_down)
351
+ self.Bind(wx.EVT_KEY_UP, self.on_hotkey_up)
348
352
 
349
353
  self.Bind(wx.EVT_MOUSEWHEEL, self.on_mousewheel)
350
354
 
@@ -376,20 +380,20 @@ class CtrlInterface(KeyCtrlInterfaceMixin):
376
380
  evt.Skip()
377
381
  return
378
382
  key = hotkey(evt)
379
- self.__key = regulate_key(key + '+')
383
+ self.__key = regulate_key(key + '-')
380
384
  if self.handler('{} pressed'.format(key), evt) is None:
381
385
  evt.Skip()
382
386
 
383
- def on_hotkey_dndrag(self, evt): #<wx._core.KeyEvent>
387
+ def on_hotkey_down(self, evt): #<wx._core.KeyEvent>
384
388
  """Called when a key is pressed while dragging.
385
389
  Specifically called when the mouse is being captured.
386
390
  """
387
391
  if self.__isDragging:
388
392
  self.on_hotkey_press(evt)
389
393
  else:
390
- evt.Skip() # for TextCtrl
394
+ evt.Skip()
391
395
 
392
- def on_hotkey_release(self, evt): #<wx._core.KeyEvent>
396
+ def on_hotkey_up(self, evt): #<wx._core.KeyEvent>
393
397
  """Called when a key is released."""
394
398
  key = hotkey(evt)
395
399
  self.__key = ''
@@ -408,7 +412,7 @@ class CtrlInterface(KeyCtrlInterfaceMixin):
408
412
  if self.handler('{} pressed'.format(evt.key), evt) is None:
409
413
  evt.Skip()
410
414
 
411
- def on_motion(self, evt):
415
+ def on_motion(self, evt): #<wx._core.MouseEvent>
412
416
  """Called on mouse motion events.
413
417
  Trigger event: 'key+[LMR]drag begin/motion/end'
414
418
  """
@@ -1630,9 +1634,9 @@ class ShellFrame(MiniFrame):
1630
1634
  if isinstance(obj, wx.Object):
1631
1635
  self.monitor.watch(obj)
1632
1636
  self.popup_window(self.monitor)
1633
- elif hasattr(obj, '__dict__'):
1637
+ if hasattr(obj, '__dict__'):
1634
1638
  self.linfo.watch(obj.__dict__)
1635
- self.ginfo.watch({})
1639
+ self.ginfo.watch(None)
1636
1640
  self.popup_window(self.linfo)
1637
1641
 
1638
1642
  def highlight(self, obj, *args, **kwargs):
mwx/graphman.py CHANGED
@@ -214,13 +214,10 @@ class Thread(object):
214
214
  Use ``check`` method where you want to quit.
215
215
  """
216
216
  def _stop():
217
- try:
218
- busy = wx.BusyInfo("One moment please, "
219
- "waiting for threads to die...")
217
+ with wx.BusyInfo("One moment please, "
218
+ "waiting for threads to die..."):
220
219
  self.handler('thread_quit', self)
221
220
  self.worker.join(1)
222
- finally:
223
- del busy
224
221
  if self.running:
225
222
  self.active = 0
226
223
  wx.CallAfter(_stop) # main-thread で終了させる
@@ -541,19 +538,6 @@ class Graph(GraphPlot):
541
538
  if self.infobar.IsShown():
542
539
  self.infobar.ShowMessage(frame.annotation)
543
540
 
544
- def get_frame_visible(self):
545
- if self.frame:
546
- return self.frame.get_visible()
547
- return False
548
-
549
- def set_frame_visible(self, v):
550
- if self.frame:
551
- if self.frame.get_visible() != v:
552
- self.frame.set_visible(v)
553
- return True
554
- return False
555
- return None
556
-
557
541
  def get_markups_visible(self):
558
542
  return self.marked.get_visible()
559
543
 
@@ -698,7 +682,7 @@ class Frame(mwx.Frame):
698
682
  lambda v: self.save_frame(),
699
683
  lambda v: v.Enable(self.__view.frame is not None)),
700
684
 
701
- (wx.ID_SAVEAS, "&Save as TIFFs", "Save buffers as a statck-tiff", Icon('saveall'),
685
+ (wx.ID_SAVEAS, "&Save as TIFFs", "Save buffers as a multi-page tiff", Icon('saveall'),
702
686
  lambda v: self.save_buffers_as_tiffs(),
703
687
  lambda v: v.Enable(self.__view.frame is not None)),
704
688
  (),
@@ -823,11 +807,13 @@ class Frame(mwx.Frame):
823
807
  self.Bind(wx.EVT_CLOSE, self.OnClose)
824
808
 
825
809
  def on_move(evt, show):
826
- self.graph.set_frame_visible(show)
827
- self.output.set_frame_visible(show)
828
- if show:
829
- self.graph.draw()
830
- self.output.draw()
810
+ def _display(view, show):
811
+ if view.frame:
812
+ view.frame.set_visible(show)
813
+ if show:
814
+ view.draw()
815
+ _display(self.graph, show)
816
+ _display(self.output, show)
831
817
  evt.Skip()
832
818
  self.Bind(wx.EVT_MOVE_START, lambda v :on_move(v, show=0))
833
819
  self.Bind(wx.EVT_MOVE_END, lambda v :on_move(v, show=1))
@@ -842,6 +828,9 @@ class Frame(mwx.Frame):
842
828
 
843
829
  ## Accepts DnD
844
830
  self.SetDropTarget(MyFileDropLoader(self.graph, self))
831
+
832
+ ## Script editor for plugins (external call)
833
+ self.Editor = "notepad"
845
834
 
846
835
  sync_switch = True
847
836
 
@@ -856,17 +845,6 @@ class Frame(mwx.Frame):
856
845
  b.OnDraw(None)
857
846
  b.canvas.draw_idle()
858
847
 
859
- Editor = "notepad"
860
-
861
- @ignore(ResourceWarning)
862
- def edit(self, fn):
863
- if hasattr(fn, '__file__'):
864
- name, _ = os.path.splitext(fn.__file__)
865
- fn = name + '.py'
866
- cmd = '{} "{}"'.format(self.Editor, fn)
867
- subprocess.Popen(cmd)
868
- self.message(cmd)
869
-
870
848
  def set_title(self, frame):
871
849
  ssn = os.path.basename(self.session_file or '--')
872
850
  ssn, _ = os.path.splitext(ssn)
@@ -917,6 +895,8 @@ class Frame(mwx.Frame):
917
895
  evt.Skip()
918
896
 
919
897
  def Destroy(self):
898
+ for name in list(self.plugins):
899
+ self.unload_plug(name) # => plug.Destroy
920
900
  self._mgr.UnInit()
921
901
  return mwx.Frame.Destroy(self)
922
902
 
@@ -943,9 +923,10 @@ class Frame(mwx.Frame):
943
923
  return
944
924
 
945
925
  ## Set the graph and output window sizes to half & half.
926
+ ## ドッキング時に再計算される
946
927
  if name == "output" or name is self.output:
947
928
  w, h = self.graph.GetClientSize()
948
- pane.best_size = (w//2, h) # ドッキング時に再計算される
929
+ pane.best_size = (w//2 - 3, h) # 分割線幅補正 -12pix (Windows only ?)
949
930
 
950
931
  ## Force Layer windows to show.
951
932
  if interactive:
@@ -1312,48 +1293,39 @@ class Frame(mwx.Frame):
1312
1293
 
1313
1294
  def unload_plug(self, name):
1314
1295
  """Unload plugin and detach the pane from UI manager."""
1315
- try:
1316
- plug = self.get_plug(name)
1317
- if not plug:
1318
- return False
1319
-
1320
- name = plug.__module__
1321
- if name not in self.plugins:
1322
- return False
1323
-
1324
- del self.plugins[name]
1325
-
1326
- if plug.__Menu_item:
1327
- menu, sep, tail = plug.menukey.rpartition('/')
1328
- menu = menu or Layer.MENU
1329
- self.menubar[menu].remove(plug.__Menu_item)
1330
- self.menubar.update(menu)
1331
-
1332
- if isinstance(plug.Parent, aui.AuiNotebook):
1333
- nb = plug.Parent
1334
- j = nb.GetPageIndex(plug)
1335
- nb.RemovePage(j) # just remove page
1336
- ## nb.DeletePage(j) # Destroys plug object too.
1337
- else:
1338
- nb = None
1339
- self._mgr.DetachPane(plug)
1340
- self._mgr.Update()
1341
-
1342
- plug.handler('page_closed', plug) # (even if not shown)
1343
- plug.Destroy()
1344
-
1345
- if nb and not nb.PageCount:
1346
- self._mgr.DetachPane(nb) # detach notebook pane
1347
- self._mgr.Update()
1348
- nb.Destroy()
1349
-
1350
- except Exception as e:
1351
- traceback.print_exc()
1352
- wx.CallAfter(wx.MessageBox,
1353
- f"{e}\n\n" + traceback.format_exc(),
1354
- f"Error in unloading {name!r}",
1355
- style=wx.ICON_ERROR)
1356
- return False
1296
+ plug = self.get_plug(name)
1297
+ if not plug:
1298
+ return
1299
+
1300
+ name = plug.__module__
1301
+ if name not in self.plugins:
1302
+ return
1303
+
1304
+ del self.plugins[name]
1305
+
1306
+ if plug.__Menu_item:
1307
+ menu, sep, tail = plug.menukey.rpartition('/')
1308
+ menu = menu or Layer.MENU
1309
+ self.menubar[menu].remove(plug.__Menu_item)
1310
+ self.menubar.update(menu)
1311
+
1312
+ if isinstance(plug.Parent, aui.AuiNotebook):
1313
+ nb = plug.Parent
1314
+ j = nb.GetPageIndex(plug)
1315
+ nb.RemovePage(j) # just remove page
1316
+ ## nb.DeletePage(j) # Destroys plug object too.
1317
+ else:
1318
+ nb = None
1319
+ self._mgr.DetachPane(plug)
1320
+ self._mgr.Update()
1321
+
1322
+ plug.handler('page_closed', plug) # (even if not shown)
1323
+ plug.Destroy()
1324
+
1325
+ if nb and not nb.PageCount:
1326
+ self._mgr.DetachPane(nb) # detach notebook pane
1327
+ self._mgr.Update()
1328
+ nb.Destroy()
1357
1329
 
1358
1330
  def reload_plug(self, name):
1359
1331
  plug = self.get_plug(name)
@@ -1370,11 +1342,16 @@ class Frame(mwx.Frame):
1370
1342
  return self.load_plug(plug.__module__, force=1, session=session)
1371
1343
  return False
1372
1344
 
1345
+ @ignore(ResourceWarning)
1373
1346
  def edit_plug(self, name):
1374
1347
  plug = self.get_plug(name)
1375
1348
  if not plug:
1376
1349
  return
1377
- self.edit(self.plugins[plug.__module__])
1350
+ ## this = inspect.getmodule(plug)
1351
+ this = self.plugins[plug.__module__]
1352
+ cmd = '{} "{}"'.format(self.Editor, this.__file__)
1353
+ subprocess.Popen(cmd)
1354
+ self.message(cmd)
1378
1355
 
1379
1356
  def inspect_plug(self, name):
1380
1357
  """Dive into the process to inspect plugs in the shell.
@@ -1717,14 +1694,14 @@ class Frame(mwx.Frame):
1717
1694
  return None
1718
1695
 
1719
1696
  def save_buffers_as_tiffs(self, path=None, frames=None):
1720
- """Export buffers to a file as a multi-page tiff."""
1697
+ """Save buffers to a file as a multi-page tiff."""
1721
1698
  if not frames:
1722
1699
  frames = self.selected_view.all_frames
1723
1700
  if not frames:
1724
1701
  return None
1725
1702
 
1726
1703
  if not path:
1727
- with wx.FileDialog(self, "Save frames as stack-tiff",
1704
+ with wx.FileDialog(self, "Save buffers as a multi-page tiff",
1728
1705
  defaultFile="Stack-image",
1729
1706
  wildcard="TIF file (*.tif)|*.tif",
1730
1707
  style=wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dlg:
@@ -1734,23 +1711,20 @@ class Frame(mwx.Frame):
1734
1711
  try:
1735
1712
  name = os.path.basename(path)
1736
1713
  self.message("Saving {!r}...".format(name))
1737
- busy = wx.BusyInfo("One moment please, "
1738
- "now saving {!r}...".format(name))
1739
-
1740
- stack = [Image.fromarray(x.buffer.astype(int)) for x in frames]
1741
- stack[0].save(path,
1742
- save_all=True,
1743
- compression="tiff_deflate", # cf. tiff_lzw
1744
- append_images=stack[1:])
1745
-
1714
+ with wx.BusyInfo("One moment please, "
1715
+ "now saving {!r}...".format(name)):
1716
+ stack = [Image.fromarray(x.buffer.astype(int)) for x in frames]
1717
+ stack[0].save(path,
1718
+ save_all=True,
1719
+ compression="tiff_deflate", # cf. tiff_lzw
1720
+ append_images=stack[1:])
1746
1721
  self.message("\b done.")
1722
+ wx.MessageBox("{} files successfully saved into\n{!r}.".format(len(stack), path))
1747
1723
  return True
1748
1724
  except Exception as e:
1749
1725
  self.message("\b failed.")
1750
1726
  wx.MessageBox(str(e), style=wx.ICON_ERROR)
1751
1727
  return False
1752
- finally:
1753
- del busy
1754
1728
 
1755
1729
  ## --------------------------------
1756
1730
  ## load/save session
mwx/matplot2.py CHANGED
@@ -100,10 +100,7 @@ class MatplotPanel(wx.Panel):
100
100
  self.toolbar.Show(0)
101
101
 
102
102
  ## modeline bar
103
- self.modeline = wx.StaticText(self, label="", style=wx.ST_NO_AUTORESIZE)
104
- self.modeline.write = self.modeline.SetLabel
105
- self.modeline.read = self.modeline.GetLabel
106
- self.modeline.SetToolTip("")
103
+ self.modeline = wx.StaticText(self, style=wx.ST_NO_AUTORESIZE)
107
104
 
108
105
  self.modeline.Bind(wx.EVT_MOTION, self.on_modeline_tip)
109
106
  self.modeline.Bind(wx.EVT_LEFT_DOWN, lambda v: self.canvas.SetFocus())
@@ -144,8 +141,8 @@ class MatplotPanel(wx.Panel):
144
141
  ## self.canvas.mpl_connect('draw_event', lambda v: self.handler('canvas_drawn', v))
145
142
 
146
143
  self.canvas.Bind(wx.EVT_CHAR_HOOK, self.on_hotkey_press)
147
- self.canvas.Bind(wx.EVT_KEY_DOWN, self.on_hotkey_dndrag)
148
- self.canvas.Bind(wx.EVT_KEY_UP, self.on_hotkey_release)
144
+ self.canvas.Bind(wx.EVT_KEY_DOWN, self.on_hotkey_down)
145
+ self.canvas.Bind(wx.EVT_KEY_UP, self.on_hotkey_up)
149
146
 
150
147
  self.canvas.Bind(wx.EVT_MOUSE_AUX1_DOWN, lambda v: self.handler('Xbutton1 pressed', v))
151
148
  self.canvas.Bind(wx.EVT_MOUSE_AUX2_DOWN, lambda v: self.handler('Xbutton2 pressed', v))
@@ -390,7 +387,7 @@ class MatplotPanel(wx.Panel):
390
387
  def on_modeline_tip(self, evt): #<wx._core.MouseEvent>
391
388
  flag = self.modeline.HitTest(evt.Position)
392
389
  if flag == wx.HT_WINDOW_INSIDE:
393
- self.modeline.SetToolTip(self.modeline.read())
390
+ self.modeline.ToolTip = self.modeline.Label
394
391
  evt.Skip()
395
392
 
396
393
  def on_focus_set(self, evt): #<wx._core.FocusEvent>
@@ -531,11 +528,11 @@ class MatplotPanel(wx.Panel):
531
528
  def on_hotkey_press(self, evt): #<wx._core.KeyEvent>
532
529
  """Called when a key is pressed."""
533
530
  key = hotkey(evt)
534
- self.__key = regulate_key(key + '+')
531
+ self.__key = regulate_key(key + '-')
535
532
  if self.handler('{} pressed'.format(key), evt) is None:
536
533
  evt.Skip()
537
534
 
538
- def on_hotkey_dndrag(self, evt): #<wx._core.KeyEvent>
535
+ def on_hotkey_down(self, evt): #<wx._core.KeyEvent>
539
536
  """Called when a key is pressed while dragging.
540
537
  Specifically called when the mouse is being captured.
541
538
  """
@@ -544,7 +541,7 @@ class MatplotPanel(wx.Panel):
544
541
  else:
545
542
  evt.Skip()
546
543
 
547
- def on_hotkey_release(self, evt): #<wx._core.KeyEvent>
544
+ def on_hotkey_up(self, evt): #<wx._core.KeyEvent>
548
545
  """Called when a key is released."""
549
546
  key = hotkey(evt)
550
547
  self.__key = ''
@@ -655,17 +652,6 @@ class MatplotPanel(wx.Panel):
655
652
  del self.Selector
656
653
  self.canvas.draw_idle()
657
654
 
658
- ## def OnShiftLimit(self, evt, r=0.1):
659
- ## w = self.xlim[1] - self.xlim[0]
660
- ## h = self.ylim[1] - self.ylim[0]
661
- ## if 'up' in evt.key: self.ylim += h * r
662
- ## elif 'down' in evt.key: self.ylim -= h * r
663
- ## elif 'left' in evt.key: self.xlim -= w * r
664
- ## elif 'right' in evt.key: self.xlim += w * r
665
- ## if 1:
666
- ## self.toolbar.push_current()
667
- ## self.draw()
668
-
669
655
  def zoomlim(self, lim, M, c=None):
670
656
  ## The limitation of zoom is necessary; If the axes is enlarged too much,
671
657
  ## the processing speed will significantly slow down.
mwx/matplot2g.py CHANGED
@@ -228,7 +228,6 @@ class AxesImagePhantom(object):
228
228
 
229
229
  @unit.setter
230
230
  def unit(self, v):
231
- u = self.unit
232
231
  if v is None:
233
232
  v = self.parent.unit
234
233
  self.__localunit = None
@@ -359,33 +358,6 @@ class AxesImagePhantom(object):
359
358
  x = l + (nx + 0.5) * ux
360
359
  y = t - (ny + 0.5) * uy # Y ピクセルインデクスは座標と逆
361
360
  return (x, y)
362
-
363
- def calc_point(self, x, y, centred=True, inaxes=False):
364
- """Computes the nearest pixelated point from a point (x, y).
365
- If centred, correct the points to the center of the nearest pixel.
366
- If inaxes, restrict the points in image area.
367
- """
368
- if isinstance(x, (list, tuple)):
369
- x = np.array(x)
370
- y = np.array(y)
371
- l,r,b,t = self.__art.get_extent()
372
- if inaxes:
373
- x[x < l] = l
374
- x[x > r] = r
375
- y[y < b] = b
376
- y[y > t] = t
377
- nx, ny = self.xytopixel(x, y)
378
- ux, uy = self.xy_unit
379
- if centred:
380
- x = l + (nx + 0.5) * ux
381
- y = t - (ny + 0.5) * uy
382
- if inaxes:
383
- x[x > r] -= ux
384
- y[y < b] += uy
385
- else:
386
- x = l + nx * ux
387
- y = t - ny * uy
388
- return (x, y)
389
361
 
390
362
 
391
363
  class GraphPlot(MatplotPanel):
@@ -589,6 +561,8 @@ class GraphPlot(MatplotPanel):
589
561
 
590
562
  self.modeline.Show(1)
591
563
  self.Layout()
564
+
565
+ self.writeln()
592
566
 
593
567
  def clear(self):
594
568
  MatplotPanel.clear(self)
@@ -834,7 +808,6 @@ class GraphPlot(MatplotPanel):
834
808
  else:
835
809
  if v == self.__unit: # no effect unless unit changes
836
810
  return
837
- u = self.__unit
838
811
  self.__unit = v
839
812
  for art in self.__Arts:
840
813
  art.update_extent()
@@ -907,13 +880,12 @@ class GraphPlot(MatplotPanel):
907
880
 
908
881
  def trace_point(self, x, y, type=NORMAL):
909
882
  """Puts (override) a message of points x and y."""
910
- if self.frame:
883
+ frame = self.frame
884
+ if frame:
911
885
  if not hasattr(x, '__iter__'): # called from OnMotion
912
- nx, ny = self.frame.xytopixel(x, y)
913
- z = self.frame.xytoc(x, y)
914
- self.message(
915
- "[{:-4d},{:-4d}] "
916
- "({:-8.3f},{:-8.3f}) value: {}".format(nx, ny, x, y, z))
886
+ nx, ny = frame.xytopixel(x, y)
887
+ z = frame.xytoc(x, y)
888
+ self.message(f"[{nx:-4d},{ny:-4d}] ({x:-8.3f},{y:-8.3f}) value: {z}")
917
889
  return
918
890
 
919
891
  if len(x) == 0: # no selection
@@ -923,43 +895,41 @@ class GraphPlot(MatplotPanel):
923
895
  return self.trace_point(x[0], y[0], type)
924
896
 
925
897
  if len(x) == 2: # 2-Selector trace line (called from Selector:setter)
926
- nx, ny = self.frame.xytopixel(x, y)
898
+ nx, ny = frame.xytopixel(x, y)
927
899
  dx = x[1] - x[0]
928
900
  dy = y[1] - y[0]
929
901
  a = np.arctan2(dy, dx) * 180/pi
930
902
  lu = np.hypot(dy, dx)
931
903
  li = np.hypot(nx[1]-nx[0], ny[1]-ny[0])
932
- self.message("[Line] "
933
- "Length: {:.1f} pixel ({:g}u) "
934
- "Angle: {:.1f} deg".format(li, lu, a))
904
+ self.message(f"[Line] Length: {li:.1f} pixel ({lu:g}u) Angle: {a:.1f} deg")
935
905
 
936
906
  elif type == REGION: # N-Selector trace polygon (called from Region:setter)
937
- nx, ny = self.frame.xytopixel(x, y)
907
+ nx, ny = frame.xytopixel(x, y)
938
908
  xo, yo = min(nx), min(ny) # top-left
939
909
  xr, yr = max(nx), max(ny) # bottom-right
940
- self.message("[Region] "
941
- "crop={}:{}:{}:{}".format(xr-xo, yr-yo, xo, yo)) # (W:H:left:top)
910
+ self.message(f"[Region] crop={xr-xo}:{yr-yo}:{xo}:{yo}") # (W:H:left:top)
942
911
 
943
912
  def writeln(self):
944
913
  """Puts (override) attributes of current frame to the modeline."""
945
914
  if not self.modeline.IsShown():
946
915
  return
947
- if self.frame:
948
- self.modeline.write(
949
- "[{page}/{maxpage}] -{a}- {name} ({data.dtype}:{cmap}{bins}) "
950
- "[{data.shape[1]}:{data.shape[0]}] {x} [{unit:g}/pixel]".format(
916
+ frame = self.frame
917
+ if frame:
918
+ self.modeline.SetLabel(
919
+ "[{page}/{maxpage}] -{a}- {name} ({data.dtype}:{cmap}{bins}) "
920
+ "[{data.shape[1]}:{data.shape[0]}] {x} [{unit:g}/pixel]".format(
951
921
  page = self.__index,
952
922
  maxpage = len(self),
953
- name = self.frame.name,
954
- data = self.frame.buffer,
955
- cmap = self.frame.get_cmap().name,
956
- bins = ' bin{}'.format(self.frame.binning) if self.frame.binning > 1 else '',
957
- unit = self.frame.unit,
958
- x = '**' if self.frame.localunit else '--',
959
- a = '%%' if not self.frame.buffer.flags.writeable else '--'))
923
+ name = frame.name,
924
+ data = frame.buffer,
925
+ cmap = frame.get_cmap().name,
926
+ bins = ' bin{}'.format(frame.binning) if frame.binning > 1 else '',
927
+ unit = frame.unit,
928
+ x = '**' if frame.localunit else '--',
929
+ a = '%%' if not frame.buffer.flags.writeable else '--'))
960
930
  else:
961
- self.modeline.write(
962
- "[{page}/{maxpage}] ---- No buffer (-:-) [-:-] -- [{unit:g}/pixel]".format(
931
+ self.modeline.SetLabel(
932
+ "[{page}/{maxpage}] ---- No buffer (-:-) [-:-] -- [{unit:g}/pixel]".format(
963
933
  page = '-',
964
934
  maxpage = len(self),
965
935
  unit = self.__unit))
@@ -973,15 +943,16 @@ class GraphPlot(MatplotPanel):
973
943
 
974
944
  def write_buffer_to_clipboard(self):
975
945
  """Write buffer data to clipboard."""
976
- if not self.frame:
946
+ frame = self.frame
947
+ if not frame:
977
948
  self.message("No frame")
978
949
  return
979
950
  try:
980
- name = self.frame.name
981
- data = self.frame.roi
951
+ name = frame.name
952
+ data = frame.roi
982
953
  GraphPlot.clipboard_name = name
983
954
  GraphPlot.clipboard_data = data
984
- bins, vlim, img = imconvert(data, self.frame.vlim)
955
+ bins, vlim, img = imconvert(data, frame.vlim)
985
956
  Clipboard.imwrite(img)
986
957
  self.message("Write buffer to clipboard.")
987
958
  except Exception as e:
@@ -1034,10 +1005,6 @@ class GraphPlot(MatplotPanel):
1034
1005
  self.handler.bind('frame_shown', self.update_colorbar)
1035
1006
  else:
1036
1007
  self.message("- A frame must exist to create a colorbar.")
1037
- ## self['*dummy*'] = np.random.rand(2,2) # dummy
1038
- ## self.create_colorbar()
1039
- ## del self['*dummy*']
1040
- pass
1041
1008
 
1042
1009
  ## --------------------------------
1043
1010
  ## matplotlib interfaces
@@ -1047,9 +1014,9 @@ class GraphPlot(MatplotPanel):
1047
1014
  """Pickup image and other arts.
1048
1015
  Called (maybe) after mouse buttons are pressed.
1049
1016
  """
1050
- ## canvas 全体に有効だが,分割された axes (colorbar 領域など) は無効
1051
- ## image plot が重なっている場合,plot -> image の順に呼び出される
1052
- ## 多重呼び出しが起きないように isPicked フラグで排他制御する
1017
+ ## canvas 全体に有効だが,分割された axes (colorbar 領域など) は無効.
1018
+ ## image - plot が重なっている場合,plot -> image の順に呼び出される.
1019
+ ## 多重呼び出しが起きないように __isPicked フラグで排他制御する.
1053
1020
 
1054
1021
  if evt.mouseevent.button != 1 or not evt.artist.get_visible():
1055
1022
  return
@@ -1118,15 +1085,16 @@ class GraphPlot(MatplotPanel):
1118
1085
  """Called before canvas.draw (overridden)."""
1119
1086
  if not self.interpolation_mode:
1120
1087
  return
1121
- if self.frame:
1088
+ frame = self.frame
1089
+ if frame:
1122
1090
  ## [dots/pixel] = [dots/u] * [u/pixel]
1123
- dots = self.ddpu[0] * self.frame.unit * self.frame.binning
1091
+ dots = self.ddpu[0] * frame.unit * frame.binning
1124
1092
 
1125
- if self.frame.get_interpolation() == 'nearest' and dots < 1:
1126
- self.frame.set_interpolation(self.interpolation_mode)
1093
+ if frame.get_interpolation() == 'nearest' and dots < 1:
1094
+ frame.set_interpolation(self.interpolation_mode)
1127
1095
 
1128
- elif self.frame.get_interpolation() != 'nearest' and dots > 1:
1129
- self.frame.set_interpolation('nearest')
1096
+ elif frame.get_interpolation() != 'nearest' and dots > 1:
1097
+ frame.set_interpolation('nearest')
1130
1098
 
1131
1099
  def OnMotion(self, evt):
1132
1100
  """Called when mouse moves in axes (overridden)."""
@@ -1135,13 +1103,15 @@ class GraphPlot(MatplotPanel):
1135
1103
 
1136
1104
  def OnPageDown(self, evt):
1137
1105
  """Next page."""
1138
- if self.frame and self.__index < len(self)-1:
1139
- self.select(self.__index + 1)
1106
+ i = self.__index
1107
+ if i is not None and i < len(self)-1:
1108
+ self.select(i + 1)
1140
1109
 
1141
1110
  def OnPageUp(self, evt):
1142
1111
  """Previous page."""
1143
- if self.frame and self.__index > 0:
1144
- self.select(self.__index - 1)
1112
+ i = self.__index
1113
+ if i is not None and i > 0:
1114
+ self.select(i - 1)
1145
1115
 
1146
1116
  def OnHomePosition(self, evt):
1147
1117
  self.update_axis()
@@ -1152,14 +1122,6 @@ class GraphPlot(MatplotPanel):
1152
1122
  if len(xs) > 1:
1153
1123
  self.handler('line_removed', self.frame)
1154
1124
 
1155
- ## def zoomlim(self, lim, M, c=None): # virtual call from OnZoom, OnScrollZoom
1156
- ## if c is None:
1157
- ## c = (lim[1] + lim[0]) / 2
1158
- ## y = c - M * (c - lim)
1159
- ## if self.frame:
1160
- ## if abs(y[1] - y[0]) > self.frame.unit or M > 1:
1161
- ## return y
1162
-
1163
1125
  def OnXAxisPanZoom(self, evt, c=None):
1164
1126
  org = self.p_event
1165
1127
  M = np.exp(-(evt.x - org.x)/100)
@@ -1184,11 +1146,33 @@ class GraphPlot(MatplotPanel):
1184
1146
  ## Selector interface
1185
1147
  ## --------------------------------
1186
1148
 
1187
- def calc_point(self, x, y, centred=True):
1188
- """Restrict point (x, y) in image area.
1189
- If centred, correct the point to the center of the nearest pixel.
1149
+ def calc_point(self, x, y, centred=True, inaxes=False):
1150
+ """Computes the nearest pixelated point from a point (x, y).
1151
+ If centred, correct the points to the center of the nearest pixel.
1152
+ If inaxes, restrict the points in image area.
1190
1153
  """
1191
- return self.frame.calc_point(x, y, centred)
1154
+ frame = self.frame
1155
+ if isinstance(x, (list, tuple)):
1156
+ x = np.array(x)
1157
+ y = np.array(y)
1158
+ l,r,b,t = frame.get_extent()
1159
+ if inaxes:
1160
+ x[x < l] = l
1161
+ x[x > r] = r
1162
+ y[y < b] = b
1163
+ y[y > t] = t
1164
+ nx, ny = frame.xytopixel(x, y)
1165
+ ux, uy = frame.xy_unit
1166
+ if centred:
1167
+ x = l + (nx + 0.5) * ux
1168
+ y = t - (ny + 0.5) * uy
1169
+ if inaxes:
1170
+ x[x > r] -= ux
1171
+ y[y < b] += uy
1172
+ else:
1173
+ x = l + nx * ux
1174
+ y = t - ny * uy
1175
+ return (x, y)
1192
1176
 
1193
1177
  def calc_shiftpoint(self, xo, yo, x, y, centred=True):
1194
1178
  """Restrict point (x, y) from (xo, yo) in pi/8 step angles.
mwx/matplot2lg.py CHANGED
@@ -59,8 +59,9 @@ class LinePlot(MatplotPanel):
59
59
 
60
60
  ## Note for matplotlib >= 3.9.0:
61
61
  ## axhspan and axvspan now return Rectangles, not Polygons.
62
- #<matplotlib.patches.Rectangle>
62
+
63
63
  #<matplotlib.patches.Polygon>
64
+ #<matplotlib.patches.Rectangle>
64
65
  self.__vspan = self.axes.axvspan(0, 0,
65
66
  color='none', ls='dashed', lw=1, ec='black', visible=0, zorder=2)
66
67
 
@@ -331,15 +332,17 @@ class Histogram(LinePlot):
331
332
  frame = self.__frame
332
333
  if frame:
333
334
  x, y = frame.__data
334
- i, j = x.searchsorted(self.region) if self.region is not None else np.uint8(self.xlim)
335
- self.modeline.write(
336
- "[--] ---- {name} ({type}:{mode}) [{bins[0]}:{bins[1]}]".format(
335
+ if self.region is not None:
336
+ i, j = x.searchsorted(self.region)
337
+ else:
338
+ i, j = np.uint8(self.xlim)
339
+ self.modeline.SetLabel(
340
+ "[--] ---- {name} ({type}:) [{}:{}]".format(i, j,
337
341
  name = frame.name,
338
342
  type = frame.buffer.dtype,
339
- mode = "bincount",
340
- bins = (i, j)))
343
+ ))
341
344
  else:
342
- self.modeline.write("")
345
+ self.modeline.SetLabel("")
343
346
 
344
347
  ## --------------------------------
345
348
  ## Motion/Drag actions (override)
@@ -349,7 +352,10 @@ class Histogram(LinePlot):
349
352
  if self.__frame:
350
353
  x, y = self.__frame.__data
351
354
  if len(x) > 1:
352
- i, j = x.searchsorted(self.region) if self.region is not None else (0,-1)
355
+ if self.region is not None:
356
+ i, j = x.searchsorted(self.region)
357
+ else:
358
+ i, j = (0, -1)
353
359
  self.__fil.set_xy(list(chain([(x[i],0)], zip(x[i:j],y[i:j]), [(x[j-1],0)])))
354
360
  else:
355
361
  self.__fil.set_xy([(0,0)])
@@ -601,19 +607,19 @@ class LineProfile(LinePlot):
601
607
  return
602
608
  frame = self.__frame
603
609
  if frame:
604
- self.modeline.write(
605
- "[--] -{a}- {name} ({type}:{mode}) "
606
- "[{length}:{width}] {x} [{unit:g}/pixel]".format(
610
+ self.modeline.SetLabel(
611
+ "[--] -{a}- {name} ({type}:{mode}) "
612
+ "[{length}:{width}] {x} [{unit:g}/pixel]".format(
607
613
  name = frame.name,
608
614
  type = frame.buffer.dtype,
609
- mode = "nearest",
615
+ mode = "logic" if self.__logicp else "pixel",
610
616
  width = self.__linewidth,
611
617
  length = len(self.plotdata[0]),
612
- unit = frame.unit if self.__logicp else 1,
613
- x = '++' if self.__logicp else '--',
618
+ unit = frame.unit,
619
+ x = '**' if frame.localunit else '--',
614
620
  a = '%%' if not frame.buffer.flags.writeable else '--'))
615
621
  else:
616
- self.modeline.write("")
622
+ self.modeline.SetLabel("")
617
623
 
618
624
  def write_data_to_clipboard(self):
619
625
  """Write plot data to clipboard."""
mwx/nutshell.py CHANGED
@@ -1749,7 +1749,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
1749
1749
  )
1750
1750
  self.parent = parent #: parent<ShellFrame> is not Parent<AuiNotebook>
1751
1751
  self.Name = name
1752
- self.default_name = "*{}*".format(name.lower())
1752
+ self.default_name = "*{}*".format(name.lower()) # e.g. '*scratch*'
1753
1753
  self.default_buffer = self.create_buffer(self.default_name)
1754
1754
 
1755
1755
  self.Bind(aui.EVT_AUINOTEBOOK_PAGE_CLOSE, self.OnPageClose)
@@ -1,13 +1,15 @@
1
1
  #! python3
2
2
  """FFmpeg wrapper.
3
3
  """
4
+ from functools import partial
4
5
  from subprocess import Popen, PIPE
5
6
  import numpy as np
6
7
  import os
7
8
  import wx
8
9
  import wx.media
9
10
 
10
- from mwx.graphman import Layer, Frame
11
+ from mwx.framework import _F, hotkey
12
+ from mwx.graphman import Layer
11
13
  from mwx.controls import LParam, Icon, Button, TextCtrl
12
14
 
13
15
 
@@ -87,7 +89,6 @@ class Plugin(Layer):
87
89
  )
88
90
  self.mc.ShowPlayerControls()
89
91
  self.mc.Bind(wx.media.EVT_MEDIA_LOADED, self.OnMediaLoaded)
90
- self.mc.Bind(wx.media.EVT_MEDIA_PAUSE, self.OnMediaPause)
91
92
 
92
93
  self.mc.SetDropTarget(MyFileDropLoader(self))
93
94
 
@@ -128,6 +129,27 @@ class Plugin(Layer):
128
129
  ]
129
130
 
130
131
  self.parent.handler.bind("unknown_format", self.load_media)
132
+
133
+ self.handler.update({ # DNA<ffmpeg_viewer>
134
+ 0 : {
135
+ 'play' : (1, ),
136
+ 'space pressed' : (1, _F(self.mc.Play)),
137
+ },
138
+ 1 : {
139
+ 'stop' : (0, ),
140
+ 'pause' : (0, ),
141
+ 'space pressed' : (1, _F(self.mc.Pause)),
142
+ },
143
+ })
144
+
145
+ self.mc.Bind(wx.media.EVT_MEDIA_PAUSE, partial(self.handler, 'pause'))
146
+ self.mc.Bind(wx.media.EVT_MEDIA_PLAY, partial(self.handler, 'play'))
147
+ self.mc.Bind(wx.media.EVT_MEDIA_STOP, partial(self.handler, 'stop'))
148
+
149
+ ## self.mc.Bind(wx.EVT_KEY_DOWN, self.on_hotkey_down)
150
+ ## self.mc.Bind(wx.EVT_KEY_UP, self.on_hotkey_up)
151
+ self.mc.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
152
+ self.mc.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
131
153
 
132
154
  def Destroy(self):
133
155
  try:
@@ -136,15 +158,20 @@ class Plugin(Layer):
136
158
  finally:
137
159
  return Layer.Destroy(self)
138
160
 
161
+ def OnKeyDown(self, evt):
162
+ if self.handler('{} pressed'.format(hotkey(evt)), evt) is None:
163
+ evt.Skip()
164
+
165
+ def OnKeyUp(self, evt):
166
+ if self.handler('{} released'.format(hotkey(evt)), evt) is None:
167
+ evt.Skip()
168
+
139
169
  def OnMediaLoaded(self, evt):
140
170
  self.ss.range = (0, self.video_dur, 0.01)
141
171
  self.to.range = (0, self.video_dur, 0.01)
142
172
  self.Show()
143
173
  evt.Skip()
144
174
 
145
- def OnMediaPause(self, evt):
146
- evt.Skip()
147
-
148
175
  def load_media(self, path=None):
149
176
  if path is None:
150
177
  with wx.FileDialog(self, "Choose a media file",
mwx/plugins/fft_view.py CHANGED
@@ -42,8 +42,8 @@ class Plugin(Layer):
42
42
  self.parent.define_key('C-S-f', self.newifft)
43
43
 
44
44
  def Destroy(self):
45
- self.parent.define_key('C-f', None)
46
- self.parent.define_key('C-S-f', None)
45
+ self.parent.undefine_key('C-f')
46
+ self.parent.undefine_key('C-S-f')
47
47
  return Layer.Destroy(self)
48
48
 
49
49
  def newfft(self):
@@ -67,7 +67,7 @@ class CheckList(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
67
67
  self.InsertItem(j, str(j))
68
68
  self.UpdateInfo(frame) # update all --> 計算が入ると時間がかかる
69
69
 
70
- self.handler.update({
70
+ self.handler.update({ # DNA<frame_listview>
71
71
  0 : {
72
72
  'Lbutton dblclick' : (0, self.OnShowItems), # -> frame_shown
73
73
  'enter pressed' : (0, self.OnShowItems), # -> frame_shown
@@ -84,7 +84,7 @@ class CheckList(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
84
84
  self.Bind(wx.EVT_LIST_COL_CLICK, self.OnSortItems)
85
85
  self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected)
86
86
 
87
- self.context = { # bound to the target
87
+ self.context = { # DNA<GraphPlot>
88
88
  None: {
89
89
  'frame_shown' : [ None, self.on_frame_shown ],
90
90
  'frame_hidden' : [ None, self.on_frame_hidden ],
mwx/wxwil.py CHANGED
@@ -69,11 +69,8 @@ class LocalsWatcher(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
69
69
  def watch(self, locals):
70
70
  self.clear()
71
71
  if not isinstance(locals, dict):
72
- ## wx.MessageBox("Cannot watch the locals.\n\n"
73
- ## "- {!r} is not a dict object.".format(locals))
74
72
  self.unwatch()
75
73
  return
76
- busy = wx.BusyCursor()
77
74
  self.target = locals
78
75
  try:
79
76
  self.Freeze()
mwx/wxwit.py CHANGED
@@ -7,6 +7,7 @@ import wx
7
7
  import wx.lib.inspection as it
8
8
 
9
9
  from .controls import Icon
10
+ from .utilus import typename
10
11
  from .framework import CtrlInterface, Menu, filling
11
12
 
12
13
 
@@ -176,7 +177,7 @@ class Inspector(it.InspectionTree, CtrlInterface):
176
177
  lambda v: watch(obj),
177
178
  lambda v: v.Enable(obj is not None)),
178
179
 
179
- (1, "&Dive into {!r}".format(obj), Icon('core'),
180
+ (1, "&Dive into {!r}".format(typename(obj)), Icon('core'),
180
181
  lambda v: dive(obj),
181
182
  lambda v: v.Enable(obj is not None)),
182
183
  ])
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mwxlib
3
- Version: 0.96.7
3
+ Version: 0.97.0
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
@@ -0,0 +1,28 @@
1
+ mwx/__init__.py,sha256=nN62CGTWjME7Zz2h-jIRB8MxwuErIkHPGrlBzydkF0o,643
2
+ mwx/bookshelf.py,sha256=UgyVYHiYUL2wEvVw110vWnvkJBtXgYAE5hvz9MMLRsU,5333
3
+ mwx/controls.py,sha256=s6yJzQyYnjCzcjXa6nbTJncxzpMI0E5zYWPn3-cFy5Q,48378
4
+ mwx/framework.py,sha256=cXyfw0-PdkONYMHM-h9OsVIsOnDO3C1f4aDC5aYBP4o,75332
5
+ mwx/graphman.py,sha256=VktL6fnYt2BBo-r7UVgVcqVd7IIOY9vpGBDNLNie088,70606
6
+ mwx/images.py,sha256=_-Eh3xF7Khu42ivkYp97NXIzSNGbjcidqtWjZQFGtqE,47827
7
+ mwx/matplot2.py,sha256=xCJ_ZzdDEWmzctpPaOrzTnwXyHINP4nfFHweoTZa6ug,32899
8
+ mwx/matplot2g.py,sha256=jSyRTW9oUqAKA9L9Rcujxy1QLoFOVg411HjVNElexzQ,64401
9
+ mwx/matplot2lg.py,sha256=JRWjWnLJUytbSq6wxs4P0gbVUr3xoLSF6Wwqd5V_pJI,27404
10
+ mwx/mgplt.py,sha256=ITzxA97yDwr_35BUk5OqnyskSuKVDbpf2AQCKY1jHTI,5671
11
+ mwx/nutshell.py,sha256=zrye6tLuGgyCC-Od323o71bauGDKFnO8Zsabs0JMqjs,137383
12
+ mwx/utilus.py,sha256=8GK_2mGY08DVN5_SGWynLKQEJsCKqvqWTDToar1XozM,37333
13
+ mwx/wxmon.py,sha256=f3V24EF7kdMlYF7usLYK9QE5KU6fSu0jVqsvwAiA-Ag,12647
14
+ mwx/wxpdb.py,sha256=lLowkkAgMhPFHAfklD7wZHq0qbSMjRxnBFtSajmVgME,19133
15
+ mwx/wxwil.py,sha256=hhyB1lPrF9ixeObxCOKQv0Theu-B-kpJg_yVU3EGSNg,5406
16
+ mwx/wxwit.py,sha256=ifxMwdIz-QhDEr8vyAztToF8VVSxKNXlq4Ap1awBZvo,7362
17
+ mwx/plugins/__init__.py,sha256=jnJ-Sl9XJ_7BFDslD_r7dsbxsOT57q_IaEriV53XIGY,41
18
+ mwx/plugins/ffmpeg_view.py,sha256=1s7QqIbOpqNrSwbNoc4wQQNo8o1ho5JfXLuseAhgzK4,10441
19
+ mwx/plugins/fft_view.py,sha256=xxTDD-_z4l18u4t2ybPB3xAMIslJmJ0gQlTxEqJUhNI,2782
20
+ mwx/plugins/frame_listview.py,sha256=hbApzZWa9-BmQthu7uZBlBbGbtf4iJ_prO8IhxoGMs8,10421
21
+ mwx/plugins/line_profile.py,sha256=--9NIc3x5EfRB3L59JvD7rzENQHyiYfu7wWJo6AuMkA,820
22
+ mwx/py/__init__.py,sha256=xykgfOytOwNuvXsfkLoumFZSTN-iBsHOjczYXngjmUE,12
23
+ mwx/py/filling.py,sha256=KaHooM32hrGGgqw75Cbt8lAvACwC6RXadob9LGgNnEc,16806
24
+ mwxlib-0.97.0.dist-info/LICENSE,sha256=PGtRKCaTkmUDlBQwpptJAxJtdqxIUtAmdBsaT9nUVkA,1091
25
+ mwxlib-0.97.0.dist-info/METADATA,sha256=3nBiqPuPWhRv2W2keE3GqrTbXBNP9N0iWDOPDKPh6DA,1880
26
+ mwxlib-0.97.0.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
27
+ mwxlib-0.97.0.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
28
+ mwxlib-0.97.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (70.2.0)
2
+ Generator: setuptools (70.3.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,28 +0,0 @@
1
- mwx/__init__.py,sha256=nN62CGTWjME7Zz2h-jIRB8MxwuErIkHPGrlBzydkF0o,643
2
- mwx/bookshelf.py,sha256=CjcgtHC33KR5mHp1lW6Bqfndpzr7hC8ICkFihw4kM3g,5134
3
- mwx/controls.py,sha256=s6yJzQyYnjCzcjXa6nbTJncxzpMI0E5zYWPn3-cFy5Q,48378
4
- mwx/framework.py,sha256=t1d0wXned_XQV5uFYZEdzFhE3d-eCvFb0GIn3W0Uz9E,75227
5
- mwx/graphman.py,sha256=XoD_wbt5wrmiRf8Q3lpn_eklakE2K-rLfpzfXG1L-Pc,71269
6
- mwx/images.py,sha256=_-Eh3xF7Khu42ivkYp97NXIzSNGbjcidqtWjZQFGtqE,47827
7
- mwx/matplot2.py,sha256=-G7z0Osozm9NjLfXvX5UcdFviwbNUktjbd904_g-PqQ,33516
8
- mwx/matplot2g.py,sha256=22rpdkqJQEJADINPaG5htACutbt8oG1ewO8LMpxaqH4,65237
9
- mwx/matplot2lg.py,sha256=4KEkl5407P_D4xHKmar6j_cfIBBCEGkm7wC_3CzgxRI,27303
10
- mwx/mgplt.py,sha256=ITzxA97yDwr_35BUk5OqnyskSuKVDbpf2AQCKY1jHTI,5671
11
- mwx/nutshell.py,sha256=cdrg3cuF6AVU2OuR3QswSiTWrTsGIVaqrBSMuxJIjdE,137364
12
- mwx/utilus.py,sha256=8GK_2mGY08DVN5_SGWynLKQEJsCKqvqWTDToar1XozM,37333
13
- mwx/wxmon.py,sha256=f3V24EF7kdMlYF7usLYK9QE5KU6fSu0jVqsvwAiA-Ag,12647
14
- mwx/wxpdb.py,sha256=lLowkkAgMhPFHAfklD7wZHq0qbSMjRxnBFtSajmVgME,19133
15
- mwx/wxwil.py,sha256=0bzSTfMEjllJheKxZPb4p8Luz6Il3V29bCLBty72U2o,5576
16
- mwx/wxwit.py,sha256=yU6XeCCWRBP7CLmpphjT072PfXAL30DNaxoChDX2p0I,7322
17
- mwx/plugins/__init__.py,sha256=jnJ-Sl9XJ_7BFDslD_r7dsbxsOT57q_IaEriV53XIGY,41
18
- mwx/plugins/ffmpeg_view.py,sha256=QjNqnvPEd9vCwfATU2BOO75fIOFD5LQ-Wf-BBhvZNZs,9368
19
- mwx/plugins/fft_view.py,sha256=HVptnn1dq-Dg7AzXKJXq1dfKiy38catlrMbJkvyLM98,2790
20
- mwx/plugins/frame_listview.py,sha256=7LDAYbl5NvmD4Ehc690IrTbcRgCALRWeLVVOT9cm9Do,10404
21
- mwx/plugins/line_profile.py,sha256=--9NIc3x5EfRB3L59JvD7rzENQHyiYfu7wWJo6AuMkA,820
22
- mwx/py/__init__.py,sha256=xykgfOytOwNuvXsfkLoumFZSTN-iBsHOjczYXngjmUE,12
23
- mwx/py/filling.py,sha256=KaHooM32hrGGgqw75Cbt8lAvACwC6RXadob9LGgNnEc,16806
24
- mwxlib-0.96.7.dist-info/LICENSE,sha256=PGtRKCaTkmUDlBQwpptJAxJtdqxIUtAmdBsaT9nUVkA,1091
25
- mwxlib-0.96.7.dist-info/METADATA,sha256=dJYCzwaGevIma7TaUYe9whPB1wOXX_-V6rRmUvJgq6g,1880
26
- mwxlib-0.96.7.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
27
- mwxlib-0.96.7.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
28
- mwxlib-0.96.7.dist-info/RECORD,,