mwxlib 0.99.9__py3-none-any.whl → 1.0.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/framework.py CHANGED
@@ -1,7 +1,7 @@
1
1
  #! python3
2
2
  """mwxlib framework.
3
3
  """
4
- __version__ = "0.99.9"
4
+ __version__ = "1.0.0"
5
5
  __author__ = "Kazuya O'moto <komoto@jeol.co.jp>"
6
6
 
7
7
  from contextlib import contextmanager
@@ -165,22 +165,6 @@ _speckeys = {
165
165
 
166
166
  _speckeys_wxkmap = dict((v, k) for k, v in _speckeys.items())
167
167
 
168
- def getKeyState(key):
169
- """Returns state of speckey (cf. wx.GetKeyState)."""
170
- try:
171
- return wx.GetKeyState(_speckeys_wxkmap[key])
172
- except KeyError:
173
- pass
174
-
175
-
176
- def setKeyState(key, state):
177
- """Makes you feel like having pressed/released speckey."""
178
- vk = wx.UIActionSimulator()
179
- if state:
180
- vk.KeyDown(_speckeys_wxkmap[key])
181
- else:
182
- vk.KeyUp(_speckeys_wxkmap[key])
183
-
184
168
 
185
169
  def hotkey(evt):
186
170
  """Interpret evt.KeyCode as hotkey:str and overwrite evt.key.
@@ -226,10 +210,29 @@ class KeyCtrlInterfaceMixin:
226
210
  spec-map : 'C-c'
227
211
  esc-map : 'escape'
228
212
  """
213
+ message = print # override this in subclass
214
+
229
215
  @postcall
230
216
  def post_message(self, *args, **kwargs):
231
217
  return self.message(*args, **kwargs)
232
218
 
219
+ @staticmethod
220
+ def getKeyState(key):
221
+ """Returns state of speckey (cf. wx.GetKeyState)."""
222
+ try:
223
+ return wx.GetKeyState(_speckeys_wxkmap[key])
224
+ except KeyError:
225
+ pass
226
+
227
+ @staticmethod
228
+ def setKeyState(key, state):
229
+ """Makes you feel like having pressed/released speckey."""
230
+ vk = wx.UIActionSimulator()
231
+ if state:
232
+ vk.KeyDown(_speckeys_wxkmap[key])
233
+ else:
234
+ vk.KeyUp(_speckeys_wxkmap[key])
235
+
233
236
  def make_keymap(self, keymap):
234
237
  """Make a basis of extension map in the handler.
235
238
  """
@@ -259,9 +262,8 @@ class KeyCtrlInterfaceMixin:
259
262
  })
260
263
 
261
264
  def pre_command_hook(self, evt):
262
- """Enter extension mode.
263
- Check text selection for [C-c/C-x].
264
- """
265
+ """Called when entering extension mode (internal use only)."""
266
+ ## Check text selection for [C-c/C-x].
265
267
  wnd = wx.Window.FindFocus()
266
268
  if isinstance(wnd, wx.TextEntry) and wnd.StringSelection\
267
269
  or isinstance(wnd, stc.StyledTextCtrl) and wnd.SelectedText:
@@ -272,6 +274,7 @@ class KeyCtrlInterfaceMixin:
272
274
  evt.Skip()
273
275
 
274
276
  def post_command_hook(self, evt):
277
+ """Called when exiting extension mode (internal use only)."""
275
278
  keymap = self.handler.previous_state
276
279
  if keymap:
277
280
  self.message("{} {}".format(keymap, evt.key))
