mwxlib 1.6.5__py3-none-any.whl → 1.6.8__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 +5 -4
- mwx/controls.py +9 -5
- mwx/framework.py +50 -45
- mwx/graphman.py +23 -14
- mwx/matplot2.py +2 -2
- mwx/matplot2g.py +236 -197
- mwx/matplot2lg.py +1 -1
- mwx/nutshell.py +1 -4
- {mwxlib-1.6.5.dist-info → mwxlib-1.6.8.dist-info}/METADATA +1 -1
- {mwxlib-1.6.5.dist-info → mwxlib-1.6.8.dist-info}/RECORD +12 -12
- {mwxlib-1.6.5.dist-info → mwxlib-1.6.8.dist-info}/WHEEL +0 -0
- {mwxlib-1.6.5.dist-info → mwxlib-1.6.8.dist-info}/top_level.txt +0 -0
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))
|
|
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)
|
|
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)
|
|
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
|
|
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')
|
|
950
|
+
bmp.SetMaskColour('black') # return dummy-sized blank bitmap
|
|
947
951
|
return bmp
|
|
948
|
-
return wx.NullBitmap
|
|
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.
|
|
4
|
+
__version__ = "1.6.8"
|
|
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
|
|
863
|
-
page = tabs.Pages[evt.Selection]
|
|
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):
|
|
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):
|
|
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()
|
|
891
|
+
wnd = wx.Window.FindFocus() # original focus
|
|
892
892
|
org = self.CurrentPage
|
|
893
893
|
if j != self.Selection:
|
|
894
|
-
self.Selection = j
|
|
895
|
-
self.CurrentPage.SetFocus()
|
|
896
|
-
if wnd and wnd is not org:
|
|
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
|
|
922
|
-
for page in
|
|
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
|
|
925
|
+
return tab, page
|
|
926
926
|
|
|
927
|
-
def move_tab(self, win,
|
|
928
|
-
"""Move the window page to the specified
|
|
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:
|
|
934
|
+
except Exception: # object not found
|
|
933
935
|
return
|
|
934
|
-
page = wx.aui.AuiNotebookPage(nb1)
|
|
936
|
+
page = wx.aui.AuiNotebookPage(nb1) # copy-ctor
|
|
935
937
|
tc1.RemovePage(win) # Accessing nb1 will crash at this point.
|
|
936
|
-
|
|
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
|
|
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,
|
|
981
|
+
self.move_tab(win, 0)
|
|
982
982
|
|
|
983
|
-
## Create a new
|
|
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])
|
|
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,
|
|
994
|
-
self.Selection = all_names.index(names[k])
|
|
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])
|
|
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((
|
|
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,8 @@ class Thread:
|
|
|
86
86
|
except AttributeError:
|
|
87
87
|
self.handler = FSM({ # DNA<Thread>
|
|
88
88
|
None : {
|
|
89
|
-
'thread_begin' : [ None ],
|
|
90
|
-
'thread_end' : [ None ],
|
|
89
|
+
'thread_begin' : [ None ],
|
|
90
|
+
'thread_end' : [ None ],
|
|
91
91
|
},
|
|
92
92
|
})
|
|
93
93
|
|
|
@@ -228,14 +228,14 @@ class LayerInterface(CtrlInterface):
|
|
|
228
228
|
|
|
229
229
|
The layer properties can be switched by the following classvars::
|
|
230
230
|
|
|
231
|
-
menukey
|
|
232
|
-
category
|
|
233
|
-
caption
|
|
234
|
-
|
|
235
|
-
dockable
|
|
236
|
-
|
|
237
|
-
reloadable
|
|
238
|
-
unloadable
|
|
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
|
|
239
239
|
|
|
240
240
|
Note:
|
|
241
241
|
parent <Frame> is not always equal to Parent when floating.
|
|
@@ -444,13 +444,13 @@ class LayerInterface(CtrlInterface):
|
|
|
444
444
|
## return self.pane.IsShown()
|
|
445
445
|
return self.IsShownOnScreen()
|
|
446
446
|
|
|
447
|
-
def Show(self, show=True):
|
|
447
|
+
def Show(self, show=True, interactive=False):
|
|
448
448
|
"""Shows or hides the window.
|
|
449
449
|
|
|
450
450
|
(override) Show associated pane window.
|
|
451
451
|
Note: This might be called from a thread.
|
|
452
452
|
"""
|
|
453
|
-
wx.CallAfter(self.parent.show_pane, self, show) #
|
|
453
|
+
wx.CallAfter(self.parent.show_pane, self, show, interactive) # Use main thread.
|
|
454
454
|
|
|
455
455
|
Drawn = property(
|
|
456
456
|
lambda self: self.IsDrawn(),
|
|
@@ -894,7 +894,7 @@ class Frame(mwx.Frame):
|
|
|
894
894
|
"""Get named pane or notebook pane.
|
|
895
895
|
|
|
896
896
|
Args:
|
|
897
|
-
name:
|
|
897
|
+
name: plug name or object.
|
|
898
898
|
"""
|
|
899
899
|
plug = self.get_plug(name)
|
|
900
900
|
if plug:
|
|
@@ -903,7 +903,16 @@ class Frame(mwx.Frame):
|
|
|
903
903
|
return self._mgr.GetPane(name)
|
|
904
904
|
|
|
905
905
|
def show_pane(self, name, show=True, interactive=False):
|
|
906
|
-
"""Show named pane or notebook pane.
|
|
906
|
+
"""Show named pane or notebook pane.
|
|
907
|
+
|
|
908
|
+
Args:
|
|
909
|
+
name: plug name or object.
|
|
910
|
+
show: Show or hide the pane window.
|
|
911
|
+
interactive: If True, modifier keys can be used to reset or reload
|
|
912
|
+
the plugin when showing the pane:
|
|
913
|
+
- [S-menu] Reset floating position.
|
|
914
|
+
- [M-S-menu] Reload plugin.
|
|
915
|
+
"""
|
|
907
916
|
pane = self.get_pane(name)
|
|
908
917
|
if not pane.IsOk():
|
|
909
918
|
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
|
|
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
|
|
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/
|
|
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
|
|
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.
|
|
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/
|
|
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/
|
|
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}/
|
|
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}/
|
|
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/
|
|
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
|
-
"""
|
|
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}/
|
|
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
|
-
|
|
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,14 +1,14 @@
|
|
|
1
1
|
mwx/__init__.py,sha256=pS7ZG8QKRypiFFiaWAq_opBB6I_1viZ0zUMk2TbjzE0,667
|
|
2
|
-
mwx/bookshelf.py,sha256=
|
|
3
|
-
mwx/controls.py,sha256=
|
|
4
|
-
mwx/framework.py,sha256=
|
|
5
|
-
mwx/graphman.py,sha256=
|
|
2
|
+
mwx/bookshelf.py,sha256=b3LhF0TXFRhbbjg3HUzq4qTk4BLzF713a3Tbh3_0iVI,8455
|
|
3
|
+
mwx/controls.py,sha256=N_4TAEMGNBD3AiVzm4JZ6SDH8VJ2gFsRPFYF40T6yL0,50006
|
|
4
|
+
mwx/framework.py,sha256=hlvLZxCUXmEtZZEgDOaQ3jUV0NREEa7JAIj-XBbP74U,77596
|
|
5
|
+
mwx/graphman.py,sha256=846j6PgkEiwR5XyljwfOApOi1TQXhR1i9w5ZKqtni_g,70370
|
|
6
6
|
mwx/images.py,sha256=Kkfy9QI_hMtwShSjUS4-ZpC_EkVuah_XhpBOR4wAKkM,49792
|
|
7
|
-
mwx/matplot2.py,sha256=
|
|
8
|
-
mwx/matplot2g.py,sha256=
|
|
9
|
-
mwx/matplot2lg.py,sha256=
|
|
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
|
|
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.
|
|
26
|
-
mwxlib-1.6.
|
|
27
|
-
mwxlib-1.6.
|
|
28
|
-
mwxlib-1.6.
|
|
25
|
+
mwxlib-1.6.8.dist-info/METADATA,sha256=_fz-J7CYEdesk07MwqAaXbF2pYX5YD37bvhZzSOYgBY,7381
|
|
26
|
+
mwxlib-1.6.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
27
|
+
mwxlib-1.6.8.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
|
|
28
|
+
mwxlib-1.6.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|