mwxlib 1.6.5__py3-none-any.whl → 1.6.7__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
@@ -23,11 +23,12 @@ class MyDropTarget(wx.DropTarget):
23
23
 
24
24
  def OnDragOver(self, x, y, result):
25
25
  item, flags = self.tree.HitTest((x, y))
26
- items = list(self.tree._gen_items(self.tree.RootItem)) # first level items
26
+ items = list(self.tree._gen_items(self.tree.RootItem)) # first level items
27
27
  if not item:
28
- item = items[0]
28
+ item = items[0] # Select the first tree item.
29
+ ## return wx.DragNone
29
30
  elif item not in items:
30
- item = self.tree.GetItemParent(item) # Select the parent item
31
+ item = self.tree.GetItemParent(item) # Select the tree item.
31
32
  if item != self.tree.Selection:
32
33
  self.tree.SelectItem(item)
33
34
  return result
@@ -42,7 +43,7 @@ class MyDropTarget(wx.DropTarget):
42
43
  if result == wx.DragMove:
43
44
  try:
44
45
  buf = self.tree._buffer # only for the same process buffer DnD
45
- buf.parent.kill_buffer(buf) # the focus moves
46
+ buf.parent.kill_buffer(buf) # the focus moves
46
47
  wx.CallAfter(self.tree.SetFocus)
47
48
  except AttributeError:
48
49
  pass
mwx/controls.py CHANGED
@@ -207,7 +207,8 @@ class Param:
207
207
  @property
208
208
  def index(self):
209
209
  """A knob index -> value.
210
- Returns -1 if the value is not defined."""
210
+ Returns -1 if the value is not defined.
211
+ """
211
212
  v = self.value
212
213
  if np.isnan(v) or np.isinf(v):
213
214
  return -1
@@ -910,7 +911,7 @@ class Icon(wx.Bitmap):
910
911
  k: v for k, v in vars(images).items()
911
912
  if isinstance(v, wx.lib.embeddedimage.PyEmbeddedImage)
912
913
  }
913
-
914
+
914
915
  def __init__(self, *args, **kwargs):
915
916
  try:
916
917
  bmp = Icon._getBitmap1(*args, **kwargs)
@@ -920,13 +921,16 @@ class Icon(wx.Bitmap):
920
921
 
921
922
  @staticmethod
922
923
  def _getBitmap1(key, size=None):
924
+ if not isinstance(size, (type(None), tuple, wx.Size)):
925
+ raise TypeError("invalid size type")
926
+
923
927
  if isinstance(key, wx.Bitmap):
924
928
  if size and key.Size != size:
925
929
  key = (key.ConvertToImage()
926
930
  .Scale(*size, wx.IMAGE_QUALITY_NEAREST)
927
931
  .ConvertToBitmap())
928
932
  return key #<wx.Bitmap>
929
- if not size:
933
+ if size is None:
930
934
  size = (16, 16)
931
935
  if key:
932
936
  try:
@@ -943,9 +947,9 @@ class Icon(wx.Bitmap):
943
947
  with wx.MemoryDC(bmp) as dc:
944
948
  dc.SetBackground(wx.Brush('black'))
945
949
  dc.Clear()
946
- bmp.SetMaskColour('black') # return dummy-sized blank bitmap
950
+ bmp.SetMaskColour('black') # return dummy-sized blank bitmap
947
951
  return bmp
948
- return wx.NullBitmap # The standard wx controls accept this.
952
+ return wx.NullBitmap # The standard wx controls accept this.
949
953
 
950
954
  @staticmethod
951
955
  def _getBitmap2(back, fore, size=None, subsize=3/4):
mwx/framework.py CHANGED
@@ -1,7 +1,7 @@
1
1
  #! python3
2
2
  """mwxlib framework.
3
3
  """
4
- __version__ = "1.6.5"
4
+ __version__ = "1.6.7"
5
5
  __author__ = "Kazuya O'moto <komoto@jeol.co.jp>"
6
6
 
7
7
  from contextlib import contextmanager
@@ -859,8 +859,8 @@ class AuiNotebook(aui.AuiNotebook):
859
859
  self.Name = name
860
860
 
861
861
  def tab_menu(evt):
862
- tabs = evt.EventObject #<AuiTabCtrl>
863
- page = tabs.Pages[evt.Selection] # GetPage for split notebook.
862
+ tabs = evt.EventObject #<AuiTabCtrl>
863
+ page = tabs.Pages[evt.Selection] # GetPage for split notebook.
864
864
  try:
865
865
  Menu.Popup(self, page.window.menu)
866
866
  except AttributeError:
@@ -868,12 +868,12 @@ class AuiNotebook(aui.AuiNotebook):
868
868
  self.Bind(aui.EVT_AUINOTEBOOK_TAB_RIGHT_DOWN, tab_menu)
869
869
 
870
870
  @property
871
- def _all_tabs(self): # (deprecated) internal use only
871
+ def _all_tabs(self):
872
872
  """Return all AuiTabCtrl objects (internal use only)."""
873
873
  return [x for x in self.Children if isinstance(x, aui.AuiTabCtrl)]
874
874
 
875
875
  @property
876
- def _all_panes(self): # (deprecated) internal use only
876
+ def _all_panes(self):
877
877
  """Return all AuiPaneInfo excluding `dummy` one (internal use only)."""
878
878
  return list(self._mgr.AllPanes)[1:]
879
879
 
@@ -888,12 +888,12 @@ class AuiNotebook(aui.AuiNotebook):
888
888
  """Replace the page with the specified page w/o focusing."""
889
889
  j = self.GetPageIndex(win)
890
890
  if j != -1:
891
- wnd = wx.Window.FindFocus() # original focus
891
+ wnd = wx.Window.FindFocus() # original focus
892
892
  org = self.CurrentPage
893
893
  if j != self.Selection:
894
- self.Selection = j # the focus moves if shown
895
- self.CurrentPage.SetFocus() # reset focus
896
- if wnd and wnd is not org: # restore focus other window
894
+ self.Selection = j # the focus moves if shown
895
+ self.CurrentPage.SetFocus() # reset focus
896
+ if wnd and wnd is not org: # restore focus other window
897
897
  wnd.SetFocus()
898
898
 
899
899
  def get_caption(self, win):
@@ -918,22 +918,24 @@ class AuiNotebook(aui.AuiNotebook):
918
918
  Note:
919
919
  Argument `win` can also be page.window.Name (not page.caption).
920
920
  """