@@ -334,8 +337,6 @@ class CtrlInterface(KeyCtrlInterfaceMixin):
334
337
  """
335
338
  handler = property(lambda self: self.__handler)
336
339
 
337
- message = print # override this in subclass
338
-
339
340
  def __init__(self):
340
341
  self.__key = ''
341
342
  self.__button = ''
@@ -1736,6 +1737,8 @@ class ShellFrame(MiniFrame):
1736
1737
  self.popup_window(self.linfo)
1737
1738
  self.add_log("<-- Beginning of debugger\r\n")
1738
1739
  self.indicator.Value = 2
1740
+ if wx.IsBusy():
1741
+ wx.EndBusyCursor()
1739
1742
 
1740
1743
  def on_debug_next(self, frame):
1741
1744
  """Called from cmdloop."""
@@ -1772,6 +1775,8 @@ class ShellFrame(MiniFrame):
1772
1775
  del shell.locals
1773
1776
  del shell.globals
1774
1777
  self.indicator.Value = 1
1778
+ if wx.IsBusy():
1779
+ wx.EndBusyCursor()
1775
1780
 
1776
1781
  def set_hookable(self, editor, traceable=True):
1777
1782
  """Bind pointer to set/unset trace."""
mwx/graphman.py CHANGED
@@ -166,8 +166,8 @@ class Thread:
166
166
  msg += '\n\n'
167
167
  try:
168
168
  self.event.clear() # suspend
169
- if wx.MessageBox(msg +
170
- "Do you want to terminate the process?",
169
+ if wx.MessageBox( # Confirm terminatation.
170
+ msg + "Do you want to terminate the process?",
171
171
  style=wx.OK|wx.CANCEL|wx.ICON_WARNING) == wx.OK:
172
172
  self.Stop()
173
173
  return False
@@ -574,8 +574,9 @@ class MyFileDropLoader(wx.FileDropTarget):
574
574
  for fn in filenames:
575
575
  name, ext = os.path.splitext(fn)
576
576
  if ext == '.py' or os.path.isdir(fn):
577
- self.loader.load_plug(fn, show=1, floating_pos=pos,
578
- force=wx.GetKeyState(wx.WXK_ALT))
577
+ self.loader.load_plug(fn, show=1,
578
+ floating_pos=pos,
579
+ force=wx.GetKeyState(wx.WXK_ALT))
579
580
  elif ext == '.jssn':
580
581
  self.loader.load_session(fn)
581
582
  elif ext == '.index':
@@ -946,6 +947,7 @@ class Frame(mwx.Frame):
946
947
  shown = plug.IsShown()
947
948
  except AttributeError:
948
949
  shown = pane.IsShown()
950
+
949
951
  if show and not shown:
950
952
  if isinstance(win, aui.AuiNotebook):
951
953
  j = win.GetPageIndex(plug)
@@ -962,6 +964,11 @@ class Frame(mwx.Frame):
962
964
  else:
963
965
  win.handler('page_closed', win)
964
966
 
967
+ if pane.dock_direction:
968
+ pane.Dock()
969
+ else:
970
+ pane.Float()
971
+
965
972
  ## Modify the floating position of the pane when displayed.
966
973
  ## Note: This is a known bug in wxWidgets 3.17 -- 3.20,
967
974
  ## and will be fixed in wxPython 4.2.1.
@@ -972,39 +979,27 @@ class Frame(mwx.Frame):
972
979
  self._mgr.Update()
973
980
  return (show != shown)
974
981
 
975
- def update_pane(self, name, show=False, **kwargs):
976
- """Update the layout of the pane.
982
+ def update_pane(self, name, **props):
983
+ """Update the layout of the pane (internal use only).
977
984
 
978
985
  Note:
979
986
  This is called automatically from load_plug,
980
987
  and should not be called directly from user.
981
988
  """
982
989
  pane = self.get_pane(name)
983
-
984
- pane.dock_layer = kwargs.get('layer', 0)
985
- pane.dock_pos = kwargs.get('pos', 0)
986
- pane.dock_row = kwargs.get('row', 0)
987
- pane.dock_proportion = kwargs.get('prop') or pane.dock_proportion
988
- pane.floating_pos = kwargs.get('floating_pos') or pane.floating_pos
989
- pane.floating_size = kwargs.get('floating_size') or pane.floating_size
990
+ for k, v in props.items():
991
+ if v is not None:
992
+ setattr(pane, k, v)
990
993
 
991
994
  plug = self.get_plug(name)
992
995
  if plug:
993
996
  dock = plug.dockable
994
- if not isinstance(dock, bool): # prior to kwargs
995
- kwargs.update(dock=dock)
997
+ if not isinstance(dock, bool):
998
+ pane.dock_direction = dock
996
999
  if not plug.caption:
997
1000
  pane.CaptionVisible(False) # no caption bar
998
1001
  pane.Gripper(dock not in (0, 5)) # show a grip when docked
999
1002
  pane.Dockable(dock)
1000
-
1001
- dock = kwargs.get('dock')
1002
- pane.dock_direction = dock or 0
1003
- if dock:
1004
- pane.Dock()
1005
- else:
1006
- pane.Float()
1007
- return self.show_pane(name, show)
1008
1003
 
1009
1004
  def OnPaneClose(self, evt): #<wx.aui.AuiManagerEvent>
1010
1005
  pane = evt.GetPane()
@@ -1113,9 +1108,9 @@ class Frame(mwx.Frame):
1113
1108
  self.register(cls, module)
1114
1109
  return module
1115
1110
 
1116
- def load_plug(self, root, force=False, session=None,
1117
- show=False, dock=False, layer=0, pos=0, row=0, prop=10000,
1118
- floating_pos=None, floating_size=None, **kwargs):
1111
+ def load_plug(self, root, force=False, session=None, show=False,
1112
+ dock=0, floating_pos=None, floating_size=None,
1113
+ **kwargs):
1119
1114
  """Load plugin.
1120
1115
 
1121
1116
  Args:
@@ -1126,10 +1121,6 @@ class Frame(mwx.Frame):
1126
1121
  session : Conditions for initializing the plug and starting session
1127
1122
  show : the pane is shown after loaded
1128
1123
  dock : dock_direction (1:top, 2:right, 3:bottom, 4:left, 5:center)
1129
- layer : dock_layer
1130
- pos : dock_pos
1131
- row : dock_row position
1132
- prop : dock_proportion < 1e6 ?
1133
1124
  floating_pos: posision of floating window
1134
1125
  floating_size: size of floating window
1135
1126
 
@@ -1141,14 +1132,16 @@ class Frame(mwx.Frame):
1141
1132
  Note:
1142
1133
  The root module must have a class Plugin <Layer>
1143
1134
  """
1144
- props = dict(show=show, dock=dock, layer=layer, pos=pos, row=row, prop=prop,
1145
- floating_pos=floating_pos, floating_size=floating_size)
1135
+ props = dict(dock_direction=dock,
1136
+ floating_pos=floating_pos,
1137
+ floating_size=floating_size)
1146
1138
 
1147
1139
  _dirname, name = split_paths(root)
1148
1140
 
1149
1141
  plug = self.get_plug(name)
