mwxlib 1.0.3__py3-none-any.whl → 1.0.6__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/controls.py CHANGED
@@ -465,7 +465,13 @@ class Knob(wx.Panel):
465
465
  self.text.BackgroundColour = c
466
466
  self.text.Refresh()
467
467
 
468
- def shift(self, evt, bit):
468
+ def shift_ctrl(self, evt, bit):
469
+ """Called when a key/mouse wheel is pressed/scrolled.
470
+
471
+ In addition to direct key input to the textctrl,
472
+ [up][down][wheelup][wheeldown] keys can be used,
473
+ with modifiers S- 2x, C- 16x, and M- 256x steps.
474
+ """
469
475
  if bit:
470
476
  if evt.ShiftDown(): bit *= 2
471
477
  if evt.ControlDown(): bit *= 16
@@ -485,13 +491,13 @@ class Knob(wx.Panel):
485
491
  evt.Skip()
486
492
 
487
493
  def OnMouseWheel(self, evt): #<wx._core.MouseEvent>
488
- self.shift(evt, 1 if evt.WheelRotation>0 else -1)
494
+ self.shift_ctrl(evt, 1 if evt.WheelRotation>0 else -1)
489
495
  evt.Skip(False)
490
496
 
491
497
  def OnCtrlKeyDown(self, evt): #<wx._core.KeyEvent>
492
498
  key = evt.GetKeyCode()
493
- if key == wx.WXK_LEFT: return self.shift(evt, -1)
494
- if key == wx.WXK_RIGHT: return self.shift(evt, 1)
499
+ if key == wx.WXK_LEFT: return self.shift_ctrl(evt, -1)
500
+ if key == wx.WXK_RIGHT: return self.shift_ctrl(evt, 1)
495
501
 
496
502
  def _focus(c):
497
503
  if isinstance(c, Knob) and c.ctrl.IsEnabled():
@@ -508,8 +514,8 @@ class Knob(wx.Panel):
508
514
 
509
515
  def OnTextKeyDown(self, evt): #<wx._core.KeyEvent>
510
516
  key = evt.GetKeyCode()
511
- if key == wx.WXK_DOWN: return self.shift(evt, -1)
512
- if key == wx.WXK_UP: return self.shift(evt, 1)
517
+ if key == wx.WXK_DOWN: return self.shift_ctrl(evt, -1)
518
+ if key == wx.WXK_UP: return self.shift_ctrl(evt, 1)
513
519
  if key == wx.WXK_ESCAPE:
514
520
  self.__par.reset(self.__par.value, internal_callback=None) # restore value
515
521
  evt.Skip()
mwx/framework.py CHANGED
@@ -1,7 +1,7 @@
1
1
  #! python3
2
2
  """mwxlib framework.
3
3
  """
4
- __version__ = "1.0.3"
4
+ __version__ = "1.0.6"
5
5
  __author__ = "Kazuya O'moto <komoto@jeol.co.jp>"
6
6
 
7
7
  from contextlib import contextmanager
@@ -395,9 +395,9 @@ class CtrlInterface(KeyCtrlInterfaceMixin):
395
395
 
396
396
  def on_hotkey_press(self, evt): #<wx._core.KeyEvent>
397
397
  """Called when a key is pressed."""
398
- if evt.EventObject is not self:
399
- evt.Skip()
400
- return
398
+ ## if evt.EventObject is not self:
399
+ ## evt.Skip()
400
+ ## return
401
401
  key = hotkey(evt)
402
402
  self.__key = regulate_key(key + '-')
403
403
  if self.handler('{} pressed'.format(key), evt) is None:
mwx/matplot2g.py CHANGED
@@ -48,6 +48,8 @@ def _to_buffer(img):
48
48
  if isinstance(img, wx.Image): # image to RGB array; RGB to grayscale
49
49
  w, h = img.GetSize()
50
50
  img = np.frombuffer(img.GetDataBuffer(), dtype='uint8').reshape(h, w, 3)
51
+
52
+ if img.ndim > 2:
51
53
  return cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
52
54
  return img
53
55
 
mwx/nutshell.py CHANGED
@@ -503,9 +503,7 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
503
503
  ## 'C-/ pressed' : (0, ), # cf. C-a home