921
- for tabs in self._all_tabs: #<aui.AuiTabCtrl>
922
- for page in tabs.Pages: #<aui.AuiNotebookPage>
921
+ for tab in self._all_tabs: #<aui.AuiTabCtrl>
922
+ for page in tab.Pages: #<aui.AuiNotebookPage>
923
923
  ## if page.window is win or page.caption == win:
924
924
  if page.window is win or page.window.Name == win:
925
- return tabs, page
925
+ return tab, page
926
926
 
927
- def move_tab(self, win, tabs):
928
- """Move the window page to the specified tabs."""
927
+ def move_tab(self, win, tab):
928
+ """Move the window page to the specified tab."""
929
+ if isinstance(tab, int):
930
+ tab = self._all_tabs[tab]
929
931
  try:
930
932
  tc1, nb1 = self.find_tab(win)
931
933
  win = nb1.window
932
- except Exception: # object not found
934
+ except Exception: # object not found
933
935
  return
934
- page = wx.aui.AuiNotebookPage(nb1) # copy-ctor
936
+ page = wx.aui.AuiNotebookPage(nb1) # copy-ctor
935
937
  tc1.RemovePage(win) # Accessing nb1 will crash at this point.
936
- tabs.AddPage(win, page) # Add a page with the copied info.
938
+ tab.AddPage(win, page) # Add a page with the copied info.
937
939
  if tc1.PageCount == 0:
938
940
  ## Delete an empty tab and the corresponding pane.
939
941
  j = self._all_tabs.index(tc1)
@@ -957,8 +959,7 @@ class AuiNotebook(aui.AuiNotebook):
957
959
  pane.name = f"pane{j+1}"
958
960
  spec = ""
959
961
  for j, tabs in enumerate(self._all_tabs):
960
- k = next(k for k, page in enumerate(tabs.Pages)
961
- if page.window.Shown) # get active window
962
+ k = next(k for k, page in enumerate(tabs.Pages) if page.window.Shown)
962
963
  ## names = [page.caption for page in tabs.Pages]
963
964
  names = [page.window.Name for page in tabs.Pages]
964
965
  spec += f"pane{j+1}={names};{k}|"
@@ -975,27 +976,24 @@ class AuiNotebook(aui.AuiNotebook):
975
976
  tabinfo = re.findall(r"pane\w+?=(.*?);(.*?)\|", tabs)
976
977
  try:
977
978
  self.Parent.Freeze()
978
- ## Collapse all tabs to main tabctrl
979
- maintab = self._all_tabs[0]
979
+ ## Collapse all tabctrls to main tabctrl
980
980
  for win in self.get_pages():
981
- self.move_tab(win, maintab)
981
+ self.move_tab(win, 0)
982
982
 
983
- ## Create a new tab using Split method.
983
+ ## Create a new tabctrl using Split method.
984
984
  ## Note: The normal way of creating panes with `_mgr` crashes.
985
-
986
985
  all_names = [win.Name for win in self.get_pages()]
987
986
  for names, k in tabinfo[1:]:
988
987
  names, k = eval(names), int(k)
989
- i = all_names.index(names[0]) # Assuming 0:tab is included.
988
+ i = all_names.index(names[0]) # Assuming 0:tab is included.
990
989
  self.Split(i, wx.LEFT)
991
- newtab = self._all_tabs[-1]
992
990
  for name in names[1:]:
993
- self.move_tab(name, newtab)
994
- self.Selection = all_names.index(names[k]) # new tabs active window
991
+ self.move_tab(name, -1)
992
+ self.Selection = all_names.index(names[k]) # new tabctrl active window
995
993
  else:
996
994
  names, k = tabinfo[0]
997
995
  names, k = eval(names), int(k)
998
- self.Selection = all_names.index(names[k]) # main tabs active window
996
+ self.Selection = all_names.index(names[k]) # main tabctrl active window
999
997
 
1000
998
  for j, pane in enumerate(self._all_panes):
1001
999
  pane.name = f"pane{j+1}"
@@ -1164,9 +1162,7 @@ class ShellFrame(MiniFrame):
1164
1162
  self.console = AuiNotebook(self, size=(600,400), name='console')
1165
1163
  self.console.AddPage(self.__shell, "root", bitmap=Icon('core'))
1166
1164
  self.console.TabCtrlHeight = 0
1167
- ## self.console.Name = "console"
1168
1165
 
1169
- ## self.console.Bind(aui.EVT_AUINOTEBOOK_BUTTON, self.OnConsoleCloseBtn)
1170
1166
  self.console.Bind(aui.EVT_AUINOTEBOOK_PAGE_CLOSE, self.OnConsolePageClose)
1171
1167
  self.console.Bind(aui.EVT_AUINOTEBOOK_PAGE_CHANGED, self.OnConsolePageChanged)
1172
1168
 
@@ -1264,6 +1260,7 @@ class ShellFrame(MiniFrame):
1264
1260
  'monitor_begin' : [ None, self.on_monitor_begin ],
1265
1261
  'monitor_end' : [ None, self.on_monitor_end ],
1266
1262
  'shell_new' : [ None, ],
1263
+ 'book_new' : [ None, ],
1267
1264
  'add_log' : [ None, self.add_log ],
1268
1265
  'add_help' : [ None, self.add_help ],
1269
1266
  'title_window' : [ None, self.on_title_window ],
@@ -1349,6 +1346,8 @@ class ShellFrame(MiniFrame):
1349
1346
  o.write("self.SetPosition({})\n".format(self.Position))
1350
1347
 
1351
1348
  for book in self.get_all_editors():
1349
+ if book.Name not in ("Scratch", "Log", "Help"): # Save default editors only.
1350
+ continue
1352
1351
  for buf in book.get_all_buffers():
1353
1352
  if buf.mtdelta is not None:
1354
1353
  o.write("self.{}.load_file({!r}, {})\n"
@@ -1511,18 +1510,6 @@ class ShellFrame(MiniFrame):
1511
1510
  nb.TabCtrlHeight = 0 if nb.PageCount == 1 else -1
1512
1511
  evt.Skip()
1513
1512
 
1514
- ## def OnConsoleCloseBtn(self, evt): #<wx._aui.AuiNotebookEvent>
1515
- ## tabs = evt.EventObject
1516
- ## win = tabs.Pages[evt.Selection].window # GetPage for split notebook.
1517
- ## if win is self.rootshell:
1518
- ## ## self.message("- Don't close the root shell.")
1519
- ## return
1520
- ## elif self.debugger.busy and win is self.debugger.interactive_shell:
1521
- ## wx.MessageBox("The debugger is running.\n\n"
1522
- ## "Enter [q]uit to exit before closing.")
1523
- ## return
1524
- ## evt.Skip()
1525
-
1526
1513
  def OnConsolePageClose(self, evt): #<wx._aui.AuiNotebookEvent>
1527
1514
  nb = evt.EventObject
1528
1515
  win = list(nb.get_pages())[evt.Selection]
@@ -1628,7 +1615,7 @@ class ShellFrame(MiniFrame):
1628
1615
  lineno = int(ln)
1629
1616
  editor = next(self.get_all_editors(filename), self.Log)
1630
1617
  ret = editor.load_file(filename, lineno)
1631
- if ret:
1618
+ if ret and show:
1632
1619
  self.popup_window(editor, show)
1633
1620
  return ret
1634
1621
 
@@ -1937,7 +1924,25 @@ class ShellFrame(MiniFrame):
1937
1924
  editor = self.ghost.CurrentPage
1938
1925
  if isinstance(editor, type(self.Log)):
1939
1926
  return editor
1940
- return next((x for x in self.get_all_editors() if x.IsShown()), self.Scratch)
1927
+ return next((book for book in self.get_all_editors() if book.IsShown()), self.Scratch)
1928
+
1929
+ def create_editor(self, bookname):
1930
+ """Create a new editor (internal use only)..
1931
+ If such an editor already exists, no new editor is created.
1932
+ """
1933
+ try:
1934
+ return next(book for book in self.get_all_editors() if book.Name == bookname)
1935
+ except StopIteration:
1936
+ with wx.FrozenWindow(self.ghost):
1937
+ editor = self.Log.__class__(self, bookname)
1938
+ self.ghost.AddPage(editor, bookname)
1939
+ self.ghost.move_tab(editor, 0)
1940
+ self.handler('book_new', editor)
1941
+ def _attach():
1942
+ editor.handler.append(self.Bookshelf.context)
1943
+ self.Bookshelf.build_tree(clear=0)
1944
+ wx.CallAfter(_attach)
1945
+ return editor
1941
1946
 
1942
1947
  ## --------------------------------
1943
1948
  ## Find / Replace text dialog
mwx/graphman.py CHANGED
@@ -86,8 +86,10 @@ class Thread:
86
86
  except AttributeError:
87
87
  self.handler = FSM({ # DNA<Thread>
88
88
  None : {
89
- 'thread_begin' : [ None ], # begin processing
90
- 'thread_end' : [ None ], # end processing
89
+ 'thread_begin' : [ None ],
90
+ 'thread_end' : [ None ],
91
+ 'thread_quit' : [ None ],
92
+ 'thread_error' : [ None ],
91
93
  },
92
94
  })
93
95
 
@@ -181,6 +183,7 @@ class Thread:
181
183
  pass
182
184
  except KeyboardInterrupt as e:
183
185
  print("- Thread terminated by user:", e)
186
+ wx.CallAfter(self.handler, 'thread_quit', self)
184
187
  except Exception as e:
185
188
  print("- Thread failed in error:", e)
186
189
  traceback.print_exc()
@@ -189,6 +192,7 @@ class Thread:
189
192
  f"{e}\n\n" + tbstr[-1] + f"{type(e).__name__}: {e}",
190
193
  f"Error in the thread running {f.__name__!r}\n\n",
191
194
  style=wx.ICON_ERROR)
195
+ wx.CallAfter(self.handler, 'thread_error', self)
192
196
  finally:
193
197
  self.active = 0
194
198
  wx.CallAfter(self.handler, 'thread_end', self)
@@ -228,14 +232,14 @@ class LayerInterface(CtrlInterface):
228
232
 
229
233
  The layer properties can be switched by the following classvars::
230
234
 
231
- menukey : menu item key:str in parent menubar
232
- category : title of notebook holder, otherwise None for single pane
233
- caption : flag to set the pane caption to be visible
234
- a string can also be specified (default is __module__)
235
- dockable : flag to set the pane to be dockable
236
- type: bool or dock:int (1:t, 2:r, 3:b, 4:l, 5:c)
237
- reloadable : flag to set the Layer to be reloadable
238
- unloadable : flag to set the Layer to be unloadable
235
+ menukey: menu item key:str in parent menubar
236
+ category: title of notebook holder, otherwise None for single pane
237
+ caption: flag to set the pane caption to be visible
238
+ a string can also be specified (default is __module__)
239
+ dockable: flag to set the pane to be dockable
240
+ type: bool or dock:int (1:t, 2:r, 3:b, 4:l, 5:c)
241
+ reloadable: flag to set the Layer to be reloadable
242
+ unloadable: flag to set the Layer to be unloadable
239
243
 
240
244
  Note:
241
245
  parent <Frame> is not always equal to Parent when floating.
@@ -444,13 +448,13 @@ class LayerInterface(CtrlInterface):
444
448
  ## return self.pane.IsShown()
445
449
  return self.IsShownOnScreen()
446
450
 
447
- def Show(self, show=True):
451
+ def Show(self, show=True, interactive=False):
448
452
  """Shows or hides the window.
449
453
 
450
454
  (override) Show associated pane window.
451
455
  Note: This might be called from a thread.
452
456
  """
453
- wx.CallAfter(self.parent.show_pane, self, show) # Show pane windows in the main thread.
457
+ wx.CallAfter(self.parent.show_pane, self, show, interactive) # Use main thread.
454
458
 
