mwxlib 1.7.13__py3-none-any.whl → 1.8.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.
- mwx/bookshelf.py +12 -12
- mwx/controls.py +22 -22
- mwx/framework.py +58 -55
- mwx/graphman.py +87 -74
- mwx/matplot2.py +40 -40
- mwx/matplot2g.py +197 -219
- mwx/matplot2lg.py +32 -32
- mwx/nutshell.py +94 -114
- mwx/plugins/ffmpeg_view.py +40 -33
- mwx/plugins/frame_listview.py +21 -31
- mwx/py/filling.py +4 -6
- mwx/utilus.py +13 -11
- mwx/wxmon.py +7 -9
- mwx/wxpdb.py +2 -1
- mwx/wxwil.py +2 -1
- mwx/wxwit.py +7 -11
- {mwxlib-1.7.13.dist-info → mwxlib-1.8.0.dist-info}/METADATA +1 -1
- mwxlib-1.8.0.dist-info/RECORD +28 -0
- mwxlib-1.7.13.dist-info/RECORD +0 -28
- {mwxlib-1.7.13.dist-info → mwxlib-1.8.0.dist-info}/WHEEL +0 -0
- {mwxlib-1.7.13.dist-info → mwxlib-1.8.0.dist-info}/top_level.txt +0 -0
mwx/graphman.py
CHANGED
|
@@ -81,10 +81,10 @@ class Thread:
|
|
|
81
81
|
try:
|
|
82
82
|
self.handler = self.owner.handler
|
|
83
83
|
except AttributeError:
|
|
84
|
-
self.handler = FSM({
|
|
84
|
+
self.handler = FSM({ # DNA<Thread>
|
|
85
85
|
None : {
|
|
86
|
-
'thread_begin' : [
|
|
87
|
-
'thread_end' : [
|
|
86
|
+
'thread_begin' : [None],
|
|
87
|
+
'thread_end' : [None],
|
|
88
88
|
},
|
|
89
89
|
})
|
|
90
90
|
|
|
@@ -177,9 +177,9 @@ class Thread:
|
|
|
177
177
|
except BdbQuit:
|
|
178
178
|
pass
|
|
179
179
|
except KeyboardInterrupt as e:
|
|
180
|
-
print("- Thread terminated by user
|
|
180
|
+
print("- Thread terminated by user;", e)
|
|
181
181
|
except Exception as e:
|
|
182
|
-
print("- Thread failed in error
|
|
182
|
+
print("- Thread failed in error;", e)
|
|
183
183
|
traceback.print_exc()
|
|
184
184
|
tbstr = traceback.format_tb(e.__traceback__)
|
|
185
185
|
wx.CallAfter(wx.MessageBox,
|
|
@@ -323,11 +323,11 @@ class LayerInterface(CtrlInterface):
|
|
|
323
323
|
if self.parameters:
|
|
324
324
|
self.reset_params(checked_only)
|
|
325
325
|
|
|
326
|
-
self.handler.append({
|
|
326
|
+
self.handler.append({ # DNA<Layer>
|
|
327
327
|
None : {
|
|
328
|
-
'page_shown' : [
|
|
329
|
-
'page_closed' : [
|
|
330
|
-
'page_hidden' : [
|
|
328
|
+
'page_shown' : [None, _F(self.Draw, show=True)],
|
|
329
|
+
'page_closed' : [None, _F(self.Draw, show=False)],
|
|
330
|
+
'page_hidden' : [None, _F(self.Draw, show=False)],
|
|
331
331
|
},
|
|
332
332
|
0 : {
|
|
333
333
|
'C-c pressed' : (0, _F(copy_params)),
|
|
@@ -462,7 +462,7 @@ class LayerInterface(CtrlInterface):
|
|
|
462
462
|
if canvas:
|
|
463
463
|
canvas.draw_idle()
|
|
464
464
|
except Exception as e:
|
|
465
|
-
print(f"- Failed to draw Arts of {self.__module__}
|
|
465
|
+
print(f"- Failed to draw Arts of {self.__module__};", e)
|
|
466
466
|
del self.Arts
|
|
467
467
|
|
|
468
468
|
|
|
@@ -508,14 +508,14 @@ class Graph(GraphPlot):
|
|
|
508
508
|
self.parent = parent
|
|
509
509
|
self.loader = loader or parent
|
|
510
510
|
|
|
511
|
-
self.handler.append({
|
|
511
|
+
self.handler.append({ # DNA<Graph>
|
|
512
512
|
None : {
|
|
513
|
-
'focus_set' : [
|
|
514
|
-
'page_shown' : [
|
|
515
|
-
'page_closed' : [
|
|
516
|
-
'frame_shown' : [
|
|
517
|
-
'S-a pressed' : [
|
|
518
|
-
'f5 pressed' : [
|
|
513
|
+
'focus_set' : [None, _F(self.loader.select_view, view=self)],
|
|
514
|
+
'page_shown' : [None, ],
|
|
515
|
+
'page_closed' : [None, ],
|
|
516
|
+
'frame_shown' : [None, _F(self.update_infobar)],
|
|
517
|
+
'S-a pressed' : [None, _F(self.toggle_infobar)],
|
|
518
|
+
'f5 pressed' : [None, _F(self.refresh)],
|
|
519
519
|
},
|
|
520
520
|
})
|
|
521
521
|
## ドロップターゲットを許可する.
|
|
@@ -547,6 +547,23 @@ class Graph(GraphPlot):
|
|
|
547
547
|
del self.region
|
|
548
548
|
self.draw()
|
|
549
549
|
|
|
550
|
+
## --------------------------------
|
|
551
|
+
## Overridden buffer methods.
|
|
552
|
+
## --------------------------------
|
|
553
|
+
|
|
554
|
+
def kill_all_buffers(self):
|
|
555
|
+
"""Delete all buffers; (override) confirm the action with a dialog."""
|
|
556
|
+
n = sum(not frame.pathname for frame in self.all_frames) # Check *need-save* frames.
|
|
557
|
+
if n:
|
|
558
|
+
s = 's' if n > 1 else ''
|
|
559
|
+
if wx.MessageBox( # Confirm closing the frame.
|
|
560
|
+
f"You are closing {n} unsaved frame{s}.\n\n"
|
|
561
|
+
"Continue closing?",
|
|
562
|
+
style=wx.YES_NO|wx.ICON_INFORMATION) != wx.YES:
|
|
563
|
+
self.message("The close has been canceled.")
|
|
564
|
+
return None
|
|
565
|
+
del self[:]
|
|
566
|
+
|
|
550
567
|
|
|
551
568
|
class MyFileDropLoader(wx.FileDropTarget):
|
|
552
569
|
"""File Drop interface.
|
|
@@ -573,7 +590,7 @@ class MyFileDropLoader(wx.FileDropTarget):
|
|
|
573
590
|
elif ext == '.jssn':
|
|
574
591
|
self.loader.load_session(fn)
|
|
575
592
|
elif ext == '.index':
|
|
576
|
-
self.loader.
|
|
593
|
+
self.loader.import_index(fn, self.view)
|
|
577
594
|
else:
|
|
578
595
|
paths.append(fn) # image file just stacks to be loaded
|
|
579
596
|
if paths:
|
|
@@ -663,26 +680,26 @@ class Frame(mwx.Frame):
|
|
|
663
680
|
lambda v: v.Enable(self.__view.frame is not None)),
|
|
664
681
|
|
|
665
682
|
(wx.ID_CLOSE_ALL, "&Close all\t(C-S-k)", "Kill all buffers", Icon('book_red'),
|
|
666
|
-
lambda v: self.__view.
|
|
683
|
+
lambda v: self.__view.kill_all_buffers(),
|
|
667
684
|
lambda v: v.Enable(self.__view.frame is not None)),
|
|
668
685
|
|
|
669
686
|
(wx.ID_SAVE, "&Save as\tCtrl-s", "Save buffer as", Icon('save'),
|
|
670
687
|
lambda v: self.save_frame(),
|
|
671
688
|
lambda v: v.Enable(self.__view.frame is not None)),
|
|
672
689
|
|
|
673
|
-
(wx.ID_SAVEAS, "&Save as TIFFs", "Save buffers as a multi-page tiff", Icon('saveall'),
|
|
690
|
+
(wx.ID_SAVEAS, "&Save as TIFFs\tCtrl+Shift+s", "Save buffers as a multi-page tiff", Icon('saveall'),
|
|
674
691
|
lambda v: self.save_frames_as_tiff(),
|
|
675
692
|
lambda v: v.Enable(self.__view.frame is not None)),
|
|
676
693
|
(),
|
|
677
|
-
("Index", (
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
(),
|
|
694
|
+
# ("Index", (
|
|
695
|
+
# (mwx.ID_(11), "&Import index", "Import index file", Icon('open'),
|
|
696
|
+
# lambda v: self.import_index()),
|
|
697
|
+
#
|
|
698
|
+
# (mwx.ID_(12), "&Export index", "Export index file", Icon('saveas'),
|
|
699
|
+
# lambda v: self.export_index(),
|
|
700
|
+
# lambda v: v.Enable(self.__view.frame is not None)),
|
|
701
|
+
# )),
|
|
702
|
+
# (),
|
|
686
703
|
("Session", (
|
|
687
704
|
(mwx.ID_(15), "&Open session", "Open session file",
|
|
688
705
|
lambda v: self.load_session()),
|
|
@@ -760,22 +777,22 @@ class Frame(mwx.Frame):
|
|
|
760
777
|
if not frame.parent.IsShown():
|
|
761
778
|
wx.CallAfter(self.show_pane, frame.parent)
|
|
762
779
|
|
|
763
|
-
self.graph.handler.append({
|
|
780
|
+
self.graph.handler.append({ # DNA<Graph:Frame>
|
|
764
781
|
None : {
|
|
765
|
-
'frame_shown' : [
|
|
766
|
-
'frame_loaded' : [
|
|
767
|
-
'frame_modified' : [
|
|
768
|
-
'frame_selected' : [
|
|
769
|
-
'canvas_draw' : [
|
|
782
|
+
'frame_shown' : [None, self.set_title],
|
|
783
|
+
'frame_loaded' : [None, show_frameview],
|
|
784
|
+
'frame_modified' : [None, show_frameview],
|
|
785
|
+
'frame_selected' : [None, self.set_title],
|
|
786
|
+
'canvas_draw' : [None, lambda v: self.sync(self.graph, self.output)],
|
|
770
787
|
},
|
|
771
788
|
})
|
|
772
|
-
self.output.handler.append({
|
|
789
|
+
self.output.handler.append({ # DNA<Graph:Frame>
|
|
773
790
|
None : {
|
|
774
|
-
'frame_shown' : [
|
|
775
|
-
'frame_loaded' : [
|
|
776
|
-
'frame_modified' : [
|
|
777
|
-
'frame_selected' : [
|
|
778
|
-
'canvas_draw' : [
|
|
791
|
+
'frame_shown' : [None, self.set_title],
|
|
792
|
+
'frame_loaded' : [None, show_frameview],
|
|
793
|
+
'frame_modified' : [None, show_frameview],
|
|
794
|
+
'frame_selected' : [None, self.set_title],
|
|
795
|
+
'canvas_draw' : [None, lambda v: self.sync(self.output, self.graph)],
|
|
779
796
|
},
|
|
780
797
|
})
|
|
781
798
|
|
|
@@ -830,11 +847,11 @@ class Frame(mwx.Frame):
|
|
|
830
847
|
name = (frame.pathname or frame.name) if frame else ''
|
|
831
848
|
self.SetTitle("{}@{} - [{}] {}".format(self.Name, platform.node(), ssn, name))
|
|
832
849
|
|
|
833
|
-
def OnActivate(self, evt):
|
|
850
|
+
def OnActivate(self, evt): # <wx._core.ActivateEvent>
|
|
834
851
|
if self and evt.Active:
|
|
835
852
|
self.set_title(self.selected_view.frame)
|
|
836
853
|
|
|
837
|
-
def OnClose(self, evt):
|
|
854
|
+
def OnClose(self, evt): # <wx._core.CloseEvent>
|
|
838
855
|
ssn = os.path.basename(self.session_file or '--')
|
|
839
856
|
with wx.MessageDialog(None,
|
|
840
857
|
"Do you want to save session before closing program?",
|
|
@@ -849,7 +866,7 @@ class Frame(mwx.Frame):
|
|
|
849
866
|
n = sum(bool(plug.thread and plug.thread.active) for plug in self.get_all_plugs())
|
|
850
867
|
if n:
|
|
851
868
|
s = 's' if n > 1 else ''
|
|
852
|
-
if wx.MessageBox(
|
|
869
|
+
if wx.MessageBox( # Confirm closing the thread.
|
|
853
870
|
f"Currently running {n} thread{s}.\n\n"
|
|
854
871
|
"Continue closing?",
|
|
855
872
|
style=wx.YES_NO|wx.ICON_INFORMATION) != wx.YES:
|
|
@@ -857,10 +874,10 @@ class Frame(mwx.Frame):
|
|
|
857
874
|
evt.Veto()
|
|
858
875
|
return
|
|
859
876
|
self.Quit()
|
|
860
|
-
n = sum(frame.pathname
|
|
877
|
+
n = sum(not frame.pathname for frame in self.graph.all_frames) # Check *need-save* frames.
|
|
861
878
|
if n:
|
|
862
879
|
s = 's' if n > 1 else ''
|
|
863
|
-
if wx.MessageBox(
|
|
880
|
+
if wx.MessageBox( # Confirm closing the frame.
|
|
864
881
|
f"You are closing {n} unsaved frame{s}.\n\n"
|
|
865
882
|
"Continue closing?",
|
|
866
883
|
style=wx.YES_NO|wx.ICON_INFORMATION) != wx.YES:
|
|
@@ -986,7 +1003,7 @@ class Frame(mwx.Frame):
|
|
|
986
1003
|
else:
|
|
987
1004
|
pane.Float()
|
|
988
1005
|
|
|
989
|
-
def OnPaneClose(self, evt):
|
|
1006
|
+
def OnPaneClose(self, evt): # <wx.aui.AuiManagerEvent>
|
|
990
1007
|
pane = evt.GetPane()
|
|
991
1008
|
win = pane.window
|
|
992
1009
|
if isinstance(win, aui.AuiNotebook):
|
|
@@ -1034,7 +1051,7 @@ class Frame(mwx.Frame):
|
|
|
1034
1051
|
return next((x for x in self.get_all_plugs() if x is name), None)
|
|
1035
1052
|
|
|
1036
1053
|
def get_all_plugs(self):
|
|
1037
|
-
for
|
|
1054
|
+
for _name, module in self.plugins.items():
|
|
1038
1055
|
yield module.__plug__
|
|
1039
1056
|
|
|
1040
1057
|
def load_plug(self, root, session=None, force=False, show=False,
|
|
@@ -1218,9 +1235,7 @@ class Frame(mwx.Frame):
|
|
|
1218
1235
|
|
|
1219
1236
|
if not hasattr(module, 'ID_'): # give a unique index to the module
|
|
1220
1237
|
global __plug_ID__ # cache ID *not* in [ID_LOWEST(4999):ID_HIGHEST(5999)]
|
|
1221
|
-
|
|
1222
|
-
__plug_ID__
|
|
1223
|
-
except NameError:
|
|
1238
|
+
if "__plug_ID__" not in globals():
|
|
1224
1239
|
__plug_ID__ = 10000
|
|
1225
1240
|
__plug_ID__ += 1
|
|
1226
1241
|
module.ID_ = __plug_ID__
|
|
@@ -1309,7 +1324,7 @@ class Frame(mwx.Frame):
|
|
|
1309
1324
|
shell = self.shellframe.clone_shell(plug)
|
|
1310
1325
|
name = plug.Name # init(shell) で名前を参照するため再定義する
|
|
1311
1326
|
|
|
1312
|
-
@shell.handler.bind("shell_activated")
|
|
1327
|
+
@shell.handler.bind("shell_activated") # @TODO: init action が重複してバインドされてしまう.
|
|
1313
1328
|
def init(shell):
|
|
1314
1329
|
"""Called when the plug shell is activated."""
|
|
1315
1330
|
nonlocal plug
|
|
@@ -1343,7 +1358,7 @@ class Frame(mwx.Frame):
|
|
|
1343
1358
|
## --------------------------------
|
|
1344
1359
|
INDEXFILE = "results.index"
|
|
1345
1360
|
|
|
1346
|
-
def
|
|
1361
|
+
def import_index(self, filename=None, view=None):
|
|
1347
1362
|
"""Load frames :ref to the Index file.
|
|
1348
1363
|
|
|
1349
1364
|
If no view given, the currently selected view is chosen.
|
|
@@ -1379,7 +1394,7 @@ class Frame(mwx.Frame):
|
|
|
1379
1394
|
))
|
|
1380
1395
|
return frames
|
|
1381
1396
|
|
|
1382
|
-
def
|
|
1397
|
+
def export_index(self, filename=None, frames=None):
|
|
1383
1398
|
"""Save frames :ref to the Index file.
|
|
1384
1399
|
"""
|
|
1385
1400
|
view = self.selected_view
|
|
@@ -1405,20 +1420,20 @@ class Frame(mwx.Frame):
|
|
|
1405
1420
|
try:
|
|
1406
1421
|
self.message("Export index of {!r}...".format(frame.name))
|
|
1407
1422
|
fn = frame.pathname
|
|
1408
|
-
if not fn or fn.endswith('>'): #
|
|
1423
|
+
if not fn or fn.endswith('>'): # *dummy-path* --> Use buffer name.
|
|
1409
1424
|
fn = os.path.join(savedir, fix_fnchars(frame.name))
|
|
1410
1425
|
if not os.path.exists(fn):
|
|
1411
1426
|
if not fn.endswith('.tif'):
|
|
1412
1427
|
fn += '.tif'
|
|
1413
1428
|
self.write_buffer(fn, frame.buffer)
|
|
1414
1429
|
frame.pathname = fn
|
|
1415
|
-
frame.name = os.path.basename(fn)
|
|
1430
|
+
frame.name = os.path.basename(fn)
|
|
1416
1431
|
print(' ', self.message("\b done."))
|
|
1417
1432
|
else:
|
|
1418
1433
|
print(' ', self.message("\b skipped."))
|
|
1419
1434
|
output_frames.append(frame)
|
|
1420
1435
|
except OSError as e:
|
|
1421
|
-
print('-', self.message("\b failed
|
|
1436
|
+
print('-', self.message("\b failed;", e))
|
|
1422
1437
|
|
|
1423
1438
|
frames = output_frames
|
|
1424
1439
|
res, mis = self.write_attributes(filename, frames)
|
|
@@ -1433,8 +1448,11 @@ class Frame(mwx.Frame):
|
|
|
1433
1448
|
## --------------------------------
|
|
1434
1449
|
## load/save frames and attributes.
|
|
1435
1450
|
## --------------------------------
|
|
1451
|
+
wildcards = [
|
|
1452
|
+
"TIF file (*.tif)|*.tif",
|
|
1453
|
+
"ALL files (*.*)|*.*",
|
|
1454
|
+
]
|
|
1436
1455
|
|
|
1437
|
-
@classmethod
|
|
1438
1456
|
def read_attributes(self, filename, check_path=True):
|
|
1439
1457
|
"""Read attributes file.
|
|
1440
1458
|
|
|
@@ -1459,13 +1477,13 @@ class Frame(mwx.Frame):
|
|
|
1459
1477
|
try:
|
|
1460
1478
|
res.update(json.loads(s, object_hook=dt_parser)) # Read res safely.
|
|
1461
1479
|
except json.decoder.JSONDecodeError:
|
|
1462
|
-
res.update(eval(s)) # Read
|
|
1480
|
+
res.update(eval(s)) # Read as tuple (deprecated).
|
|
1463
1481
|
|
|
1464
1482
|
if check_path:
|
|
1465
1483
|
for name, attr in tuple(res.items()):
|
|
1466
|
-
fn = os.path.join(savedir, name) #
|
|
1484
|
+
fn = os.path.join(savedir, name) # Search by relpath (saved dir/name).
|
|
1467
1485
|
if os.path.exists(fn):
|
|
1468
|
-
attr['pathname'] = fn # If found, update
|
|
1486
|
+
attr['pathname'] = fn # If found, update the path.
|
|
1469
1487
|
else:
|
|
1470
1488
|
fn = attr.get('pathname') # If not found, check for the recorded path.
|
|
1471
1489
|
if not fn or not os.path.exists(fn):
|
|
@@ -1473,11 +1491,10 @@ class Frame(mwx.Frame):
|
|
|
1473
1491
|
except FileNotFoundError:
|
|
1474
1492
|
pass
|
|
1475
1493
|
except Exception as e:
|
|
1476
|
-
print("- Failed to read attributes
|
|
1494
|
+
print("- Failed to read attributes;", e)
|
|
1477
1495
|
wx.MessageBox(str(e), style=wx.ICON_ERROR)
|
|
1478
1496
|
return res, mis
|
|
1479
1497
|
|
|
1480
|
-
@classmethod
|
|
1481
1498
|
def write_attributes(self, filename, frames, merge_data=True):
|
|
1482
1499
|
"""Write attributes file.
|
|
1483
1500
|
|
|
@@ -1500,10 +1517,10 @@ class Frame(mwx.Frame):
|
|
|
1500
1517
|
new[name] = attr
|
|
1501
1518
|
|
|
1502
1519
|
with open(filename, 'w') as o:
|
|
1503
|
-
# print(pformat(tuple(new.items())), file=o) #
|
|
1520
|
+
# print(pformat(tuple(new.items())), file=o) # Write as tuple (deprecated).
|
|
1504
1521
|
json.dump(new, o, indent=2, default=dt_converter)
|
|
1505
1522
|
except Exception as e:
|
|
1506
|
-
print("- Failed to write attributes
|
|
1523
|
+
print("- Failed to write attributes;", e)
|
|
1507
1524
|
wx.MessageBox(str(e), style=wx.ICON_ERROR)
|
|
1508
1525
|
return new, mis
|
|
1509
1526
|
|
|
@@ -1530,8 +1547,7 @@ class Frame(mwx.Frame):
|
|
|
1530
1547
|
if frames:
|
|
1531
1548
|
saved_results = {}
|
|
1532
1549
|
for frame in frames:
|
|
1533
|
-
if frame.pathname.endswith('>'): #
|
|
1534
|
-
## Attributes are compiled in load_buffer.
|
|
1550
|
+
if frame.pathname.endswith('>'): # *dummy-path* compiled in load_buffer
|
|
1535
1551
|
continue
|
|
1536
1552
|
## Compile attributes from index files located in each frame path.
|
|
1537
1553
|
savedir = os.path.dirname(frame.pathname)
|
|
@@ -1588,6 +1604,7 @@ class Frame(mwx.Frame):
|
|
|
1588
1604
|
_name, ext = os.path.splitext(path)
|
|
1589
1605
|
if ext != ".tif":
|
|
1590
1606
|
path += ".tif"
|
|
1607
|
+
|
|
1591
1608
|
try:
|
|
1592
1609
|
name = os.path.basename(path)
|
|
1593
1610
|
self.message("Saving {!r}...".format(name))
|
|
@@ -1600,7 +1617,7 @@ class Frame(mwx.Frame):
|
|
|
1600
1617
|
n = len(frames)
|
|
1601
1618
|
d = len(str(n))
|
|
1602
1619
|
for j, frame in enumerate(frames):
|
|
1603
|
-
frame.pathname = path + f"<{j:0{d}}>" #
|
|
1620
|
+
frame.pathname = path + f"<{j:0{d}}>" # *dummy-path* in multi-page tiff
|
|
1604
1621
|
## multi-page tiff: 同名のインデクスファイルに属性を書き出す.
|
|
1605
1622
|
self.write_attributes(path[:-4] + ".index", frames, merge_data=False)
|
|
1606
1623
|
self.message("\b done.")
|
|
@@ -1613,10 +1630,6 @@ class Frame(mwx.Frame):
|
|
|
1613
1630
|
## --------------------------------
|
|
1614
1631
|
## load/save images.
|
|
1615
1632
|
## --------------------------------
|
|
1616
|
-
wildcards = [
|
|
1617
|
-
"TIF file (*.tif)|*.tif",
|
|
1618
|
-
"ALL files (*.*)|*.*",
|
|
1619
|
-
]
|
|
1620
1633
|
|
|
1621
1634
|
@staticmethod
|
|
1622
1635
|
def read_buffer(path):
|
|
@@ -1677,7 +1690,7 @@ class Frame(mwx.Frame):
|
|
|
1677
1690
|
page_name, info = items[j] # original buffer name and attributes
|
|
1678
1691
|
else:
|
|
1679
1692
|
page_name = name + f"<{j:0{d}}>" # default buffer name
|
|
1680
|
-
info['pathname'] = path + f"<{j:0{d}}>" #
|
|
1693
|
+
info['pathname'] = path + f"<{j:0{d}}>" # *dummy-path* in multi-page tiff
|
|
1681
1694
|
frame = view.load(buf, page_name, show=0, **info)
|
|
1682
1695
|
frames.append(frame)
|
|
1683
1696
|
else:
|
|
@@ -1803,7 +1816,7 @@ class Frame(mwx.Frame):
|
|
|
1803
1816
|
|
|
1804
1817
|
def _save(view):
|
|
1805
1818
|
paths = [frame.pathname for frame in view.all_frames if frame.pathname]
|
|
1806
|
-
paths = [fn for fn in paths if not fn.endswith('>')] #
|
|
1819
|
+
paths = [fn for fn in paths if not fn.endswith('>')] # *dummy-path* 除外
|
|
1807
1820
|
o.write(f"self.{view.Name}.unit = {view.unit:g}\n")
|
|
1808
1821
|
o.write(f"self.load_frame({paths!r}, self.{view.Name})\n")
|
|
1809
1822
|
try:
|
mwx/matplot2.py
CHANGED
|
@@ -85,10 +85,10 @@ class MatplotPanel(wx.Panel):
|
|
|
85
85
|
|
|
86
86
|
self.message = log or (lambda s: s)
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
# <matplotlib.figure.Figure>
|
|
89
89
|
self.figure = Figure(facecolor='white', figsize=(.1,.1)) # inches
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
# <matplotlib.backends.backend_wxagg.FigureCanvasWxAgg>
|
|
92
92
|
self.canvas = FigureCanvas(self, -1, self.figure)
|
|
93
93
|
|
|
94
94
|
## To avoid AssertionError "self._cachedRenderer is not None"
|
|
@@ -96,7 +96,7 @@ class MatplotPanel(wx.Panel):
|
|
|
96
96
|
## "initial draw which caches the renderer"
|
|
97
97
|
self.canvas.draw()
|
|
98
98
|
|
|
99
|
-
|
|
99
|
+
# <matplotlib.backends.backend_wxagg.NavigationToolbar2WxAgg>
|
|
100
100
|
self.toolbar = Toolbar(self.canvas)
|
|
101
101
|
self.toolbar.Show(0)
|
|
102
102
|
|
|
@@ -161,28 +161,28 @@ class MatplotPanel(wx.Panel):
|
|
|
161
161
|
if self.handler.fork(self.handler.current_event, evt) is None:
|
|
162
162
|
evt.Skip()
|
|
163
163
|
|
|
164
|
-
def skip(evt):
|
|
164
|
+
def skip(evt): # <wx._core.KeyEvent> <matplotlib.backend_bases.MouseEvent>
|
|
165
165
|
try:
|
|
166
166
|
evt.Skip()
|
|
167
167
|
except AttributeError:
|
|
168
168
|
pass
|
|
169
169
|
|
|
170
|
-
self.__handler = FSM({
|
|
170
|
+
self.__handler = FSM({ # DNA<MatplotPanel>
|
|
171
171
|
None : {
|
|
172
|
-
'canvas_draw' : [
|
|
173
|
-
#'canvas_drawn' : [
|
|
174
|
-
#'canvas_resized' : [
|
|
175
|
-
'focus_set' : [
|
|
176
|
-
'focus_kill' : [
|
|
177
|
-
'figure_enter' : [
|
|
178
|
-
'figure_leave' : [
|
|
179
|
-
'axes_enter' : [
|
|
180
|
-
'axes_leave' : [
|
|
181
|
-
'home pressed' : [
|
|
182
|
-
'Xbutton1 pressed' : [
|
|
183
|
-
'Xbutton2 pressed' : [
|
|
184
|
-
'M-left pressed' : [
|
|
185
|
-
'M-right pressed' : [
|
|
172
|
+
'canvas_draw' : [None, self.OnDraw], # before canvas.draw
|
|
173
|
+
#'canvas_drawn' : [None, ], # after canvas.draw
|
|
174
|
+
#'canvas_resized' : [None, ],
|
|
175
|
+
'focus_set' : [None, self.on_focus_set],
|
|
176
|
+
'focus_kill' : [None, self.on_focus_kill],
|
|
177
|
+
'figure_enter' : [None, self.on_figure_enter],
|
|
178
|
+
'figure_leave' : [None, self.on_figure_leave],
|
|
179
|
+
'axes_enter' : [None, ],
|
|
180
|
+
'axes_leave' : [None, ],
|
|
181
|
+
'home pressed' : [None, self.OnHomePosition],
|
|
182
|
+
'Xbutton1 pressed' : [None, self.OnBackPosition],
|
|
183
|
+
'Xbutton2 pressed' : [None, self.OnForwardPosition],
|
|
184
|
+
'M-left pressed' : [None, self.OnBackPosition],
|
|
185
|
+
'M-right pressed' : [None, self.OnForwardPosition],
|
|
186
186
|
},
|
|
187
187
|
NORMAL : {
|
|
188
188
|
'art_picked' : (NORMAL, ),
|
|
@@ -302,16 +302,16 @@ class MatplotPanel(wx.Panel):
|
|
|
302
302
|
|
|
303
303
|
def clear(self):
|
|
304
304
|
"""Initialize the plot figure."""
|
|
305
|
-
|
|
305
|
+
# <matplotlib.axes.Axes>
|
|
306
306
|
self.figure.clear()
|
|
307
307
|
self.figure.add_subplot(111) # cf. add_axes(rect=(l,b,w,h))
|
|
308
308
|
|
|
309
|
-
|
|
309
|
+
# <matplotlib.lines.Line2D>
|
|
310
310
|
(self.selected,) = self.axes.plot([], [], "yo-", ms=6, lw=2, alpha=0.75,
|
|
311
311
|
markeredgecolor='y', visible=0)
|
|
312
312
|
self.selected.set_data([], [])
|
|
313
313
|
|
|
314
|
-
|
|
314
|
+
# <matplotlib.widgets.Cursor>
|
|
315
315
|
self.cursor = Cursor(self.axes, useblit=True, color='grey', linewidth=1)
|
|
316
316
|
self.cursor.visible = 1
|
|
317
317
|
|
|
@@ -392,13 +392,13 @@ class MatplotPanel(wx.Panel):
|
|
|
392
392
|
unselectedModeLineBg = 'auto'
|
|
393
393
|
unselectedModeLineFg = 'auto'
|
|
394
394
|
|
|
395
|
-
def on_modeline_tip(self, evt):
|
|
395
|
+
def on_modeline_tip(self, evt): # <wx._core.MouseEvent>
|
|
396
396
|
flag = self.modeline.HitTest(evt.Position)
|
|
397
397
|
if flag == wx.HT_WINDOW_INSIDE:
|
|
398
398
|
self.modeline.SetToolTip(self.modeline.Label)
|
|
399
399
|
evt.Skip()
|
|
400
400
|
|
|
401
|
-
def on_focus_set(self, evt):
|
|
401
|
+
def on_focus_set(self, evt): # <wx._core.FocusEvent>
|
|
402
402
|
if self.modeline.IsShown():
|
|
403
403
|
self.modeline.SetBackgroundColour(self.selectedModeLineBg)
|
|
404
404
|
self.modeline.SetForegroundColour(self.selectedModeLineFg)
|
|
@@ -406,7 +406,7 @@ class MatplotPanel(wx.Panel):
|
|
|
406
406
|
self.escape()
|
|
407
407
|
evt.Skip()
|
|
408
408
|
|
|
409
|
-
def on_focus_kill(self, evt):
|
|
409
|
+
def on_focus_kill(self, evt): # <wx._core.FocusEvent>
|
|
410
410
|
if self.modeline.IsShown():
|
|
411
411
|
self.modeline.SetBackgroundColour(self.unselectedModeLineBg)
|
|
412
412
|
self.modeline.SetForegroundColour(self.unselectedModeLineFg)
|
|
@@ -450,10 +450,10 @@ class MatplotPanel(wx.Panel):
|
|
|
450
450
|
x, y = x[0], y[0]
|
|
451
451
|
self.message("({:g}, {:g})".format(x, y))
|
|
452
452
|
|
|
453
|
-
def on_figure_enter(self, evt):
|
|
453
|
+
def on_figure_enter(self, evt): # <matplotlib.backend_bases.MouseEvent>
|
|
454
454
|
pass
|
|
455
455
|
|
|
456
|
-
def on_figure_leave(self, evt):
|
|
456
|
+
def on_figure_leave(self, evt): # <matplotlib.backend_bases.MouseEvent>
|
|
457
457
|
self.cursor.clear(evt)
|
|
458
458
|
self.canvas.draw()
|
|
459
459
|
|
|
@@ -493,16 +493,16 @@ class MatplotPanel(wx.Panel):
|
|
|
493
493
|
def p_event(self, v):
|
|
494
494
|
self.__isPressed = v
|
|
495
495
|
|
|
496
|
-
def on_menu_lock(self, evt):
|
|
496
|
+
def on_menu_lock(self, evt): # <matplotlib.backend_bases.MouseEvent>
|
|
497
497
|
self.__isMenu = 1
|
|
498
498
|
|
|
499
|
-
def on_menu(self, evt):
|
|
499
|
+
def on_menu(self, evt): # <matplotlib.backend_bases.MouseEvent>
|
|
500
500
|
if self.__isMenu:
|
|
501
501
|
self.canvas.SetFocus()
|
|
502
502
|
Menu.Popup(self, self.menu)
|
|
503
503
|
self.__isMenu = 0
|
|
504
504
|
|
|
505
|
-
def on_pick(self, evt):
|
|
505
|
+
def on_pick(self, evt): # <matplotlib.backend_bases.PickEvent>
|
|
506
506
|
"""Find index near (x,y) and set the selector.
|
|
507
507
|
Called (maybe) after mouse button pressed.
|
|
508
508
|
"""
|
|
@@ -518,10 +518,10 @@ class MatplotPanel(wx.Panel):
|
|
|
518
518
|
x = evt.mouseevent.xdata
|
|
519
519
|
y = evt.mouseevent.ydata
|
|
520
520
|
try:
|
|
521
|
-
|
|
521
|
+
# <matplotlib.lines.Line2D>
|
|
522
522
|
xs, ys = evt.artist.get_data()
|
|
523
523
|
except AttributeError:
|
|
524
|
-
|
|
524
|
+
# <matplotlib.collections.PathCollection>
|
|
525
525
|
xs, ys = evt.artist.get_offsets().T
|
|
526
526
|
|
|
527
527
|
distances = np.hypot(x-xs[indices], y-ys[indices])
|
|
@@ -533,14 +533,14 @@ class MatplotPanel(wx.Panel):
|
|
|
533
533
|
self.handler('art_picked', evt)
|
|
534
534
|
self.message("({:g}, {:g}) index {}".format(x, y, evt.index))
|
|
535
535
|
|
|
536
|
-
def on_hotkey_press(self, evt):
|
|
536
|
+
def on_hotkey_press(self, evt): # <wx._core.KeyEvent>
|
|
537
537
|
"""Called when a key is pressed."""
|
|
538
538
|
key = hotkey(evt)
|
|
539
539
|
self.__key = regulate_key(key + '-')
|
|
540
540
|
if self.handler('{} pressed'.format(key), evt) is None:
|
|
541
541
|
evt.Skip()
|
|
542
542
|
|
|
543
|
-
def on_hotkey_down(self, evt):
|
|
543
|
+
def on_hotkey_down(self, evt): # <wx._core.KeyEvent>
|
|
544
544
|
"""Called when a key is pressed while dragging.
|
|
545
545
|
Specifically called when the mouse is being captured.
|
|
546
546
|
"""
|
|
@@ -549,14 +549,14 @@ class MatplotPanel(wx.Panel):
|
|
|
549
549
|
else:
|
|
550
550
|
evt.Skip()
|
|
551
551
|
|
|
552
|
-
def on_hotkey_up(self, evt):
|
|
552
|
+
def on_hotkey_up(self, evt): # <wx._core.KeyEvent>
|
|
553
553
|
"""Called when a key is released."""
|
|
554
554
|
key = hotkey(evt)
|
|
555
555
|
self.__key = ''
|
|
556
556
|
if self.handler('{} released'.format(key), evt) is None:
|
|
557
557
|
evt.Skip()
|
|
558
558
|
|
|
559
|
-
def _on_mouse_event(self, evt):
|
|
559
|
+
def _on_mouse_event(self, evt): # <matplotlib.backend_bases.MouseEvent>
|
|
560
560
|
"""Called in mouse event handlers."""
|
|
561
561
|
if not evt.inaxes or evt.inaxes is not self.axes:
|
|
562
562
|
(evt.xdata, evt.ydata) = self.mapdisp2xy(evt.x, evt.y)
|
|
@@ -571,7 +571,7 @@ class MatplotPanel(wx.Panel):
|
|
|
571
571
|
evt.key = key
|
|
572
572
|
return key
|
|
573
573
|
|
|
574
|
-
def on_button_press(self, evt):
|
|
574
|
+
def on_button_press(self, evt): # <matplotlib.backend_bases.MouseEvent>
|
|
575
575
|
"""Called when the mouse button is pressed."""
|
|
576
576
|
self.p_event = evt
|
|
577
577
|
key = self._on_mouse_event(evt)
|
|
@@ -582,7 +582,7 @@ class MatplotPanel(wx.Panel):
|
|
|
582
582
|
self.__isDragging = False
|
|
583
583
|
self.handler('{}button pressed'.format(key), evt)
|
|
584
584
|
|
|
585
|
-
def on_button_release(self, evt):
|
|
585
|
+
def on_button_release(self, evt): # <matplotlib.backend_bases.MouseEvent>
|
|
586
586
|
"""Called when the mouse button is released."""
|
|
587
587
|
key = self._on_mouse_event(evt)
|
|
588
588
|
if self.__isDragging:
|
|
@@ -595,7 +595,7 @@ class MatplotPanel(wx.Panel):
|
|
|
595
595
|
self.handler('{}button released'.format(key), evt)
|
|
596
596
|
self.p_event = None
|
|
597
597
|
|
|
598
|
-
def on_motion_notify(self, evt):
|
|
598
|
+
def on_motion_notify(self, evt): # <matplotlib.backend_bases.MouseEvent>
|
|
599
599
|
"""Called when the mouse is moved."""
|
|
600
600
|
key = self._on_mouse_event(evt)
|
|
601
601
|
if evt.button in (1,2,3):
|
|
@@ -616,7 +616,7 @@ class MatplotPanel(wx.Panel):
|
|
|
616
616
|
return
|
|
617
617
|
self.handler('{} motion'.format(event), evt)
|
|
618
618
|
|
|
619
|
-
def on_scroll(self, evt):
|
|
619
|
+
def on_scroll(self, evt): # <matplotlib.backend_bases.MouseEvent>
|
|
620
620
|
"""Called when scrolling the mouse wheel."""
|
|
621
621
|
self.p_event = evt
|
|
622
622
|
key = self._on_mouse_event(evt)
|