mwxlib 1.3.3__py3-none-any.whl → 1.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of mwxlib might be problematic. Click here for more details.
- mwx/bookshelf.py +12 -3
- mwx/controls.py +91 -80
- mwx/framework.py +75 -84
- mwx/graphman.py +33 -27
- mwx/matplot2.py +9 -9
- mwx/matplot2g.py +68 -57
- mwx/matplot2lg.py +6 -6
- mwx/nutshell.py +45 -33
- mwx/plugins/ffmpeg_view.py +1 -1
- mwx/wxpdb.py +6 -6
- {mwxlib-1.3.3.dist-info → mwxlib-1.4.0.dist-info}/METADATA +1 -2
- mwxlib-1.4.0.dist-info/RECORD +28 -0
- {mwxlib-1.3.3.dist-info → mwxlib-1.4.0.dist-info}/WHEEL +1 -1
- mwxlib-1.3.3.dist-info/LICENSE +0 -21
- mwxlib-1.3.3.dist-info/RECORD +0 -29
- {mwxlib-1.3.3.dist-info → mwxlib-1.4.0.dist-info}/top_level.txt +0 -0
mwx/framework.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#! python3
|
|
2
2
|
"""mwxlib framework.
|
|
3
3
|
"""
|
|
4
|
-
__version__ = "1.
|
|
4
|
+
__version__ = "1.4.0"
|
|
5
5
|
__author__ = "Kazuya O'moto <komoto@jeol.co.jp>"
|
|
6
6
|
|
|
7
7
|
from contextlib import contextmanager
|
|
@@ -32,8 +32,9 @@ def deb(target=None, loop=True, locals=None, debrc=None, **kwargs):
|
|
|
32
32
|
If None, the target is set to `__main__`.
|
|
33
33
|
loop : If True, the app and the mainloop will be created.
|
|
34
34
|
locals : Additional context of the shell
|
|
35
|
-
debrc : file name of the session
|
|
35
|
+
debrc : file name of the session. Defaults to None.
|
|
36
36
|
If None, no session will be created or saved.
|
|
37
|
+
If `''`, the default session (.debrc) will be loaded.
|
|
37
38
|
|
|
38
39
|
**kwargs: Nautilus ShellFrame arguments
|
|
39
40
|
|
|
@@ -872,23 +873,19 @@ class AuiNotebook(aui.AuiNotebook):
|
|
|
872
873
|
self.Bind(aui.EVT_AUINOTEBOOK_TAB_RIGHT_DOWN, tab_menu)
|
|
873
874
|
|
|
874
875
|
@property
|
|
875
|
-
def
|
|
876
|
-
"""Returns all window pages (internal use only)."""
|
|
877
|
-
return [self.GetPage(i) for i in range(self.PageCount)]
|
|
878
|
-
|
|
879
|
-
@property
|
|
880
|
-
def all_tabs(self): # (deprecated) internal use only
|
|
876
|
+
def _all_tabs(self): # (deprecated) internal use only
|
|
881
877
|
"""Returns all AuiTabCtrl objects (internal use only)."""
|
|
882
878
|
return [x for x in self.Children if isinstance(x, aui.AuiTabCtrl)]
|
|
883
879
|
|
|
884
880
|
@property
|
|
885
|
-
def
|
|
881
|
+
def _all_panes(self): # (deprecated) internal use only
|
|
886
882
|
"""Returns all AuiPaneInfo excluding `dummy` one (internal use only)."""
|
|
887
883
|
return list(self._mgr.AllPanes)[1:]
|
|
888
884
|
|
|
889
885
|
def get_pages(self, type=None):
|
|
890
886
|
"""Yields pages of the specified window type."""
|
|
891
|
-
for
|
|
887
|
+
for i in range(self.PageCount):
|
|
888
|
+
win = self.GetPage(i)
|
|
892
889
|
if type is None or isinstance(win, type):
|
|
893
890
|
yield win
|
|
894
891
|
|
|
@@ -926,7 +923,7 @@ class AuiNotebook(aui.AuiNotebook):
|
|
|
926
923
|
Note:
|
|
927
924
|
Argument `win` can also be page.window.Name (not page.caption).
|
|
928
925
|
"""
|
|
929
|
-
for tabs in self.
|
|
926
|
+
for tabs in self._all_tabs: #<aui.AuiTabCtrl>
|
|
930
927
|
for page in tabs.Pages: #<aui.AuiNotebookPage>
|
|
931
928
|
## if page.window is win or page.caption == win:
|
|
932
929
|
if page.window is win or page.window.Name == win:
|
|
@@ -944,8 +941,8 @@ class AuiNotebook(aui.AuiNotebook):
|
|
|
944
941
|
tabs.AddPage(win, page) # Add a page with the copied info.
|
|
945
942
|
if tc1.PageCount == 0:
|
|
946
943
|
## Delete an empty tab and the corresponding pane.
|
|
947
|
-
j = self.
|
|
948
|
-
pane = self.
|
|
944
|
+
j = self._all_tabs.index(tc1)
|
|
945
|
+
pane = self._all_panes[j]
|
|
949
946
|
tc1.Destroy()
|
|
950
947
|
self._mgr.DetachPane(pane.window)
|
|
951
948
|
self._mgr.Update()
|
|
@@ -961,10 +958,10 @@ class AuiNotebook(aui.AuiNotebook):
|
|
|
961
958
|
Perspectives are saved according to page.window.Name.
|
|
962
959
|
User should give it (not page.caption) a unique name.
|
|
963
960
|
"""
|
|
964
|
-
for j, pane in enumerate(self.
|
|
961
|
+
for j, pane in enumerate(self._all_panes):
|
|
965
962
|
pane.name = f"pane{j+1}"
|
|
966
963
|
spec = ""
|
|
967
|
-
for j, tabs in enumerate(self.
|
|
964
|
+
for j, tabs in enumerate(self._all_tabs):
|
|
968
965
|
k = next(k for k, page in enumerate(tabs.Pages)
|
|
969
966
|
if page.window.Shown) # get active window
|
|
970
967
|
## names = [page.caption for page in tabs.Pages]
|
|
@@ -984,19 +981,19 @@ class AuiNotebook(aui.AuiNotebook):
|
|
|
984
981
|
try:
|
|
985
982
|
self.Parent.Freeze()
|
|
986
983
|
## Collapse all tabs to main tabctrl
|
|
987
|
-
maintab = self.
|
|
988
|
-
for win in self.
|
|
984
|
+
maintab = self._all_tabs[0]
|
|
985
|
+
for win in self.get_pages():
|
|
989
986
|
self.move_tab(win, maintab)
|
|
990
987
|
|
|
991
988
|
## Create a new tab using Split method.
|
|
992
989
|
## Note: The normal way of creating panes with `_mgr` crashes.
|
|
993
990
|
|
|
994
|
-
all_names = [win.Name for win in self.
|
|
991
|
+
all_names = [win.Name for win in self.get_pages()]
|
|
995
992
|
for names, k in tabinfo[1:]:
|
|
996
993
|
names, k = eval(names), int(k)
|
|
997
994
|
i = all_names.index(names[0]) # Assuming 0:tab is included.
|
|
998
995
|
self.Split(i, wx.LEFT)
|
|
999
|
-
newtab = self.
|
|
996
|
+
newtab = self._all_tabs[-1]
|
|
1000
997
|
for name in names[1:]:
|
|
1001
998
|
self.move_tab(name, newtab)
|
|
1002
999
|
self.Selection = all_names.index(names[k]) # new tabs active window
|
|
@@ -1005,7 +1002,7 @@ class AuiNotebook(aui.AuiNotebook):
|
|
|
1005
1002
|
names, k = eval(names), int(k)
|
|
1006
1003
|
self.Selection = all_names.index(names[k]) # main tabs active window
|
|
1007
1004
|
|
|
1008
|
-
for j, pane in enumerate(self.
|
|
1005
|
+
for j, pane in enumerate(self._all_panes):
|
|
1009
1006
|
pane.name = f"pane{j+1}"
|
|
1010
1007
|
self._mgr.LoadPerspective(frames)
|
|
1011
1008
|
self._mgr.Update()
|
|
@@ -1061,8 +1058,9 @@ class ShellFrame(MiniFrame):
|
|
|
1061
1058
|
Args:
|
|
1062
1059
|
target : target object of the rootshell.
|
|
1063
1060
|
If None, it will be __main__.
|
|
1064
|
-
session : file name of the session
|
|
1061
|
+
session : file name of the session. Defaults to None.
|
|
1065
1062
|
If None, no session will be created or saved.
|
|
1063
|
+
If `''`, the default session (.debrc) will be loaded.
|
|
1066
1064
|
ensureClose : flag for the shell standalone.
|
|
1067
1065
|
If True, EVT_CLOSE will close the window.
|
|
1068
1066
|
Otherwise the window will be only hidden.
|
|
@@ -1182,7 +1180,7 @@ class ShellFrame(MiniFrame):
|
|
|
1182
1180
|
self._mgr.AddPane(self.ghost,
|
|
1183
1181
|
aui.AuiPaneInfo().Name("ghost")
|
|
1184
1182
|
.Caption("Ghost in the Shell").Right()
|
|
1185
|
-
.MaximizeButton().Show(
|
|
1183
|
+
.MaximizeButton().Show(1))
|
|
1186
1184
|
|
|
1187
1185
|
self._mgr.AddPane(self.watcher,
|
|
1188
1186
|
aui.AuiPaneInfo().Name("watcher")
|
|
@@ -1245,12 +1243,10 @@ class ShellFrame(MiniFrame):
|
|
|
1245
1243
|
'trace_end' : [ None, self.on_trace_end ],
|
|
1246
1244
|
'monitor_begin' : [ None, self.on_monitor_begin ],
|
|
1247
1245
|
'monitor_end' : [ None, self.on_monitor_end ],
|
|
1248
|
-
'buffer_new' : [ None, ],
|
|
1249
1246
|
'shell_new' : [ None, ],
|
|
1250
1247
|
'add_log' : [ None, self.add_log ],
|
|
1251
1248
|
'add_help' : [ None, self.add_help ],
|
|
1252
1249
|
'title_window' : [ None, self.on_title_window ],
|
|
1253
|
-
'buffer_caption_updated' : [ None, self.on_buffer_caption ], # => self.OnActivate
|
|
1254
1250
|
},
|
|
1255
1251
|
0 : {
|
|
1256
1252
|
'* pressed' : (0, fork_debugger),
|
|
@@ -1424,7 +1420,7 @@ class ShellFrame(MiniFrame):
|
|
|
1424
1420
|
|
|
1425
1421
|
def OnClose(self, evt):
|
|
1426
1422
|
if self.debugger.busy:
|
|
1427
|
-
if wx.MessageBox( # Confirm debugger
|
|
1423
|
+
if wx.MessageBox( # Confirm closing the debugger.
|
|
1428
1424
|
"The debugger is running.\n\n"
|
|
1429
1425
|
"Enter [q]uit to exit before closing.\n"
|
|
1430
1426
|
"Continue closing?",
|
|
@@ -1445,7 +1441,7 @@ class ShellFrame(MiniFrame):
|
|
|
1445
1441
|
if buf.need_buffer_save:
|
|
1446
1442
|
self.popup_window(book)
|
|
1447
1443
|
buf.SetFocus()
|
|
1448
|
-
if wx.MessageBox( # Confirm
|
|
1444
|
+
if wx.MessageBox( # Confirm closing the buffer.
|
|
1449
1445
|
"You are closing unsaved content.\n\n"
|
|
1450
1446
|
"Changes to the content will be discarded.\n"
|
|
1451
1447
|
"Continue closing?",
|
|
@@ -1464,21 +1460,30 @@ class ShellFrame(MiniFrame):
|
|
|
1464
1460
|
if not evt.Active:
|
|
1465
1461
|
## Reset autoload when active focus going outside.
|
|
1466
1462
|
self.__autoload = True
|
|
1467
|
-
elif evt.GetActivationReason() == evt.Reason_Mouse
|
|
1468
|
-
and self.__autoload:
|
|
1463
|
+
elif evt.GetActivationReason() == evt.Reason_Mouse and self.__autoload:
|
|
1469
1464
|
## Check all buffers that need to be loaded.
|
|
1465
|
+
verbose = 1
|
|
1470
1466
|
for book in self.get_all_editors():
|
|
1471
1467
|
for buf in book.get_all_buffers():
|
|
1472
1468
|
if buf.need_buffer_load:
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1469
|
+
buf.update_caption()
|
|
1470
|
+
if verbose:
|
|
1471
|
+
with wx.MessageDialog(self, # Confirm load.
|
|
1472
|
+
"The file has been modified externally.\n\n"
|
|
1473
|
+
"The contents of the buffer will be overwritten.\n"
|
|
1474
|
+
"Continue loading {}/{}?".format(book.Name, buf.name),
|
|
1475
|
+
"Load {!r}".format(buf.name),
|
|
1476
|
+
style=wx.YES_NO|wx.CANCEL|wx.HELP|wx.ICON_INFORMATION) as dlg:
|
|
1477
|
+
dlg.SetHelpLabel("Yes to All")
|
|
1478
|
+
ret = dlg.ShowModal()
|
|
1479
|
+
if ret == wx.ID_NO:
|
|
1480
|
+
continue
|
|
1481
|
+
if ret == wx.ID_CANCEL:
|
|
1482
|
+
break # all
|
|
1483
|
+
if ret == wx.ID_HELP: # ID_YESTOALL
|
|
1484
|
+
verbose = 0
|
|
1481
1485
|
book.load_file(buf.filename, buf.markline+1)
|
|
1486
|
+
self.__autoload = False
|
|
1482
1487
|
## Reinitialize self-specific builtins if other instances are destroyed.
|
|
1483
1488
|
if evt.Active:
|
|
1484
1489
|
self.Init()
|
|
@@ -1629,7 +1634,7 @@ class ShellFrame(MiniFrame):
|
|
|
1629
1634
|
if m:
|
|
1630
1635
|
filename, ln = m.groups()
|
|
1631
1636
|
lineno = int(ln)
|
|
1632
|
-
editor = self.
|
|
1637
|
+
editor = next(self.get_all_editors(filename), self.Log)
|
|
1633
1638
|
ret = editor.load_file(filename, lineno)
|
|
1634
1639
|
if ret:
|
|
1635
1640
|
self.popup_window(editor, show)
|
|
@@ -1829,23 +1834,16 @@ class ShellFrame(MiniFrame):
|
|
|
1829
1834
|
title = obj if isinstance(obj, str) else repr(obj)
|
|
1830
1835
|
self.SetTitle("Nautilus - {}".format(title))
|
|
1831
1836
|
|
|
1832
|
-
def on_buffer_caption(self, buf):
|
|
1833
|
-
"""Called when the buffer caption is updated."""
|
|
1834
|
-
if buf.caption_prefix.startswith('!'):
|
|
1835
|
-
v = wx.ActivateEvent(wx.wxEVT_ACTIVATE, True,
|
|
1836
|
-
buf.Id, ActivationReason=0)
|
|
1837
|
-
self.EventHandler.ProcessEvent(v) # => self.OnActivate
|
|
1838
|
-
|
|
1839
1837
|
def add_log(self, text, noerr=None):
|
|
1840
1838
|
"""Add text to the logging buffer.
|
|
1841
|
-
If noerr:bool is specified, add a line-
|
|
1839
|
+
If noerr:bool is specified, add a line-mark.
|
|
1842
1840
|
"""
|
|
1843
1841
|
buf = self.Log.default_buffer or self.Log.new_buffer()
|
|
1844
1842
|
with buf.off_readonly():
|
|
1845
|
-
buf.goto_char(buf.TextLength) # line to set an arrow
|
|
1843
|
+
buf.goto_char(buf.TextLength) # line to set an arrow mark
|
|
1846
1844
|
buf.write(text)
|
|
1847
1845
|
if noerr is not None:
|
|
1848
|
-
## Set a
|
|
1846
|
+
## Set a mark on the current line.
|
|
1849
1847
|
buf.add_marker(buf.cline, 1 if noerr else 2) # 1:white 2:red-arrow
|
|
1850
1848
|
return
|
|
1851
1849
|
|
|
@@ -1873,8 +1871,9 @@ class ShellFrame(MiniFrame):
|
|
|
1873
1871
|
if not hasattr(target, '__dict__'):
|
|
1874
1872
|
raise TypeError("primitive objects cannot be targeted")
|
|
1875
1873
|
|
|
1876
|
-
|
|
1877
|
-
|
|
1874
|
+
try:
|
|
1875
|
+
shell = next(self.get_all_shells(target))
|
|
1876
|
+
except StopIteration:
|
|
1878
1877
|
shell = self.rootshell.__class__(self, target, name="clone",
|
|
1879
1878
|
style=wx.CLIP_CHILDREN|wx.BORDER_NONE)
|
|
1880
1879
|
self.console.AddPage(shell, typename(shell.target))
|
|
@@ -1906,38 +1905,40 @@ class ShellFrame(MiniFrame):
|
|
|
1906
1905
|
yield from self.console.get_pages(type)
|
|
1907
1906
|
yield from self.ghost.get_pages(type)
|
|
1908
1907
|
|
|
1909
|
-
def get_all_shells(self):
|
|
1910
|
-
"""Yields all shells
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
"""
|
|
1915
|
-
|
|
1908
|
+
def get_all_shells(self, target=None):
|
|
1909
|
+
"""Yields all shells with specified target.
|
|
1910
|
+
|
|
1911
|
+
If the shell is found, it switches to the corresponding page.
|
|
1912
|
+
If `target` is not provided, it yields all shells in the notebooks.
|
|
1913
|
+
"""
|
|
1914
|
+
if target is None:
|
|
1915
|
+
yield from self.console.get_pages(type(self.rootshell))
|
|
1916
|
+
else:
|
|
1917
|
+
for shell in self.console.get_pages(type(self.rootshell)):
|
|
1918
|
+
if shell.target is target:
|
|
1919
|
+
self.console.swap_page(shell)
|
|
1920
|
+
yield shell
|
|
1916
1921
|
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1922
|
+
def get_all_editors(self, fn=None):
|
|
1923
|
+
"""Yields all editors with specified fn:filename or code.
|
|
1924
|
+
|
|
1925
|
+
If the editor is found, it switches to the corresponding page.
|
|
1926
|
+
If `fn` is not provided, it yields all editors in the notebooks.
|
|
1927
|
+
"""
|
|
1928
|
+
if fn is None:
|
|
1929
|
+
yield from self.ghost.get_pages(type(self.Log))
|
|
1930
|
+
else:
|
|
1931
|
+
for book in self.ghost.get_pages(type(self.Log)):
|
|
1932
|
+
buf = book.find_buffer(fn)
|
|
1933
|
+
if buf:
|
|
1934
|
+
book.swap_page(buf)
|
|
1935
|
+
yield book
|
|
1921
1936
|
|
|
1922
1937
|
@property
|
|
1923
1938
|
def current_shell(self):
|
|
1924
1939
|
"""Currently selected shell or rootshell."""
|
|
1925
1940
|
return self.console.CurrentPage
|
|
1926
1941
|
|
|
1927
|
-
def find_shell(self, target):
|
|
1928
|
-
"""Find a shell targeting the specified object.
|
|
1929
|
-
If found, switch to the corresponding page.
|
|
1930
|
-
"""
|
|
1931
|
-
for shell in self.get_all_shells():
|
|
1932
|
-
if shell.target is target:
|
|
1933
|
-
self.console.swap_page(shell)
|
|
1934
|
-
return shell
|
|
1935
|
-
|
|
1936
|
-
@property
|
|
1937
|
-
def all_editors(self): # (deprecated) for backward compatibility
|
|
1938
|
-
"""Yields all editors in the notebooks."""
|
|
1939
|
-
return self.ghost.get_pages(type(self.Log))
|
|
1940
|
-
|
|
1941
1942
|
@property
|
|
1942
1943
|
def current_editor(self):
|
|
1943
1944
|
"""Currently selected editor or scratch."""
|
|
@@ -1946,16 +1947,6 @@ class ShellFrame(MiniFrame):
|
|
|
1946
1947
|
return editor
|
|
1947
1948
|
return next((x for x in self.get_all_editors() if x.IsShown()), self.Scratch)
|
|
1948
1949
|
|
|
1949
|
-
def find_editor(self, fn):
|
|
1950
|
-
"""Find an editor containing the specified fn:filename or code.
|
|
1951
|
-
If found, switch to the corresponding page.
|
|
1952
|
-
"""
|
|
1953
|
-
for book in self.get_all_editors():
|
|
1954
|
-
buf = book.find_buffer(fn)
|
|
1955
|
-
if buf:
|
|
1956
|
-
book.swap_page(buf)
|
|
1957
|
-
return book
|
|
1958
|
-
|
|
1959
1950
|
## --------------------------------
|
|
1960
1951
|
## Find text dialog
|
|
1961
1952
|
## --------------------------------
|
mwx/graphman.py
CHANGED
|
@@ -152,32 +152,38 @@ class Thread:
|
|
|
152
152
|
raise KeyboardInterrupt("terminated by user")
|
|
153
153
|
return True
|
|
154
154
|
|
|
155
|
-
def pause(self, msg=
|
|
155
|
+
def pause(self, msg=None, caption=wx.MessageBoxCaptionStr):
|
|
156
156
|
"""Pause the thread.
|
|
157
|
+
Confirm whether to terminate the thread.
|
|
157
158
|
|
|
158
|
-
|
|
159
|
+
Returns:
|
|
160
|
+
True : [OK] if terminating.
|
|
161
|
+
False : [CANCEL] otherwise.
|
|
159
162
|
|
|
160
163
|
Note:
|
|
164
|
+
Use ``check`` method where you want to pause.
|
|
161
165
|
Even after the message dialog is displayed, the thread
|
|
162
166
|
does not suspend until check (or event.wait) is called.
|
|
163
167
|
"""
|
|
164
168
|
if not self.running:
|
|
165
169
|
return None
|
|
166
|
-
if
|
|
167
|
-
msg
|
|
170
|
+
if not msg:
|
|
171
|
+
msg = ("The thread is running.\n\n"
|
|
172
|
+
"Do you want to terminate the thread?")
|
|
168
173
|
try:
|
|
169
174
|
self.event.clear() # suspend
|
|
170
|
-
if wx.MessageBox( # Confirm
|
|
171
|
-
msg
|
|
175
|
+
if wx.MessageBox( # Confirm closing the thread.
|
|
176
|
+
msg, caption,
|
|
172
177
|
style=wx.OK|wx.CANCEL|wx.ICON_WARNING) == wx.OK:
|
|
173
178
|
self.Stop()
|
|
174
|
-
return
|
|
175
|
-
return
|
|
179
|
+
return True
|
|
180
|
+
return False
|
|
176
181
|
finally:
|
|
177
182
|
self.event.set() # resume
|
|
178
183
|
|
|
179
184
|
def Start(self, f, *args, **kwargs):
|
|
180
|
-
"""Start the thread to run the specified function.
|
|
185
|
+
"""Start the thread to run the specified function.
|
|
186
|
+
"""
|
|
181
187
|
@wraps(f)
|
|
182
188
|
def _f(*v, **kw):
|
|
183
189
|
try:
|
|
@@ -213,7 +219,10 @@ class Thread:
|
|
|
213
219
|
def Stop(self):
|
|
214
220
|
"""Stop the thread.
|
|
215
221
|
|
|
216
|
-
|
|
222
|
+
Note:
|
|
223
|
+
Use ``check`` method where you want to stop.
|
|
224
|
+
Even after the message dialog is displayed, the thread
|
|
225
|
+
does not suspend until check (or event.wait) is called.
|
|
217
226
|
"""
|
|
218
227
|
def _stop():
|
|
219
228
|
with wx.BusyInfo("One moment please, "
|
|
@@ -553,9 +562,9 @@ class Graph(GraphPlot):
|
|
|
553
562
|
self.update_art_of_mark()
|
|
554
563
|
|
|
555
564
|
def remove_markups(self):
|
|
556
|
-
del self.
|
|
557
|
-
del self.
|
|
558
|
-
del self.
|
|
565
|
+
del self.selector
|
|
566
|
+
del self.markers
|
|
567
|
+
del self.region
|
|
559
568
|
|
|
560
569
|
def hide_layers(self):
|
|
561
570
|
for name in self.parent.plugins:
|
|
@@ -730,21 +739,21 @@ class Frame(mwx.Frame):
|
|
|
730
739
|
(wx.ID_PASTE, "&Paste\t(C-v)", "Paste buffer from clipboard", Icon('paste'),
|
|
731
740
|
lambda v: self.__view.read_buffer_from_clipboard()),
|
|
732
741
|
(),
|
|
733
|
-
(mwx.ID_(21), "Toggle &
|
|
742
|
+
(mwx.ID_(21), "Toggle &markers", "Show/Hide markups", wx.ITEM_CHECK, Icon('+'),
|
|
734
743
|
lambda v: self.__view.set_markups_visible(v.IsChecked()),
|
|
735
744
|
lambda v: v.Check(self.__view.get_markups_visible())),
|
|
736
745
|
|
|
737
|
-
(mwx.ID_(22), "&Remove
|
|
746
|
+
(mwx.ID_(22), "&Remove markers", "Remove markups", Icon('-'),
|
|
738
747
|
lambda v: self.__view.remove_markups()),
|
|
739
748
|
(),
|
|
740
|
-
(mwx.ID_(23), "Hide all &
|
|
749
|
+
(mwx.ID_(23), "Hide all &layers", "Hide all layers", Icon('xr'),
|
|
741
750
|
lambda v: self.__view.hide_layers()),
|
|
742
751
|
(),
|
|
743
|
-
(mwx.ID_(24), "&Histogram\tCtrl-h", "Show
|
|
752
|
+
(mwx.ID_(24), "&Histogram\tCtrl-h", "Show histogram window", wx.ITEM_CHECK,
|
|
744
753
|
lambda v: self.show_pane(self.histogram, v.IsChecked()),
|
|
745
754
|
lambda v: v.Check(self.histogram.IsShownOnScreen())),
|
|
746
755
|
|
|
747
|
-
(mwx.ID_(25), "&Invert
|
|
756
|
+
(mwx.ID_(25), "&Invert color\t(C-i)", "Invert colormap", wx.ITEM_CHECK,
|
|
748
757
|
lambda v: self.__view.invert_cmap(),
|
|
749
758
|
lambda v: v.Check(self.__view.get_cmap()[-2:] == "_r")),
|
|
750
759
|
]
|
|
@@ -764,10 +773,10 @@ class Frame(mwx.Frame):
|
|
|
764
773
|
## lambda v: self.__view.set_cmap('gray'),
|
|
765
774
|
## lambda v: v.Check(self.__view.get_cmap()[:4] == "gray")),
|
|
766
775
|
##
|
|
767
|
-
("Standard
|
|
776
|
+
("Standard colors",
|
|
768
777
|
[_cmenu(i, c) for i, c in enumerate(colours) if c.islower()]),
|
|
769
778
|
|
|
770
|
-
("Other
|
|
779
|
+
("Other colors",
|
|
771
780
|
[_cmenu(i, c) for i, c in enumerate(colours) if not c.islower()]),
|
|
772
781
|
]
|
|
773
782
|
|
|
@@ -876,20 +885,17 @@ class Frame(mwx.Frame):
|
|
|
876
885
|
for name in self.plugins:
|
|
877
886
|
plug = self.get_plug(name)
|
|
878
887
|
if plug.thread and plug.thread.active:
|
|
879
|
-
if
|
|
888
|
+
if not plug.thread.pause( # Confirm closing the thread.
|
|
880
889
|
"The thread is running.\n\n"
|
|
881
|
-
"Enter [q]uit to exit before closing.\n"
|
|
882
890
|
"Continue closing?",
|
|
883
|
-
"Close {!r}".format(plug.Name)
|
|
884
|
-
style=wx.YES_NO|wx.ICON_INFORMATION) != wx.YES:
|
|
891
|
+
"Close {!r}".format(plug.Name)):
|
|
885
892
|
self.message("The close has been canceled.")
|
|
886
893
|
evt.Veto()
|
|
887
894
|
return
|
|
888
|
-
|
|
889
|
-
break
|
|
895
|
+
## self.Quit()
|
|
890
896
|
for frame in self.graph.get_all_frames():
|
|
891
897
|
if frame.pathname is None:
|
|
892
|
-
if wx.MessageBox( # Confirm
|
|
898
|
+
if wx.MessageBox( # Confirm closing the frame.
|
|
893
899
|
"You are closing unsaved frame.\n\n"
|
|
894
900
|
"Continue closing?",
|
|
895
901
|
"Close {!r}".format(frame.name),
|
mwx/matplot2.py
CHANGED
|
@@ -457,12 +457,12 @@ class MatplotPanel(wx.Panel):
|
|
|
457
457
|
self.canvas.draw()
|
|
458
458
|
|
|
459
459
|
@property
|
|
460
|
-
def
|
|
460
|
+
def selector(self):
|
|
461
461
|
"""Selected points array [[x],[y]]."""
|
|
462
462
|
return np.array(self.selected.get_data(orig=0))
|
|
463
463
|
|
|
464
|
-
@
|
|
465
|
-
def
|
|
464
|
+
@selector.setter
|
|
465
|
+
def selector(self, v):
|
|
466
466
|
x, y = v
|
|
467
467
|
if not hasattr(x, '__iter__'):
|
|
468
468
|
x, y = [x], [y]
|
|
@@ -472,8 +472,8 @@ class MatplotPanel(wx.Panel):
|
|
|
472
472
|
self.draw(self.selected)
|
|
473
473
|
self.trace_point(*v)
|
|
474
474
|
|
|
475
|
-
@
|
|
476
|
-
def
|
|
475
|
+
@selector.deleter
|
|
476
|
+
def selector(self):
|
|
477
477
|
self.selected.set_visible(0)
|
|
478
478
|
self.selected.set_data([], [])
|
|
479
479
|
self.handler('selector_removed', self.frame)
|
|
@@ -502,7 +502,7 @@ class MatplotPanel(wx.Panel):
|
|
|
502
502
|
self.__isMenu = 0
|
|
503
503
|
|
|
504
504
|
def on_pick(self, evt): #<matplotlib.backend_bases.PickEvent>
|
|
505
|
-
"""Find index near (x,y) and set the
|
|
505
|
+
"""Find index near (x,y) and set the selector.
|
|
506
506
|
Called (maybe) after mouse button pressed.
|
|
507
507
|
"""
|
|
508
508
|
if evt.mouseevent.button != 1 or not evt.artist.get_visible():
|
|
@@ -527,7 +527,7 @@ class MatplotPanel(wx.Panel):
|
|
|
527
527
|
evt.index = k = indices[distances.argmin()] # index of the nearest point
|
|
528
528
|
evt.xdata = x = xs[k]
|
|
529
529
|
evt.ydata = y = ys[k]
|
|
530
|
-
self.
|
|
530
|
+
self.selector = ([x], [y])
|
|
531
531
|
self.canvas.draw_idle()
|
|
532
532
|
self.handler('art_picked', evt)
|
|
533
533
|
self.message("({:g}, {:g}) index {}".format(x, y, evt.index))
|
|
@@ -634,7 +634,7 @@ class MatplotPanel(wx.Panel):
|
|
|
634
634
|
|
|
635
635
|
def OnMotion(self, evt):
|
|
636
636
|
"""Called when mouse moves in axes."""
|
|
637
|
-
if not self.
|
|
637
|
+
if not self.selector.size:
|
|
638
638
|
self.trace_point(evt.xdata, evt.ydata)
|
|
639
639
|
|
|
640
640
|
def OnForwardPosition(self, evt):
|
|
@@ -656,7 +656,7 @@ class MatplotPanel(wx.Panel):
|
|
|
656
656
|
|
|
657
657
|
def OnEscapeSelection(self, evt):
|
|
658
658
|
"""Escape from selection."""
|
|
659
|
-
del self.
|
|
659
|
+
del self.selector
|
|
660
660
|
self.canvas.draw_idle()
|
|
661
661
|
|
|
662
662
|
def zoomlim(self, lim, M, c=None):
|