504
504
  ## 'C-\ pressed' : (0, ), # cf. C-e end
505
505
  'C-; pressed' : (0, _F(self.comment_out_line)),
506
- 'C-S-; pressed' : (0, _F(self.comment_out_line)),
507
506
  'C-: pressed' : (0, _F(self.uncomment_line)),
508
- 'C-S-: pressed' : (0, _F(self.uncomment_line)),
509
507
  'select_line' : (11, self.on_linesel_begin),
510
508
  'select_lines' : (11, self.on_linesel_next),
511
509
  },
@@ -637,10 +635,10 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
637
635
  self.IndicatorSetForeground(10, "red")
638
636
 
639
637
  self.IndicatorSetStyle(11, stc.STC_INDIC_STRAIGHTBOX)
638
+ self.IndicatorSetForeground(11, "yellow")
640
639
  self.IndicatorSetUnder(11, True)
641
- self.IndicatorSetAlpha(11, 60)
642
- self.IndicatorSetOutlineAlpha(11, 60)
643
- self.IndicatorSetForeground(11, "light gray")
640
+ self.IndicatorSetAlpha(11, 0xe8)
641
+ self.IndicatorSetOutlineAlpha(11, 0)
644
642
 
645
643
  self.IndicatorSetStyle(2, stc.STC_INDIC_DOTS)
646
644
  self.IndicatorSetForeground(2, "light gray")
@@ -1849,7 +1847,7 @@ class Buffer(EditorInterface, EditWindow):
1849
1847
  """Fork events to the parent."""
1850
1848
  self.parent.handler(self.handler.current_event, evt)
1851
1849
 
1852
- ## Note: Key events are not propagated from Buffer to EditorBook.
1850
+ ## Note: Mouse events are not propagated from Buffer to EditorBook.
1853
1851
  ## They are explicitly dispatched from buffer.handler to editor.handler.
1854
1852
 
1855
1853
  self.handler.update({ # DNA<Buffer>
@@ -1869,8 +1867,9 @@ class Buffer(EditorInterface, EditWindow):
1869
1867
  '*[LR]win pressed' : (-1, ),
1870
1868
  },
1871
1869
  0 : { # Normal mode
1872
- '* pressed' : (0, skip, dispatch),
1870
+ '* pressed' : (0, skip),
1873
1871
  '* released' : (0, skip, dispatch),
1872
+ '*button* pressed' : (0, skip, dispatch),
1874
1873
  'escape pressed' : (-1, self.on_enter_escmap),
1875
1874
  'C-h pressed' : (0, self.call_helpTip),
1876
1875
  '. pressed' : (2, self.OnEnterDot),
@@ -2211,10 +2210,11 @@ class EditorBook(AuiNotebook, CtrlInterface):
2211
2210
  'buffer_activated' : [ None, dispatch, self.on_activated ],
2212
2211
  'buffer_inactivated' : [ None, dispatch, self.on_inactivated ],
2213
2212
  'buffer_caption_updated' : [ None, dispatch ],
2214
- '*button* pressed' : [ None, dispatch, skip ],
2215
- '*button* released' : [ None, dispatch, skip ],
2216
2213
  },
2217
2214
  0 : { # Normal mode
2215
+ '* pressed' : (0, skip),
2216
+ '* released' : (0, skip, dispatch),
2217
+ '*button* pressed' : (0, skip, dispatch),
2218
2218
  'M-up pressed' : (0, _F(self.previous_buffer)),
2219
2219
  'M-down pressed' : (0, _F(self.next_buffer)),
2220
2220
  },
@@ -2437,10 +2437,14 @@ class EditorBook(AuiNotebook, CtrlInterface):
2437
2437
  self.swap_buffer(buf, lineno)
2438
2438
  return True
2439
2439
  return False
2440
+ except FileNotFoundError:
2441
+ self.post_message(f"New file: {filename!r}.")
2442
+ self.delete_buffer(buf)
2443
+ return False
2440
2444
  except Exception as e:
2441
2445
  self.post_message(f"Failed to load {filename!r}.", e)
2442
2446
  self.delete_buffer(buf)
2443
- return False
2447
+ raise
2444
2448
 
2445
2449
  def find_file(self, filename=None):
2446
2450
  """Open the specified file."""
@@ -2453,7 +2457,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
2453
2457
  for fn in dlg.Paths:
2454
2458
  self.find_file(fn)
2455
2459
  return
2456
- if not self.load_file(filename):
2460
+ if self.load_file(filename) == False:
2457
2461
  buf = self.create_buffer(filename)
2458
2462
  buf._Buffer__mtime = 0 # => need_buffer_save
2459
2463
  self.swap_buffer(buf)
@@ -2815,8 +2819,6 @@ class Nautilus(EditorInterface, Shell):
2815
2819
  'shell_modified' : [ None, dispatch ],
2816
2820
  'shell_activated' : [ None, dispatch, self.on_activated ],
2817
2821
  'shell_inactivated' : [ None, dispatch, self.on_inactivated ],
2818
- '*button* pressed' : [ None, dispatch, skip ],
2819
- '*button* released' : [ None, dispatch, skip ],
2820
2822
  },