1150
1142
  if plug and not force:
1151
1143
  self.update_pane(name, **props)
1144
+ self.show_pane(name, show)
1152
1145
  try:
1153
1146
  if session:
1154
1147
  plug.load_session(session)
@@ -1178,15 +1171,11 @@ class Frame(mwx.Frame):
1178
1171
  if name not in self.plugins:
1179
1172
  raise NameError("Plugin name must not be the same as any other panes")
1180
1173
 
1174
+ show = show or pane.IsShown()
1181
1175
  props.update(
1182
- show = show or pane.IsShown(),
1183
- dock = pane.IsDocked() and pane.dock_direction,
1184
- layer = pane.dock_layer,
1185
- pos = pane.dock_pos,
1186
- row = pane.dock_row,
1187
- prop = pane.dock_proportion,
1188
- floating_pos = floating_pos or pane.floating_pos[:], # copy (pane unloaded)
1189
- floating_size = floating_size or pane.floating_size[:], # copy
1176
+ dock_direction = pane.IsDocked() and pane.dock_direction,
1177
+ floating_pos = floating_pos or pane.floating_pos[:], # copy unloading pane
1178
+ floating_size = floating_size or pane.floating_size[:], # copy unloading pane
1190
1179
  )
1191
1180
  except (AttributeError, NameError) as e:
1192
1181
  traceback.print_exc()
@@ -1248,6 +1237,7 @@ class Frame(mwx.Frame):
1248
1237
  plug.Name = name
1249
1238
 
1250
1239
  self.update_pane(name, **props)
1240
+ self.show_pane(name, show)
1251
1241
 
1252
1242
  ## Create a menu
1253
1243
  plug.__Menu_item = None
mwx/images.py CHANGED
@@ -135,6 +135,19 @@ clock = PyEmbeddedImage(
135
135
  b'vqHBv3R3pmbxzgwz4Z+EaTXtwqIogrzjxIJ4QVVV1UyihxgjFv3/K09Bu/lEkBgg5rLZH+fT'
136
136
  b'5dvfn7iFAAAAAElFTkSuQmCC')
137
137
 
138
+ #----------------------------------------------------------------------
139
+ cog = PyEmbeddedImage(
140
+ b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAAK/INwWK6QAAABl0'
141
+ b'RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGSSURBVCjPVVFNSwJhEF78Ad79'
142
+ b'Cf6PvXQRsotUlzKICosuRYmR2RJR0KE6lBFFZVEbpFBSqKu2rum6llFS9HHI4iUhT153n6Zt'
143
+ b'IWMOM+/MM88z7wwH7s9Ub16SJcnbmrNcxVm2q7Z8/QPvEOtntpj92NkCqITLepEpjix7xQti'
144
+ b'LOoQ2b6+E7YAN/5nfOEJ2WbKqOIOJ4bYVMEQx4LfBBQDsvFMhUcCVU1/CxVXmDBGA5ZETrhD'
145
+ b'CQVcYAPbyEJBhvrnBVPiSpNr6cYDNCQwo4zzU/ySckkgDYuNuVpI42T9k4gLKGMPs/xPzzov'
146
+ b'QiY2hQYe0jlJfyNNhTqiWDYBq/wBMcSRpnyPzu1oS7WtxjVBSthU1vgVksiQ3Dn6Gp5ah2YO'
147
+ b'KQo5GiuHPA6xT1EKpxQNCNYejgIR457KKio0S56YckjSa9jo//3mrj+BV0QQagqGTOo+Y7gZ'
148
+ b'If1puP3WHoLhEb2PjTlCTCWGXtbp8DCX3hZuOdaIc9A+aQvWk4ihq95p67a7nP+u+Ws+r0dq'
149
+ b'l9z/zv0NCYhdCPKZ7oYAAAAASUVORK5CYII=')
150
+
138
151
  #----------------------------------------------------------------------