455
459
  Drawn = property(
456
460
  lambda self: self.IsDrawn(),
@@ -894,7 +898,7 @@ class Frame(mwx.Frame):
894
898
  """Get named pane or notebook pane.
895
899
 
896
900
  Args:
897
- name: str or plug object.
901
+ name: plug name or object.
898
902
  """
899
903
  plug = self.get_plug(name)
900
904
  if plug:
@@ -903,7 +907,16 @@ class Frame(mwx.Frame):
903
907
  return self._mgr.GetPane(name)
904
908
 
905
909
  def show_pane(self, name, show=True, interactive=False):
906
- """Show named pane or notebook pane."""
910
+ """Show named pane or notebook pane.
911
+
912
+ Args:
913
+ name: plug name or object.
914
+ show: Show or hide the pane window.
915
+ interactive: If True, modifier keys can be used to reset or reload
916
+ the plugin when showing the pane:
917
+ - [S-menu] Reset floating position.
918
+ - [M-S-menu] Reload plugin.
919
+ """
907
920
  pane = self.get_pane(name)
908
921
  if not pane.IsOk():
909
922
  return
mwx/matplot2.py CHANGED
@@ -371,12 +371,12 @@ class MatplotPanel(wx.Panel):
371
371
  return b - a
372
372
 
373
373
  def mapxy2disp(self, x, y):
374
- """Map xydata --> display dot pixel-coordinates."""
374
+ """Map xydata --> display dot pixel coordinates."""
375
375
  v = np.array((x, y)).T
376
376
  return self.axes.transData.transform(v)
377
377
 
378
378
  def mapdisp2xy(self, px, py):
379
- """Map display dot pixel-coordinates --> xydata."""
379
+ """Map display dot pixel coordinates --> xydata."""
380
380
  v = np.array((px, py)).T
381
381
  return self.axes.transData.inverted().transform(v)
382
382
 
mwx/matplot2g.py CHANGED
@@ -207,10 +207,6 @@ class AxesImagePhantom:
207
207
  cx, cy = self.center
208
208
  self.__art.set_extent((cx-w, cx+w, cy-h, cy+h))
209
209
 
210
- selector = _Property('selector')
211
- markers = _Property('markers')
212
- region = _Property('region')
213
-
214
210
  artist = property(
215
211
  lambda self: self.__art)
216
212
 
@@ -260,7 +256,7 @@ class AxesImagePhantom:
260
256
 
261
257
  @property
262
258
  def unit(self):
263
- """Logical length per pixel arb.unit [u/pixel]."""
259
+ """Logical length per pixel arb.unit [u/pix]."""
264
260
  return self.__localunit or self.parent.unit
265
261
 
266
262
  @unit.setter
@@ -314,14 +310,14 @@ class AxesImagePhantom:
314
310
 
315
311
  @property
316
312
  def index(self):
317
- """Page number in the parent book."""
313
+ """Page number in the parent view."""
318
314
  return self.parent.index(self)
319
315
 
320
316
  @property
321
317
  def roi(self):
322
318
  """Current buffer ROI (region of interest)."""
323
319
  if self.parent.region.size:
324
- nx, ny = self.xytopixel(*self.parent.region)
320
+ nx, ny = self.xytopixel(*self.region)
325
321
  sx = slice(max(0, nx[0]), nx[1]) # nx slice
326
322
  sy = slice(max(0, ny[1]), ny[0]) # ny slice 反転 (降順)
327
323
  return self.__buf[sy, sx]
@@ -375,8 +371,8 @@ class AxesImagePhantom:
375
371
  nx = (x - l) / ux
376
372
  ny = (t - y) / uy # Y ピクセルインデクスは座標と逆
377
373
  if cast:
378
- return (_cast(nx), _cast(ny))
379
- return (nx-0.5, ny-0.5)
374
+ return np.array((_cast(nx), _cast(ny)))
375
+ return np.array((nx-0.5, ny-0.5))
380
376
 
381
377
  def xyfrompixel(self, nx, ny=None):
382
378
  """Convert pixel [nx,ny] -> (x,y) xydata (float number).
@@ -389,7 +385,50 @@ class AxesImagePhantom:
389
385
  ux, uy = self.xy_unit
390
386
  x = l + (nx + 0.5) * ux
391
387
  y = t - (ny + 0.5) * uy # Y ピクセルインデクスは座標と逆
392
- return (x, y)
388
+ return np.array((x, y))
389
+
390
+ selector = _Property('selector')
391
+ markers = _Property('markers')
392
+ region = _Property('region')
393
+
394
+ @property
395
+ def selector_pix(self):
396
+ """Selected points array [[x],[y]] in pixels."""
397
+ return self.xytopixel(self.selector)
398
+
399
+ @selector_pix.setter
400
+ def selector_pix(self, v):
401
+ self.selector = self.xyfrompixel(v)
402
+
403
+ @selector_pix.deleter
404
+ def selector_pix(self):
405
+ del self.selector
406
+
407
+ @property
408
+ def markers_pix(self):
409
+ """Marked points data array [[x],[y]] in pixels."""
410
+ return self.xytopixel(self.markers)
411
+
412
+ @markers_pix.setter
413
+ def markers_pix(self, v):
414
+ self.markers = self.xyfrompixel(v)
415
+
416
+ @markers_pix.deleter
417
+ def markers_pix(self):
418
+ del self.markers
419
+
420
+ @property
421
+ def region_pix(self):
422
+ """Cropped points data array [l,r],[b,t] in pixels."""
423
+ return self.xytopixel(self.region)
424
+
425
+ @region_pix.setter
426
+ def region_pix(self, v):
427
+ self.region = self.xyfrompixel(v)
428
+
429
+ @region_pix.deleter
430
+ def region_pix(self):
431
+ del self.region
393
432
 
394
433
 
395
434
  class GraphPlot(MatplotPanel):
@@ -604,7 +643,7 @@ class GraphPlot(MatplotPanel):
604
643
  self.__Arts = []
605
644
  self.__index = None
606
645
 
607
- ## cf. self.figure.dpi = 80dpi (0.3175mm/pixel)
646
+ ## cf. self.figure.dpi = 80dpi (0.3175mm/pix)
608
647
  self.__unit = 1.0
609
648
 
610
649
  #<matplotlib.lines.Line2D>
@@ -841,7 +880,7 @@ class GraphPlot(MatplotPanel):
841
880
 
842
881
  @property
843
882
  def unit(self):
844
- """Logical length per pixel arb.unit [u/pixel]."""
883
+ """Logical length per pixel arb.unit [u/pix]."""
845
884
  return self.__unit
846
885
 
847
886
  @unit.setter
@@ -960,7 +999,7 @@ class GraphPlot(MatplotPanel):
960
999
  if frame:
961
1000
  self.modeline.SetLabel(
962
1001
  "[{page}/{maxpage}] -{a}- {name} ({data.dtype}:{cmap}{bins}) "
963
- "[{data.shape[1]}:{data.shape[0]}] {x} [{unit:g}/pixel]".format(
1002
+ "[{data.shape[1]}:{data.shape[0]}] {x} [{unit:g}/pix]".format(
964
1003
  page = self.__index,
965
1004
  maxpage = len(self),
966
1005
  name = frame.name,
@@ -972,7 +1011,7 @@ class GraphPlot(MatplotPanel):
972
1011
  a = '%%' if not frame.buffer.flags.writeable else '--'))
973
1012
  else:
974
1013
  self.modeline.SetLabel(
975
- "[{page}/{maxpage}] ---- No buffer (-:-) [-:-] -- [{unit:g}/pixel]".format(
1014
+ "[{page}/{maxpage}] ---- No buffer (-:-) [-:-] -- [{unit:g}/pix]".format(
976
1015
  page = '-',
977
1016
  maxpage = len(self),
978
1017
  unit = self.__unit))
@@ -1124,7 +1163,7 @@ class GraphPlot(MatplotPanel):
1124
1163
  return
1125
1164
  frame = self.frame
1126
1165
  if frame:
1127
- ## [dots/pixel] = [dots/u] * [u/pixel]
1166
+ ## [dots/pix] = [dots/u] * [u/pix]
1128
1167
  dots = self.ddpu[0] * frame.unit * frame.binning
1129
1168
 
1130
1169
  if frame.get_interpolation() == 'nearest' and dots < 1:
@@ -1264,7 +1303,7 @@ class GraphPlot(MatplotPanel):
1264
1303
  self.handler('line_drawn', self.frame)
1265
1304
 
1266
1305
  ## --------------------------------
1267
- ## Selector +Line interface
1306
+ ## Selector + Line interface
1268
1307
  ## --------------------------------
1269
1308
 
1270
1309
  def OnLineSelected(self, evt):
@@ -1337,13 +1376,193 @@ class GraphPlot(MatplotPanel):
1337
1376
  def OnLineShiftEnd(self, evt):
1338
1377
  self.handler('line_moved', self.frame)
1339
1378
 
1379
+ ## --------------------------------
1380
+ ## Marker interface
1381
+ ## --------------------------------
1382
+
1383
+ #: Limit number of markers to display 最大(表示)数を制限する
1384
+ maxnum_markers = 1000
1385
+
1386
+ @property
1387
+ def markers(self):
1388
+ """Marked points data array [[x],[y]]."""
1389
+ xm, ym = self.marked.get_data(orig=0)
1390
+ return np.array((xm, ym))
1391
+
1392
+ @markers.setter
1393
+ def markers(self, v):
1394
+ x, y = v
1395
+ if not hasattr(x, '__iter__'):
1396
+ x, y = [x], [y]
1397
+ elif len(x) > self.maxnum_markers:
1398
+ self.message("- Got too many markers ({}) to plot".format(len(x)))
1399
+ return
1400
+ self.marked.set_data(x, y)
1401
+ self.__marksel = []
1402
+ self.update_art_of_mark()
1403
+ self.handler('mark_drawn', self.frame)
1404
+
1405
+ @markers.deleter
1406
+ def markers(self):
1407
+ if self.markers.size:
1408
+ self.marked.set_data([], [])
1409
+ self.__marksel = []
1410
+ self.update_art_of_mark()
1411
+ self.handler('mark_removed', self.frame)
1412
+
1413
+ def get_current_mark(self):
1414
+ """Currently selected mark."""
1415
+ xm, ym = self.marked.get_data(orig=0)
1416
+ return np.take((xm, ym), self.__marksel, axis=1)
1417
+
1418
+ def set_current_mark(self, x, y):
1419
+ xm, ym = self.marked.get_data(orig=0)
1420
+ j = self.__marksel
1421
+ if j:
1422
+ xm[j], ym[j] = x, y
1423
+ self.marked.set_data(xm, ym)
1424
+ self.update_art_of_mark(j, xm[j], ym[j])
1425
+ else:
1426
+ n = len(xm)
1427
+ k = len(x) if hasattr(x, '__iter__') else 1
1428
+ self.__marksel = list(range(n, n+k))
1429
+ xm, ym = np.append(xm, x), np.append(ym, y)
1430
+ self.marked.set_data(xm, ym)
1431
+ self.marked.set_visible(1)
1432
+ self.update_art_of_mark()
1433
+ self.selector = (x, y)
1434
+
1435
+ def del_current_mark(self):
1436
+ j = self.__marksel
1437
+ if j:
1438
+ xm, ym = self.marked.get_data(orig=0)
1439
+ xm, ym = np.delete(xm, j), np.delete(ym, j)
1440
+ self.__marksel = []
1441
+ self.marked.set_data(xm, ym)
1442
+ n = len(xm)
1443
+ self.__marksel = [j[-1] % n] if n > 0 else []
1444
+ self.update_art_of_mark()
1445
+
1446
+ def update_art_of_mark(self, *args):
1447
+ if args:
1448
+ for k, x, y in zip(*args):
1449
+ art = self.__markarts[k] # art の再描画処理をして終了
1450
+ art.xy = x, y
1451
+ self.draw(self.marked)
1452
+ return
1453
+ for art in self.__markarts: # or reset all arts
1454
+ art.remove()
1455
+ self.__markarts = []
1456
+ if self.marked.get_visible() and self.handler.current_state in (MARK, MARK+DRAGGING):
1457
+ N = self.maxnum_markers
1458
+ xm, ym = self.marked.get_data(orig=0)
1459
+ for k, (x, y) in enumerate(zip(xm[:N], ym[:N])):
1460
+ self.__markarts.append(
1461
+ self.axes.annotate(k, #<matplotlib.text.Annotation>
1462
+ xy=(x,y), xycoords='data',
1463
+ xytext=(6,6), textcoords='offset points',
1464
+ bbox=dict(boxstyle="round", fc=(1,1,1,), ec=(1,0,0,)),
1465
+ color='red', size=7, #fontsize=8,
1466
+ )
1467
+ )
1468
+ self.trace_point(*self.get_current_mark(), type=MARK)
1469
+ self.draw(self.marked)
1470
+
1471
+ def OnMarkAppend(self, evt):
1472
+ xs, ys = self.selector
1473
+ if not self.__marksel and len(xs) > 0:
1474
+ self.set_current_mark(xs, ys)
1475
+ self.handler('mark_drawn', self.frame)
1476
+ self.update_art_of_mark()
1477
+
1478
+ def OnMarkRemove(self, evt):
1479
+ if self.__marksel:
1480
+ self.del_current_mark()
1481
+ self.handler('mark_removed', self.frame)
1482
+
1483
+ def OnMarkSelected(self, evt): #<matplotlib.backend_bases.PickEvent>
1484
+ k = evt.ind[0]
1485
+ if evt.mouseevent.key == 'shift': # 多重マーカー選択
1486
+ if k not in self.__marksel:
1487
+ self.__marksel += [k]
1488
+ else:
1489
+ self.__marksel = [k]
1490
+ self.update_art_of_mark()
1491
+ self.selector = self.get_current_mark()
1492
+ if self.selector.shape[1] > 1:
1493
+ self.handler('line_drawn', self.frame) # 多重マーカー選択時
1494
+
1495
+ def OnMarkDeselected(self, evt): #<matplotlib.backend_bases.PickEvent>
1496
+ self.__marksel = []
1497
+ self.update_art_of_mark()
1498
+
1499
+ def OnMarkDragBegin(self, evt):
1500
+ if not self.frame or self._inaxes(evt):
1501
+ self.handler('quit', evt)
1502
+ return
1503
+ self.__orgpoints = self.get_current_mark()
1504
+
1505
+ def OnMarkDragMove(self, evt):
1506
+ x, y = self.calc_point(evt.xdata, evt.ydata)
1507
+ self.set_current_mark(x, y)
1508
+ self.handler('mark_draw', self.frame)
1509
+
1510
+ def OnMarkDragEscape(self, evt):
1511
+ self.set_current_mark(*self.__orgpoints)
1512
+ self.handler('mark_drawn', self.frame)
1513
+
1514
+ def OnMarkDragEnd(self, evt):
1515
+ self.handler('mark_drawn', self.frame)
1516
+
1517
+ def OnMarkShift(self, evt):
1518
+ j = self.__marksel
1519
+ if j and self.frame:
1520
+ ux, uy = self.frame.xy_unit
1521
+ du = {
1522
+ 'up' : ( 0., uy),
1523
+ 'down' : ( 0.,-uy),
1524
+ 'left' : (-ux, 0.),
1525
+ 'right' : ( ux, 0.),
1526
+ }
1527
+ p = self.get_current_mark() + np.resize(du[evt.key], (2,1))
1528
+ self.set_current_mark(*p)
1529
+ self.handler('mark_draw', self.frame)
1530
+
1531
+ def OnMarkShiftEnd(self, evt):
1532
+ self.handler('mark_drawn', self.frame)
1533
+
1534
+ def next_mark(self, j):
1535
+ self.__marksel = [j]
1536
+ xs, ys = self.get_current_mark()
1537
+ self.xlim += xs[-1] - (self.xlim[1] + self.xlim[0]) / 2
1538
+ self.ylim += ys[-1] - (self.ylim[1] + self.ylim[0]) / 2
1539
+ self.selector = (xs, ys)
1540
+ self.trace_point(xs, ys, type=MARK)
1541
+ self.draw()
1542
+
1543
+ def OnMarkSkipNext(self, evt):
1544
+ n = self.markers.shape[1]
1545
+ j = self.__marksel
1546
+ if j:
1547
+ self.next_mark((j[-1]+1) % n)
1548
+ elif n:
1549
+ self.next_mark(0)
1550
+
1551
+ def OnMarkSkipPrevious(self, evt):
1552
+ n = self.markers.shape[1]
1553
+ j = self.__marksel
1554
+ if j:
1555
+ self.next_mark((j[-1]-1) % n)
1556
+ elif n:
1557
+ self.next_mark(-1)
1558
+
1340
1559
  ## --------------------------------
1341
1560
  ## Region interface
1342
1561
  ## --------------------------------
1343
1562
 
1344
1563
  @property
1345
1564
  def region(self):
1346
- """Rectangle points data array [l,r],[b,t]."""
1565
+ """Cropped rectangle points data array [l,r],[b,t]."""
1347
1566
  x, y = self.rected.get_data(orig=0)
1348
1567
  if len(x) and len(y):
1349
1568
  xo, x = min(x), max(x) #= x[[0, 2]]
@@ -1550,183 +1769,3 @@ class GraphPlot(MatplotPanel):
1550
1769
  self.set_wxcursor(wx.CURSOR_SIZENWSE) # on-NW/SE-corner
1551
1770
  else:
1552
1771
  self.set_wxcursor(wx.CURSOR_ARROW) # outside
1553
-
1554
- ## --------------------------------
1555
- ## Marker interface
1556
- ## --------------------------------
1557
-
1558
- #: Limit number of markers to display 最大(表示)数を制限する
1559
- maxnum_markers = 1000
1560
-
1561
- @property
1562
- def markers(self):
1563
- """Marked points data array [[x],[y]]."""
1564
- xm, ym = self.marked.get_data(orig=0)
1565
- return np.array((xm, ym))
1566
-
1567
- @markers.setter
1568
- def markers(self, v):
1569
- x, y = v
1570
- if not hasattr(x, '__iter__'):
1571
- x, y = [x], [y]
1572
- elif len(x) > self.maxnum_markers:
1573
- self.message("- Got too many markers ({}) to plot".format(len(x)))
1574
- return
1575
- self.marked.set_data(x, y)
1576
- self.__marksel = []
1577
- self.update_art_of_mark()
1578
- self.handler('mark_drawn', self.frame)
1579
-
1580
- @markers.deleter
1581
- def markers(self):
1582
- if self.markers.size:
1583
- self.marked.set_data([], [])
1584
- self.__marksel = []
1585
- self.update_art_of_mark()
1586
- self.handler('mark_removed', self.frame)
1587
-
1588
- def get_current_mark(self):
1589
- """Currently selected mark."""
1590
- xm, ym = self.marked.get_data(orig=0)
1591
- return np.take((xm, ym), self.__marksel, axis=1)
1592
-
1593
- def set_current_mark(self, x, y):
1594
- xm, ym = self.marked.get_data(orig=0)
1595
- j = self.__marksel
1596
- if j:
1597
- xm[j], ym[j] = x, y
1598
- self.marked.set_data(xm, ym)
1599
- self.update_art_of_mark(j, xm[j], ym[j])
1600
- else:
1601
- n = len(xm)
1602
- k = len(x) if hasattr(x, '__iter__') else 1
1603
- self.__marksel = list(range(n, n+k))
1604
- xm, ym = np.append(xm, x), np.append(ym, y)
1605
- self.marked.set_data(xm, ym)
1606
- self.marked.set_visible(1)
1607
- self.update_art_of_mark()
1608
- self.selector = (x, y)
1609
-
1610
- def del_current_mark(self):
1611
- j = self.__marksel
1612
- if j:
1613
- xm, ym = self.marked.get_data(orig=0)
1614
- xm, ym = np.delete(xm, j), np.delete(ym, j)
1615
- self.__marksel = []
1616
- self.marked.set_data(xm, ym)
1617
- n = len(xm)
1618
- self.__marksel = [j[-1] % n] if n > 0 else []
1619
- self.update_art_of_mark()
1620
-
1621
- def update_art_of_mark(self, *args):
1622
- if args:
1623
- for k, x, y in zip(*args):
1624
- art = self.__markarts[k] # art の再描画処理をして終了
1625
- art.xy = x, y
1626
- self.draw(self.marked)
1627
- return
1628
- for art in self.__markarts: # or reset all arts
1629
- art.remove()
1630
- self.__markarts = []
1631
- if self.marked.get_visible() and self.handler.current_state in (MARK, MARK+DRAGGING):
1632
- N = self.maxnum_markers
1633
- xm, ym = self.marked.get_data(orig=0)
1634
- for k, (x, y) in enumerate(zip(xm[:N], ym[:N])):
1635
- self.__markarts.append(
1636
- self.axes.annotate(k, #<matplotlib.text.Annotation>
1637
- xy=(x,y), xycoords='data',
1638
- xytext=(6,6), textcoords='offset points',
1639
- bbox=dict(boxstyle="round", fc=(1,1,1,), ec=(1,0,0,)),
1640
- color='red', size=7, #fontsize=8,
1641
- )
1642
- )
1643
- self.trace_point(*self.get_current_mark(), type=MARK)
1644
- self.draw(self.marked)
1645
-
1646
- def OnMarkAppend(self, evt):
1647
- xs, ys = self.selector
1648
- if not self.__marksel and len(xs) > 0:
1649
- self.set_current_mark(xs, ys)
1650
- self.handler('mark_drawn', self.frame)
1651
- self.update_art_of_mark()
1652
-
1653
- def OnMarkRemove(self, evt):
1654
- if self.__marksel:
1655
- self.del_current_mark()
1656
- self.handler('mark_removed', self.frame)
1657
-
1658
- def OnMarkSelected(self, evt): #<matplotlib.backend_bases.PickEvent>
1659
- k = evt.ind[0]
1660
- if evt.mouseevent.key == 'shift': # 多重マーカー選択
1661
- if k not in self.__marksel:
1662
- self.__marksel += [k]
1663
- else:
1664
- self.__marksel = [k]
1665
- self.update_art_of_mark()
1666
- self.selector = self.get_current_mark()
1667
- if self.selector.shape[1] > 1:
1668
- self.handler('line_drawn', self.frame) # 多重マーカー選択時
1669
-
1670
- def OnMarkDeselected(self, evt): #<matplotlib.backend_bases.PickEvent>
1671
- self.__marksel = []
1672
- self.update_art_of_mark()
1673
-
1674
- def OnMarkDragBegin(self, evt):
1675
- if not self.frame or self._inaxes(evt):
1676
- self.handler('quit', evt)
1677
- return
1678
- self.__orgpoints = self.get_current_mark()
1679
-
1680
- def OnMarkDragMove(self, evt):
1681
- x, y = self.calc_point(evt.xdata, evt.ydata)
1682
- self.set_current_mark(x, y)
1683
- self.handler('mark_draw', self.frame)
1684
-
1685
- def OnMarkDragEscape(self, evt):
1686
- self.set_current_mark(*self.__orgpoints)
1687
- self.handler('mark_drawn', self.frame)
1688
-
1689
- def OnMarkDragEnd(self, evt):
1690
- self.handler('mark_drawn', self.frame)
1691
-
1692
- def OnMarkShift(self, evt):
1693
- j = self.__marksel
1694
- if j and self.frame:
1695
- ux, uy = self.frame.xy_unit
1696
- du = {
1697
- 'up' : ( 0., uy),
1698
- 'down' : ( 0.,-uy),
1699
- 'left' : (-ux, 0.),
1700
- 'right' : ( ux, 0.),
1701
- }
1702
- p = self.get_current_mark() + np.resize(du[evt.key], (2,1))
1703
- self.set_current_mark(*p)
1704
- self.handler('mark_draw', self.frame)
1705
-
1706
- def OnMarkShiftEnd(self, evt):
1707
- self.handler('mark_drawn', self.frame)
1708
-
1709
- def next_mark(self, j):
1710
- self.__marksel = [j]
1711
- xs, ys = self.get_current_mark()
1712
- self.xlim += xs[-1] - (self.xlim[1] + self.xlim[0]) / 2
1713
- self.ylim += ys[-1] - (self.ylim[1] + self.ylim[0]) / 2
1714
- self.selector = (xs, ys)
1715
- self.trace_point(xs, ys, type=MARK)
1716
- self.draw()
1717
-
1718
- def OnMarkSkipNext(self, evt):
1719
- n = self.markers.shape[1]
1720
- j = self.__marksel
1721
- if j:
1722
- self.next_mark((j[-1]+1) % n)
1723
- elif n:
1724
- self.next_mark(0)
1725
-
1726
- def OnMarkSkipPrevious(self, evt):
1727
- n = self.markers.shape[1]
1728
- j = self.__marksel
1729
- if j:
1730
- self.next_mark((j[-1]-1) % n)
1731
- elif n:
1732
- self.next_mark(-1)
mwx/matplot2lg.py CHANGED
@@ -609,7 +609,7 @@ class LineProfile(LinePlot):
609
609
  if frame:
610
610
  self.modeline.SetLabel(
611
611
  "[--] -{a}- {name} ({type}:{mode}) "
612
- "[{length}:{width}] {x} [{unit:g}/pixel]".format(
612
+ "[{length}:{width}] {x} [{unit:g}/pix]".format(
613
613
  name = frame.name,
614
614
  type = frame.buffer.dtype,
615
615
  mode = "logic" if self.__logicp else "pixel",
mwx/nutshell.py CHANGED
@@ -2435,8 +2435,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
2435
2435
 
2436
2436
  def create_buffer(self, filename, index=None):
2437
2437
  """Create a new buffer (internal use only)."""
2438
- try:
2439
- self.Freeze()
2438
+ with wx.FrozenWindow(self):
2440
2439
  buf = Buffer(self, filename, style=wx.BORDER_DEFAULT)
2441
2440
  self.set_attributes(buf, **self.defaultBufferStyle)
2442
2441
  if index is None:
@@ -2444,8 +2443,6 @@ class EditorBook(AuiNotebook, CtrlInterface):
2444
2443
  self.InsertPage(index, buf, buf.name) # => [buffer_activated]
2445
2444
  self.handler('buffer_new', buf)
2446
2445
  return buf
2447
- finally:
2448
- self.Thaw()
2449
2446
 
2450
2447
  def new_buffer(self):
2451
2448
  """Create a new default buffer."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mwxlib
3
- Version: 1.6.5
3
+ Version: 1.6.7
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,14 +1,14 @@
1
1
  mwx/__init__.py,sha256=pS7ZG8QKRypiFFiaWAq_opBB6I_1viZ0zUMk2TbjzE0,667
2
- mwx/bookshelf.py,sha256=yW17nMNPXKHM7LLXLpr9DaRhyFHz_OBAZ_DsuEK2QzA,8387
3
- mwx/controls.py,sha256=B9f_A0ev3SPf75K-LIZCusMLeDGYz1O3cMml7IOrDrM,49870
4
- mwx/framework.py,sha256=S07VXuto0GulB48mVJurs5GsEIRPkvmWPE37l1IgeRI,77463
5
- mwx/graphman.py,sha256=7y2pNi0pOR7MuSFOaINuz4PNRXAuRXyp5ChMaWpQXBU,70042
2
+ mwx/bookshelf.py,sha256=b3LhF0TXFRhbbjg3HUzq4qTk4BLzF713a3Tbh3_0iVI,8455
3
+ mwx/controls.py,sha256=N_4TAEMGNBD3AiVzm4JZ6SDH8VJ2gFsRPFYF40T6yL0,50006
4
+ mwx/framework.py,sha256=N9gTB2Uyi6FvgTVEYi7KLtHifzHajf3nYBK_b_SdQL4,77596
5
+ mwx/graphman.py,sha256=7R-vNzu0VJ_u4eT6-7Sel_qA8BZoSfG7p7zbaf-uetA,70591
6
6
  mwx/images.py,sha256=Kkfy9QI_hMtwShSjUS4-ZpC_EkVuah_XhpBOR4wAKkM,49792
7
- mwx/matplot2.py,sha256=cjdN12RENqWFw1v9QyO05XQc6dK3Pn_ltdC3OfmhGfg,32995
8
- mwx/matplot2g.py,sha256=0gxjl7UKx8QGRI2thpniA7dQu9fpHGG0mvl7Ml2exrc,65474
9
- mwx/matplot2lg.py,sha256=jE-LYPEVaEapQN8L-eviRyEx4Lw-8GyLGzZotrIZShU,27413
7
+ mwx/matplot2.py,sha256=HrURlLP-jEubuHrOhL1yvXOgeduHn1OqYnT2bWg4BoM,32995
8
+ mwx/matplot2g.py,sha256=BzftcjoVx_sFw57osb31jsnIAwJQC8CqexCUC0AY9ZU,66533
9
+ mwx/matplot2lg.py,sha256=91ItF-6_zc_tQGvjMgtgc1UKdI_yhe8dDCzj1nN5TQc,27411
10
10
  mwx/mgplt.py,sha256=SVUJ0ls4gC9xulbWxK2qqmDxf0uBCflvwoPkxoF5s3M,5566
11
- mwx/nutshell.py,sha256=JHFiY-X1pEdFBzSQRXO_loIhJyPuWljWhhGzie3m7TU,147552
11
+ mwx/nutshell.py,sha256=-2QHKIDHEdJhCjcHmhyKBKTYQdydK6m0ssqp597Oe3Q,147505
12
12
  mwx/testsuite.py,sha256=pBB7ZNicI_thrg6LmNPgUOgfMWwRoAaYWN1nFy6t6S4,790
13
13
  mwx/utilus.py,sha256=JOYBTHoo_GmYykX72PgiPzgD2M-1pcOR8gMBLc2bnck,39016
14
14
  mwx/wxmon.py,sha256=aS6lSjDm0PxIhfyBPtg-wIP0v-R3g2K5a3k2mclWSrQ,12798
@@ -22,7 +22,7 @@ mwx/plugins/frame_listview.py,sha256=yd2NCgspqGfTNhj1wxuW8r1zapIm7vNzVX2iytk8CDM
22
22
  mwx/plugins/line_profile.py,sha256=zzm6_7lnAnNepLbh07ordp3nRWDFQJtu719ZVjrVf8s,819
23
23
  mwx/py/__init__.py,sha256=xykgfOytOwNuvXsfkLoumFZSTN-iBsHOjczYXngjmUE,12
24
24
  mwx/py/filling.py,sha256=vWCJoHd_oyXOeXTHtXGY7wfNQeNAZhV3GZu4xlc8GDY,16867
25
- mwxlib-1.6.5.dist-info/METADATA,sha256=PyFl4mr1WzMpVnXtqD2FKECHGPz8-t48mUwkuwjgsgw,7381
26
- mwxlib-1.6.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
- mwxlib-1.6.5.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
28
- mwxlib-1.6.5.dist-info/RECORD,,
25
+ mwxlib-1.6.7.dist-info/METADATA,sha256=JPmghjPapW6r7Yfk1-naUsmJBlU88iLXxPHe6-ahkpU,7381
26
+ mwxlib-1.6.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
+ mwxlib-1.6.7.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
28
+ mwxlib-1.6.7.dist-info/RECORD,,
File without changes