2821
2823
  -1 : { # original action of the wx.py.shell
2822
2824
  '* pressed' : (0, skip, self.on_exit_escmap),
@@ -2833,7 +2835,8 @@ class Nautilus(EditorInterface, Shell):
2833
2835
  },
2834
2836
  0 : { # Normal mode
2835
2837
  '* pressed' : (0, skip),
2836
- '* released' : (0, skip),
2838
+ '* released' : (0, skip, dispatch),
2839
+ '*button* pressed' : (0, skip, dispatch),
2837
2840
  'escape pressed' : (-1, self.on_enter_escmap),
2838
2841
  'space pressed' : (0, self.OnSpace),
2839
2842
  '*backspace pressed' : (0, self.OnBackspace),
@@ -109,8 +109,8 @@ class Plugin(Layer):
109
109
  self.snp = Button(self, handler=self.snapshot, icon='clip')
110
110
  self.exp = Button(self, handler=self.export, icon='save')
111
111
 
112
- self.rw = Button(self, handler=lambda v: self.seekdelta(-100), icon='|<-')
113
- self.fw = Button(self, handler=lambda v: self.seekdelta(+100), icon='->|')
112
+ self.rw = Button(self, handler=lambda v: self.seekto(-100), icon='|<-')
113
+ self.fw = Button(self, handler=lambda v: self.seekto(+100), icon='->|')
114
114
 
115
115
  self.layout((self.mc,), expand=2)
116
116
  self.layout((self.ss, self.to, self.rw, self.fw,
@@ -130,14 +130,24 @@ class Plugin(Layer):
130
130
  self.parent.handler.bind("unknown_format", self.load_media)
131
131
 
132
132
  self.handler.update({ # DNA<ffmpeg_viewer>
133
- 0 : {
134
- 'play' : (1, ),
135
- 'space pressed' : (1, _F(self.mc.Play)),
133
+ 0 : { # MEDIASTATE_STOPPED
134
+ 'play' : (2, ),
135
+ 'space pressed' : (2, _F(self.mc.Play)),
136
+ 'left pressed' : (0, _F(self.seekd, -1000)),
137
+ 'right pressed' : (0, _F(self.seekd, 1000)),
136
138
  },
137
- 1 : {
139
+ 1 : { # MEDIASTATE_PAUSED
138
140
  'stop' : (0, ),
139
- 'pause' : (0, ),
141
+ 'space pressed' : (2, _F(self.mc.Play)),
142
+ 'left pressed' : (1, _F(self.seekd, -1000)),
143
+ 'right pressed' : (1, _F(self.seekd, 1000)),
144
+ },
145
+ 2 : { # MEDIASTATE_PLAYING
146
+ 'stop' : (0, ),
147
+ 'pause' : (1, ),
140
148
  'space pressed' : (1, _F(self.mc.Pause)),
149
+ 'left pressed' : (2, _F(self.seekd, -1000)),
150
+ 'right pressed' : (2, _F(self.seekd, 1000)),
141
151
  },
142
152
  })
143
153
 
@@ -145,10 +155,8 @@ class Plugin(Layer):
145
155
  self.mc.Bind(wx.media.EVT_MEDIA_PLAY, partial(self.handler, 'play'))
146
156
  self.mc.Bind(wx.media.EVT_MEDIA_STOP, partial(self.handler, 'stop'))
147
157
 
148
- ## self.mc.Bind(wx.EVT_KEY_DOWN, self.on_hotkey_down)
149
- ## self.mc.Bind(wx.EVT_KEY_UP, self.on_hotkey_up)
150
- self.mc.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
151
- self.mc.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
158
+ self.mc.Bind(wx.EVT_KEY_DOWN, self.on_hotkey_down)
159
+ self.mc.Bind(wx.EVT_KEY_UP, self.on_hotkey_up)
152
160
 
153
161
  self.Bind(wx.EVT_SHOW, self.OnShow)
154
162
 
@@ -158,14 +166,6 @@ class Plugin(Layer):
158
166
  finally:
159
167
  return Layer.Destroy(self)
160
168
 
161
- def OnKeyDown(self, evt):
162
- if self.handler('{} pressed'.format(hotkey(evt)), evt) is None:
163
- evt.Skip()
164
-
165
- def OnKeyUp(self, evt):
166
- if self.handler('{} released'.format(hotkey(evt)), evt) is None:
167
- evt.Skip()
168
-
169
169
  def OnShow(self, evt):
170
170
  if not evt.IsShown():
171
171
  if self.mc:
@@ -250,18 +250,24 @@ class Plugin(Layer):
250
250
  crop = "{}:{}:0:0".format(*self.video_size)
251
251
  self.crop.Value = crop
252
252
 
253
- def seekdelta(self, offset):
254
- """Seek relative position [ms]."""
255
- if wx.GetKeyState(wx.WXK_SHIFT):
256
- offset /= 10
253
+ def seekto(self, offset):
254
+ """Seek position with offset [ms] from the `to` position."""
257
255
  try:
258
256
  t = self.to.value + offset/1000
259
- except Exception as e:
260
- print(e)
261
- else:
262
- if self._path and 0 <= t < self.video_dur:
257
+ if 0 <= t < self.video_dur:
263
258
  self.to.value = round(t, 3)
264
- self.set_offset(self.to) # => seek
259
+ self.set_offset(self.to)
260
+ except AttributeError:
261
+ pass
262
+
263
+ def seekd(self, offset):
264
+ """Seek position with offset [ms] from the current position."""
265
+ try:
266
+ t = self.mc.Tell() + offset
267
+ if 0 <= t < self.video_dur * 1000:
268
+ self.mc.Seek(self.DELTA + t)
269
+ except AttributeError:
270
+ pass
265
271
 
266
272
  def snapshot(self):
267
273
  """Create a snapshot of the current frame.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mwxlib
3
- Version: 1.0.3
3
+ Version: 1.0.6
4
4
  Summary: A wrapper of matplotlib and wxPython (phoenix)
5
5
  Home-page: https://github.com/komoto48g/mwxlib
6
6
  Author: Kazuya O'moto
@@ -1,28 +1,28 @@
1
1
  mwx/__init__.py,sha256=psabnAMei5VzB2TsB2qBNLrIZMX0LiqjlXCpNGmDejk,668
2
2
  mwx/bookshelf.py,sha256=so-xSLq08sMlJBErTxOaDoKUAMa_g1CkIP2pNnff68c,5607
3
- mwx/controls.py,sha256=fL_DdAjW9fIRFzlZYP296vo76e7d9cgLp4_fcWariUY,47654
4
- mwx/framework.py,sha256=PFUIaqPkHe-5ozh0Otg8EM8zcjHPnoijdXvSJekMLRY,75809
3
+ mwx/controls.py,sha256=iXNTk4ge6sHStenjxC7bFKgQHvqxMwfb82IbgiDmtEk,47944
4
+ mwx/framework.py,sha256=Y0YBqjcbfPMTqal_-vN9LPAXaHVNTYbxQ1UpMbVAb_8,75818
5
5
  mwx/graphman.py,sha256=mDnhy3jAzZCo8_p6ZcA-NDPMuOyW_R2r_fuxUIAM7D8,69669
6
6
  mwx/images.py,sha256=oxCn0P-emiWujSS2gUgU5TUnr5cPjix2jBcjOBDr24I,48701
7
7
  mwx/matplot2.py,sha256=zA56jIdRUdzu-wrmPai1PSOjzqV2Erqw2yFKW-jwdA8,32901
8
- mwx/matplot2g.py,sha256=diwWNxzyy-c8KBDaolHaMqWdFXSYhEumgwXIZ9wAEYk,64467
8
+ mwx/matplot2g.py,sha256=4G5uZJZzATEC3QEVZ4pGHetEDfu5NJNUFyeAaQScK5s,64495
9
9
  mwx/matplot2lg.py,sha256=JRWjWnLJUytbSq6wxs4P0gbVUr3xoLSF6Wwqd5V_pJI,27404
10
10
  mwx/mgplt.py,sha256=M5rt-H7Uq1OHnlFvMA4a3945UBvppbR9L_mw8NL_YZ0,5602
11
- mwx/nutshell.py,sha256=6JC855mDnZ8juWDkQ6DqXaiCJB88GJ4wgqH8VqYfSnM,142028
11
+ mwx/nutshell.py,sha256=9QeJXQluEmZSB0B8rGSH9SU_WvjCymmDdU0DKd3fkko,142076
12
12
  mwx/utilus.py,sha256=Yyw8L1f-ikhyd7wtFXYtsOswofWxmB4GAmLOZnhUXeU,37388
13
13
  mwx/wxmon.py,sha256=yzWqrbY6LzpfRwQeytYUeqFhFuLVm_XEvrVAL_k0HBQ,12756
14
14
  mwx/wxpdb.py,sha256=--TQr-_zs9dWPYV2V4s3Zr4abvN14o5wD8anT9frHUg,18875
15
15
  mwx/wxwil.py,sha256=hhyB1lPrF9ixeObxCOKQv0Theu-B-kpJg_yVU3EGSNg,5406
16
16
  mwx/wxwit.py,sha256=1hHtMi2YEy2T_LnUpwdmrIdtCuvxMOFyykqnbq6jLP0,7294
17
17
  mwx/plugins/__init__.py,sha256=jnJ-Sl9XJ_7BFDslD_r7dsbxsOT57q_IaEriV53XIGY,41
18
- mwx/plugins/ffmpeg_view.py,sha256=ZKkSLpyuzpVuRbaPib04rChzlwAifNp3pcgxABeqE4k,10693
18
+ mwx/plugins/ffmpeg_view.py,sha256=Yp1BMeNfkTTPwykvWW1_h4wrvhBSeBUdAvKhnMQIa6g,11102
19
19
  mwx/plugins/fft_view.py,sha256=08A_Y73XirV7kXpwf-v0mUA0Hr0MOfdMXv3tvL1hvWA,2789
20
20
  mwx/plugins/frame_listview.py,sha256=gowjQ-ARNonMkDSXkQgPKq4U9YBJ-vQ0jK2krBVOdCs,10420
21
21
  mwx/plugins/line_profile.py,sha256=zzm6_7lnAnNepLbh07ordp3nRWDFQJtu719ZVjrVf8s,819
22
22
  mwx/py/__init__.py,sha256=xykgfOytOwNuvXsfkLoumFZSTN-iBsHOjczYXngjmUE,12
23
23
  mwx/py/filling.py,sha256=fumUG1F5M9TL-Dfqni4G85uk7TmvnUunTbdcPDV0vfo,16857
24
- mwxlib-1.0.3.dist-info/LICENSE,sha256=PGtRKCaTkmUDlBQwpptJAxJtdqxIUtAmdBsaT9nUVkA,1091
25
- mwxlib-1.0.3.dist-info/METADATA,sha256=LnXTIWenG879NSl5xuUgY8rJMXF8B589tXumD0VUzho,7259
26
- mwxlib-1.0.3.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
27
- mwxlib-1.0.3.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
28
- mwxlib-1.0.3.dist-info/RECORD,,
24
+ mwxlib-1.0.6.dist-info/LICENSE,sha256=PGtRKCaTkmUDlBQwpptJAxJtdqxIUtAmdBsaT9nUVkA,1091
25
+ mwxlib-1.0.6.dist-info/METADATA,sha256=p5q3rC09GOoq4pW_UWNKP7Z1SvrX24kKCy-I19tKmts,7259
26
+ mwxlib-1.0.6.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
27
+ mwxlib-1.0.6.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
28
+ mwxlib-1.0.6.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.2.0)
2
+ Generator: setuptools (75.3.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5