139
152
  colour = PyEmbeddedImage(
140
153
  b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0'
mwx/matplot2g.py CHANGED
@@ -21,7 +21,7 @@ from .matplot2 import MatplotPanel
21
21
  from .matplot2 import NORMAL, DRAGGING, PAN, ZOOM, MARK, LINE, REGION
22
22
 
23
23
 
24
- def _imcv(src):
24
+ def _to_cvtype(src):
25
25
  """Convert the image to a type that can be applied to the cv2 function.
26
26
  Note:
27
27
  CV2 normally accepts uint8/16 and float32/64.
@@ -31,33 +31,18 @@ def _imcv(src):
31
31
  return src
32
32
 
33
33
 
34
- def _to_buffer(img):
35
- if isinstance(img, Image.Image):
36
- ## return np.asarray(img) # ref
37
- return np.array(img) # copy
38
-
39
- if isinstance(img, wx.Bitmap):
40
- img = img.ConvertToImage()
41
-
42
- if isinstance(img, wx.Image):
43
- w, h = img.GetSize()
44
- buf = np.frombuffer(img.GetDataBuffer(), dtype='uint8')
45
- return buf.reshape(h, w, 3)
46
- return img
47
-
48
-
49
34
  def _to_array(x):
50
35
  if isinstance(x, (list, tuple)):
51
36
  x = np.array(x)
52
37
  return x
53
38
 
54
39
 
55
- def imconvert(src, cutoff=0, threshold=None, binning=1):
56
- """Convert buffer to image<uint8>
40
+ def _to_image(src, cutoff=0, threshold=None, binning=1):
41
+ """Convert buffer to image <uint8>
57
42
 
58
43
  >>> dst = (src-a) * 255 / (b-a)
59
44
 
60
- cf. convertScaleAbs(src[, dst[, alpha[, beta]]]) -> dst<uint8>
45
+ cf. convertScaleAbs(src[, dst[, alpha[, beta]]]) -> dst <uint8>
61
46
 
62
47
  >>> dst = |src * alpha + beta|
63
48
  alpha = 255 / (b-a)
@@ -80,13 +65,13 @@ def imconvert(src, cutoff=0, threshold=None, binning=1):
80
65
 
81
66
  if bins > 1:
82
67
  ## src = src[::bins,::bins]
83
- src = _imcv(src)
68
+ src = _to_cvtype(src)
84
69
  src = cv2.resize(src, None, fx=1/bins, fy=1/bins, interpolation=cv2.INTER_AREA)
85
70
 
86
- if src.dtype == np.uint8:
87
- return bins, (0,255), src
71
+ if src.dtype == np.uint8: # RGB or gray image <uint8>
72
+ return bins, (0, 255), src
88
73
 
89
- if hasattr(cutoff, '__iter__'):
74
+ if hasattr(cutoff, '__iter__'): # cutoff vlim:list is specified.
90
75
  a, b = cutoff
91
76
  elif cutoff > 0:
92
77
  a = np.percentile(src, cutoff)
@@ -133,8 +118,17 @@ class AxesImagePhantom:
133
118
  self.__aspect_ratio = aspect
134
119
  self.__attributes = attributes
135
120
  self.__attributes['localunit'] = self.__localunit
136
- self.__buf = _to_buffer(buf)
137
- bins, vlim, img = imconvert(self.__buf,
121
+ if isinstance(buf, Image.Image):
122
+ buf = np.array(buf) # copy buffer to array
123
+ if isinstance(buf, wx.Bitmap):
124
+ buf = buf.ConvertToImage() # bitmap to image
125
+ if isinstance(buf, wx.Image): # image to RGB array
126
+ w, h = buf.GetSize()
127
+ buf = np.frombuffer(buf.GetDataBuffer(), dtype='uint8').reshape(h, w, 3)
128
+ if buf.ndim > 2:
129
+ buf = cv2.cvtColor(buf, cv2.COLOR_RGB2GRAY) # RGB to grayscale
130
+ self.__buf = buf
131
+ bins, vlim, img = _to_image(self.__buf,
138
132
  cutoff = self.parent.score_percentile,
139
133
  threshold = self.parent.nbytes_threshold,
140
134
  )
@@ -279,9 +273,8 @@ class AxesImagePhantom:
279
273
  def update_buffer(self, buf=None):
280
274
  """Update buffer and the image (internal use only)."""
281
275
  if buf is not None:
282
- self.__buf = _to_buffer(buf)
283
-
284
- bins, vlim, img = imconvert(self.__buf,
276
+ self.__buf = buf
277
+ bins, vlim, img = _to_image(self.__buf,
285
278
  cutoff = self.parent.score_percentile,
286
279
  threshold = self.parent.nbytes_threshold,
287
280
  )
@@ -951,7 +944,7 @@ class GraphPlot(MatplotPanel):
951
944
  data = frame.roi
952
945
  GraphPlot.clipboard_name = name
953
946
  GraphPlot.clipboard_data = data
954
- bins, vlim, img = imconvert(data, frame.vlim)
947
+ bins, vlim, img = _to_image(data, frame.vlim)
955
948
  Clipboard.imwrite(img)
956
949
  self.message("Write buffer to clipboard.")
957
950
  except Exception as e:
@@ -965,12 +958,12 @@ class GraphPlot(MatplotPanel):
965
958
  data = GraphPlot.clipboard_data
966
959
  if name:
967
960
  self.message("Read buffer from clipboard.")
968
- self.load(data)
969
961
  GraphPlot.clipboard_name = None
970
962
  GraphPlot.clipboard_data = None
971
963
  else:
972
964
  self.message("Read image from clipboard.")
973
- self.load(Clipboard.imread())
965
+ data = Clipboard.imread()
966
+ self.load(data)
974
967
  except Exception as e:
975
968
  traceback.print_exc()
976
969
  self.message("- No data in clipboard.", e)
mwx/nutshell.py CHANGED
@@ -49,7 +49,6 @@ py_where_re = r'> +([^*?"<>|\r\n]+?):([0-9]+)'
49
49
  py_break_re = r'at ([^*?"<>|\r\n]+?):([0-9]+)'
50
50
 
51
51
  ## Custom constants in wx.stc
52
- stc.STC_P_WORD3 = 20 # deprecated
53
52
  stc.STC_STYLE_CARETLINE = 40
54
53
  stc.STC_STYLE_ANNOTATION = 41
55
54
 
@@ -635,9 +634,9 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
635
634
 
636
635
  self.IndicatorSetStyle(11, stc.STC_INDIC_STRAIGHTBOX)
637
636
  self.IndicatorSetUnder(11, True)
638
- self.IndicatorSetAlpha(11, 255)
639
- self.IndicatorSetOutlineAlpha(11, 255)
640
- self.IndicatorSetForeground(11, "yellow")
637
+ self.IndicatorSetAlpha(11, 60)
638
+ self.IndicatorSetOutlineAlpha(11, 60)
639
+ self.IndicatorSetForeground(11, "light gray")
641
640
 
642
641
  self.IndicatorSetStyle(2, stc.STC_INDIC_DOTS)
643
642
  self.IndicatorSetForeground(2, "light gray")
@@ -804,11 +803,11 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
804
803
  self.mark = self.cpos
805
804
 
806
805
  def set_pointer(self):
807
- if self.pointer == self.cline:
806
+ if self.pointer == self.cline: # toggle
808
807
  self.pointer = -1
809
808
  else:
810
- self.pointer = self.cline
811
- self.red_pointer = -1
809
+ self.pointer = self.cline # reset
810
+ self.red_pointer = -1
812
811
 
813
812
  def exchange_point_and_mark(self):
814
813
  p = self.cpos
@@ -1419,15 +1418,15 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
1419
1418
  def _format(ln):
1420
1419
  return "{:4d} {}".format(ln+1, self.GetLine(ln).strip())
1421
1420
 
1422
- pts = self.StyleGetSize(stc.STC_STYLE_DEFAULT)
1423
- self.StyleSetSize(stc.STC_STYLE_DEFAULT, pts-1)
1421
+ ## pts = self.StyleGetSize(stc.STC_STYLE_DEFAULT)
1422
+ ## self.StyleSetSize(stc.STC_STYLE_DEFAULT, pts-1)
1424
1423
 
1425
1424
  self.AutoCompSetSeparator(ord('\n'))
1426
1425
  self.AutoCompShow(0, '\n'.join(map(_format, self.__itextlines)))
1427
1426
  self.AutoCompSelect("{:4d}".format(self.cline+1))
1428
1427
  self.Bind(stc.EVT_STC_AUTOCOMP_SELECTION, self.on_itext_selection)
1429
1428
 
1430
- self.StyleSetSize(stc.STC_STYLE_DEFAULT, pts)
1429
+ ## self.StyleSetSize(stc.STC_STYLE_DEFAULT, pts)
1431
1430
 
1432
1431
  def on_itext_exit(self, evt):
1433
1432
  """Called when exiting filter_text mode."""
@@ -2144,7 +2143,6 @@ class Buffer(EditorInterface, EditWindow):
2144
2143
  self.AnnotationSetStyle(lx, stc.STC_STYLE_ANNOTATION)
2145
2144
  self.AnnotationSetText(lx, msg)
2146
2145
  self.message(e)
2147
- ## print(msg, file=sys.__stderr__)
2148
2146
  else:
2149
2147
  self.code = code
2150
2148
  del self.pointer # Reset pointer (debugger hook point).
@@ -2583,19 +2581,21 @@ class Interpreter(interpreter.Interpreter):
2583
2581
  interpreter.Interpreter.showtraceback(self)
2584
2582
 
2585
2583
  t, v, tb = sys.exc_info()
2586
- v.lineno = tb.tb_next.tb_lineno
2587
- v.filename = tb.tb_next.tb_frame.f_code.co_filename
2584
+ while tb.tb_next:
2585
+ tb = tb.tb_next
2586
+ v.lineno = tb.tb_lineno
2587
+ v.filename = tb.tb_frame.f_code.co_filename
2588
2588
  try:
2589
2589
  self.parent.handler('interp_error', v)
2590
2590
  except AttributeError:
2591
2591
  pass
2592
2592
 
2593
- def showsyntaxerror(self, filename=None):
2593
+ def showsyntaxerror(self, filename=None, **kwargs):
2594
2594
  """Display the syntax error that just occurred.
2595
2595
 
2596
2596
  (override) Pass the syntax error info to the parent:shell.
2597
2597
  """
2598
- interpreter.Interpreter.showsyntaxerror(self, filename)
2598
+ interpreter.Interpreter.showsyntaxerror(self, filename, **kwargs)
2599
2599
 
2600
2600
  t, v, tb = sys.exc_info()
2601
2601
  try:
@@ -2711,7 +2711,6 @@ class Nautilus(EditorInterface, Shell):
2711
2711
  obj.this = inspect.getmodule(obj)
2712
2712
  obj.shell = self # overwrite the facade <wx.py.shell.ShellFacade>
2713
2713
  except AttributeError:
2714
- ## print("- cannot overwrite target vars:", e)
2715
2714
  pass
2716
2715
  self.parent.handler('title_window', obj)
2717
2716
 
@@ -3206,8 +3205,8 @@ class Nautilus(EditorInterface, Shell):
3206
3205
  Note:
3207
3206
  This is called before run, execute, and original magic.
3208
3207
  """
3209
- sep1 = "`@=;#" # [`] no ops, no spaces, no comma
3210
- sep2 = "`@=+-/*%<>&|^~,; \t#" # [@] ops, delims, and whitespaces
3208
+ sep1 = "`@=;\r\n#" # [`] no ops, no spaces, no comma
3209
+ sep2 = "`@=+-/*%<>&|^~,; \t\r\n#" # [@] ops, delims, and whitespaces
3211
3210
 
3212
3211
  def _popiter(ls, f):
3213
3212
  pred = f if callable(f) else re.compile(f).match
@@ -3276,9 +3275,10 @@ class Nautilus(EditorInterface, Shell):
3276
3275
  Delete target shell to prevent referencing the dead shell.
3277
3276
  """
3278
3277
  def _del():
3278
+ obj = self.target
3279
3279
  try:
3280
- if not self.target.shell:
3281
- del self.target.shell # delete the facade <wx.py.shell.ShellFacade>
3280
+ if not obj.shell:
3281
+ del obj.shell # delete the facade <wx.py.shell.ShellFacade>
3282
3282
  except AttributeError:
3283
3283
  pass
3284
3284
  wx.CallAfter(_del)
@@ -3288,11 +3288,14 @@ class Nautilus(EditorInterface, Shell):
3288
3288
  Reset localvars assigned for the shell target.
3289
3289
  """
3290
3290
  self.trace_position()
3291
- self.parent.handler('title_window', self.target)
3291
+ obj = self.target
3292
3292
  try:
3293
- self.target.shell = self # overwrite the facade <wx.py.shell.ShellFacade>
3293
+ obj.self = obj
3294
+ obj.this = inspect.getmodule(obj)
3295
+ obj.shell = self # overwrite the facade <wx.py.shell.ShellFacade>
3294
3296
  except AttributeError:
3295
3297
  pass
3298
+ self.parent.handler('title_window', obj)
3296
3299
 
3297
3300
  def on_inactivated(self, shell):
3298
3301
  """Called when shell:self is inactivated.
@@ -3328,7 +3331,7 @@ class Nautilus(EditorInterface, Shell):
3328
3331
 
3329
3332
  def on_interp_error(self, e):
3330
3333
  ln = self.LineFromPosition(self.bolc)
3331
- self.pointer = ln + e.lineno - 1
3334
+ self.red_pointer = ln + e.lineno - 1
3332
3335
 
3333
3336
  ## --------------------------------
3334
3337
  ## Attributes of the shell
@@ -3652,11 +3655,11 @@ class Nautilus(EditorInterface, Shell):
3652
3655
  lines = [int(ln) for fn, ln in err if fn == filename]
3653
3656
  if lines:
3654
3657
  region = self.get_region(self.cline)
3655
- self.pointer = region[0] + lines[-1] - 1
3658
+ lx = region[0] + lines[-1] - 1
3659
+ self.red_pointer = lx
3656
3660
  self.message(e)
3657
- ## print(msg, file=sys.__stderr__)
3658
3661
  else:
3659
- del self.pointer
3662
+ del self.red_pointer
3660
3663
  self.message("Evaluated {!r} successfully.".format(filename))
3661
3664
  else:
3662
3665
  self.message("No region")
@@ -77,7 +77,6 @@ class Plugin(Layer):
77
77
  """Media loader using FFMpeg (installation required).
78
78
  """
79
79
  menukey = "Plugins/Extensions/FFMpeg viewer"
80
- ## menukey = "FFMpeg/"
81
80
  dockable = False
82
81
 
83
82
  def Init(self):
mwx/plugins/fft_view.py CHANGED
@@ -26,7 +26,7 @@ class Plugin(Layer):
26
26
  Rectangular regions will result in distorted patterns.
27
27
  長方形のリージョンは歪んだパターンになるので要注意
28
28
  """
29
- menukey = "Plugins/Extensions/&FFT view"
29
+ menukey = "Plugins/Extensions/&FFT view\tAlt+f"
30
30
  caption = "FFT view"
31
31
 
32
32
  def Init(self):
@@ -243,7 +243,7 @@ class CheckList(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
243
243
  class Plugin(Layer):
244
244
  """Property list of Graph buffers.
245
245
  """
246
- menukey = "Plugins/Extensions/&Buffer listbox\tCtrl+b"
246
+ menukey = "Plugins/Extensions/&Buffer listbox\tAlt+b"
247
247
  caption = "Property list"
248
248
  dockable = False
249
249
 
@@ -8,7 +8,7 @@ from mwx.matplot2lg import LineProfile
8
8
  class Plugin(Layer):
9
9
  """Line profile of the currently selected buffers.
10
10
  """
11
- menukey = "Plugins/Extensions/&Line profile\tCtrl+l"
11
+ menukey = "Plugins/Extensions/&Line profile\tAlt+l"
12
12
  caption = "Line profile"
13
13
  dockable = False
14
14
 
mwx/wxpdb.py CHANGED
@@ -295,10 +295,6 @@ class Debugger(Pdb):
295
295
  self.__hookpoint = None
296
296
  self.indents = ' ' * 2
297
297
  self.stdin.input = '' # clear stdin buffer
298
- def _continue():
299
- if wx.IsBusy():
300
- wx.EndBusyCursor()
301
- wx.CallAfter(_continue)
302
298
 
303
299
  def on_debug_mark(self, frame):
304
300
  """Called when interaction."""
@@ -365,11 +361,6 @@ class Debugger(Pdb):
365
361
 
366
362
  ## Note: Required to terminate the reader of threading pdb.
367
363
  self.send_input('\n')
368
-
369
- def _continue():
370
- if wx.IsBusy():
371
- wx.EndBusyCursor()
372
- wx.CallAfter(_continue)
373
364
 
374
365
  def on_trace_hook(self, frame):
375
366
  """Called when a breakppoint is reached."""
mwx/wxwit.py CHANGED
@@ -217,8 +217,6 @@ def dump(widget=None):
217
217
  def watchit(widget=None, **kwargs):
218
218
  """Wx.py tool for watching widget tree structure and events."""
219
219
  from wx.lib.inspection import InspectionTool
220
- if widget:
221
- kwargs.update(locals=widget.__dict__)
222
220
  it = InspectionTool()
223
221
  it.Init(**kwargs)
224
222
  it.Show(widget)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mwxlib
3
- Version: 0.99.9
3
+ Version: 1.0.0
4
4
  Summary: A wrapper of matplotlib and wxPython (phoenix)
5
5
  Home-page: https://github.com/komoto48g/mwxlib
6
6
  Author: Kazuya O'moto
@@ -39,22 +39,17 @@ These instructions will get you a copy of the project up and running on your loc
39
39
  - ~~Python 2.7~~ (PY2 support has ended since 0.50)
40
40
  - ~~Python 3.5~~ (PY35 support has ended since 0.70)
41
41
  - ~~Python 3.7~~ (PY37 support has ended since 0.80)
42
- - Python 3.8 -- 3.9 (deprecated since 0.90)
43
- - wxpython >= 4.1.1
42
+ - ~~Python 3.8 -- 3.9~~ (Deprecated since 0.90)
43
+ - Python 3.10 -- 3.12
44
+ - wxpython >= 4.2.2 (recommended)
44
45
  - numpy
45
46
  - pillow
46
47
  - matplotlib
47
48
  - opencv-python
48
- - Python 3.10 -- 3.11
49
- - wxpython >= 4.2.1
50
- - numpy
51
- - pillow
52
- - matplotlib
53
- - opencv-python
54
- - Python 3.12
55
- - A version of wxpython for PY312 has not yet released on PyPi.
56
- * You can download the snapshot from https://wxpython.org/Phoenix/snapshot-builds/,
57
- * or the latest snapshot from Azure Pipelines https://alldunn.visualstudio.com/wxPython-CI/_build?definitionId=2&_a=summary
49
+ - Python 3.13
50
+ - There are some bugs in mwxlib that remain unfixed.
51
+ - A version of wxpython for PY313 has released on PyPi.
52
+ * You can also download the snapshot from https://wxpython.org/Phoenix/snapshot-builds/,
58
53
 
59
54
 
60
55
  ### Installing
@@ -0,0 +1,28 @@
1
+ mwx/__init__.py,sha256=psabnAMei5VzB2TsB2qBNLrIZMX0LiqjlXCpNGmDejk,668
2
+ mwx/bookshelf.py,sha256=so-xSLq08sMlJBErTxOaDoKUAMa_g1CkIP2pNnff68c,5607
3
+ mwx/controls.py,sha256=LZqee9K8uPxs-Iqcp1zMMNBjFpGPrHbcMaIBuBOL7oo,47647
4
+ mwx/framework.py,sha256=vtufV2jjqdTr2CRhbJYY_NbJMtqft9uKCzZR12dfgk0,75809
5
+ mwx/graphman.py,sha256=1GGBk4kJYRQ7zkvO2rvHxHoINrIfHSB7cabQKWhTyaI,69669
6
+ mwx/images.py,sha256=oxCn0P-emiWujSS2gUgU5TUnr5cPjix2jBcjOBDr24I,48701
7
+ mwx/matplot2.py,sha256=zA56jIdRUdzu-wrmPai1PSOjzqV2Erqw2yFKW-jwdA8,32901
8
+ mwx/matplot2g.py,sha256=xQeHKHAZkLZ2tY-rlTXEIKue1Iw9Vo73l6z_3GSQVCQ,64422
9
+ mwx/matplot2lg.py,sha256=JRWjWnLJUytbSq6wxs4P0gbVUr3xoLSF6Wwqd5V_pJI,27404
10
+ mwx/mgplt.py,sha256=M5rt-H7Uq1OHnlFvMA4a3945UBvppbR9L_mw8NL_YZ0,5602
11
+ mwx/nutshell.py,sha256=pNGLBlVYz6D4LNjosCjXaopcITkQ2-qGVQ6zGmVJJYQ,141850
12
+ mwx/utilus.py,sha256=Yyw8L1f-ikhyd7wtFXYtsOswofWxmB4GAmLOZnhUXeU,37388
13
+ mwx/wxmon.py,sha256=yzWqrbY6LzpfRwQeytYUeqFhFuLVm_XEvrVAL_k0HBQ,12756
14
+ mwx/wxpdb.py,sha256=--TQr-_zs9dWPYV2V4s3Zr4abvN14o5wD8anT9frHUg,18875
15
+ mwx/wxwil.py,sha256=hhyB1lPrF9ixeObxCOKQv0Theu-B-kpJg_yVU3EGSNg,5406
16
+ mwx/wxwit.py,sha256=1hHtMi2YEy2T_LnUpwdmrIdtCuvxMOFyykqnbq6jLP0,7294
17
+ mwx/plugins/__init__.py,sha256=jnJ-Sl9XJ_7BFDslD_r7dsbxsOT57q_IaEriV53XIGY,41
18
+ mwx/plugins/ffmpeg_view.py,sha256=ZKkSLpyuzpVuRbaPib04rChzlwAifNp3pcgxABeqE4k,10693
19
+ mwx/plugins/fft_view.py,sha256=08A_Y73XirV7kXpwf-v0mUA0Hr0MOfdMXv3tvL1hvWA,2789
20
+ mwx/plugins/frame_listview.py,sha256=gowjQ-ARNonMkDSXkQgPKq4U9YBJ-vQ0jK2krBVOdCs,10420
21
+ mwx/plugins/line_profile.py,sha256=zzm6_7lnAnNepLbh07ordp3nRWDFQJtu719ZVjrVf8s,819
22
+ mwx/py/__init__.py,sha256=xykgfOytOwNuvXsfkLoumFZSTN-iBsHOjczYXngjmUE,12
23
+ mwx/py/filling.py,sha256=fumUG1F5M9TL-Dfqni4G85uk7TmvnUunTbdcPDV0vfo,16857
24
+ mwxlib-1.0.0.dist-info/LICENSE,sha256=PGtRKCaTkmUDlBQwpptJAxJtdqxIUtAmdBsaT9nUVkA,1091
25
+ mwxlib-1.0.0.dist-info/METADATA,sha256=IyWzRxDY-vYI_37c6GQ5WgZFAc93d5vfuqaGY8_s3dI,7259
26
+ mwxlib-1.0.0.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
27
+ mwxlib-1.0.0.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
28
+ mwxlib-1.0.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.1.0)
2
+ Generator: setuptools (75.2.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,28 +0,0 @@
1
- mwx/__init__.py,sha256=psabnAMei5VzB2TsB2qBNLrIZMX0LiqjlXCpNGmDejk,668
2
- mwx/bookshelf.py,sha256=so-xSLq08sMlJBErTxOaDoKUAMa_g1CkIP2pNnff68c,5607
3
- mwx/controls.py,sha256=LZqee9K8uPxs-Iqcp1zMMNBjFpGPrHbcMaIBuBOL7oo,47647
4
- mwx/framework.py,sha256=nJ22_22Hk2U8xSbHOszluJdSMDwYsw6XjI3lOiprcJc,75501
5
- mwx/graphman.py,sha256=qX5aHEw4u9iGR8lNpZkXDnGPVMhyAH6NnBapiaUbKZw,70265
6
- mwx/images.py,sha256=_-Eh3xF7Khu42ivkYp97NXIzSNGbjcidqtWjZQFGtqE,47827
7
- mwx/matplot2.py,sha256=zA56jIdRUdzu-wrmPai1PSOjzqV2Erqw2yFKW-jwdA8,32901
8
- mwx/matplot2g.py,sha256=gCXa8X1MEMP7n_mG73h3SkWKuNZOfjVKUTWNRXXK11c,64310
9
- mwx/matplot2lg.py,sha256=JRWjWnLJUytbSq6wxs4P0gbVUr3xoLSF6Wwqd5V_pJI,27404
10
- mwx/mgplt.py,sha256=M5rt-H7Uq1OHnlFvMA4a3945UBvppbR9L_mw8NL_YZ0,5602
11
- mwx/nutshell.py,sha256=zJULq1K8WiOBUncMpXE8HbunqUULa9MUt0hBET5jmgs,141810
12
- mwx/utilus.py,sha256=Yyw8L1f-ikhyd7wtFXYtsOswofWxmB4GAmLOZnhUXeU,37388
13
- mwx/wxmon.py,sha256=yzWqrbY6LzpfRwQeytYUeqFhFuLVm_XEvrVAL_k0HBQ,12756
14
- mwx/wxpdb.py,sha256=lLowkkAgMhPFHAfklD7wZHq0qbSMjRxnBFtSajmVgME,19133
15
- mwx/wxwil.py,sha256=hhyB1lPrF9ixeObxCOKQv0Theu-B-kpJg_yVU3EGSNg,5406
16
- mwx/wxwit.py,sha256=l7uq6NgGBhay-uAE1pQgWziSAGO9QZPJ4EpEBw1P9xU,7357
17
- mwx/plugins/__init__.py,sha256=jnJ-Sl9XJ_7BFDslD_r7dsbxsOT57q_IaEriV53XIGY,41
18
- mwx/plugins/ffmpeg_view.py,sha256=Mmen75o6LyA5QEHB8sCFSPCIPvEaALKzrgomym3fGAU,10721
19
- mwx/plugins/fft_view.py,sha256=xxTDD-_z4l18u4t2ybPB3xAMIslJmJ0gQlTxEqJUhNI,2782
20
- mwx/plugins/frame_listview.py,sha256=yEYPCdLHLSMTJwTv6iYAh3Lo4lJvYfp5BxTLP3FhW9Y,10421
21
- mwx/plugins/line_profile.py,sha256=--9NIc3x5EfRB3L59JvD7rzENQHyiYfu7wWJo6AuMkA,820
22
- mwx/py/__init__.py,sha256=xykgfOytOwNuvXsfkLoumFZSTN-iBsHOjczYXngjmUE,12
23
- mwx/py/filling.py,sha256=fumUG1F5M9TL-Dfqni4G85uk7TmvnUunTbdcPDV0vfo,16857
24
- mwxlib-0.99.9.dist-info/LICENSE,sha256=PGtRKCaTkmUDlBQwpptJAxJtdqxIUtAmdBsaT9nUVkA,1091
25
- mwxlib-0.99.9.dist-info/METADATA,sha256=1-yAjrG-AehfMfbbEyPN3eMtrGErVkNft7OHtTkwSU0,7411
26
- mwxlib-0.99.9.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
27
- mwxlib-0.99.9.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
28
- mwxlib-0.99.9.dist-info/RECORD,,