From 1f0290bf1a9cb91bd17d1b70e1f518f03cb5ca73 Mon Sep 17 00:00:00 2001 From: volconst <20997907+volconst@users.noreply.github.com> Date: Thu, 27 Aug 2020 12:46:56 +0000 Subject: [PATCH] MS Windows Fix: toolbar shortcuts, blank jog, jog tab-out Connect, Print, Pause shortcuts worked only when toolbar is focused 'P' shortcut is specially coded to invoke either Print or Pause even when Pause is labeled Resume. Fix blank Jog control when focused Fix: TAB cycles inside Jog without exit to next control --- printrun/gui/toolbar.py | 3 ++- printrun/gui/xybuttons.py | 10 +++++++--- printrun/gui/zbuttons.py | 4 +++- printrun/pronterface.py | 42 ++++++++++++++++++++++++++++++++------- 4 files changed, 47 insertions(+), 12 deletions(-) diff --git a/printrun/gui/toolbar.py b/printrun/gui/toolbar.py index 37a273dd3..f29bc9394 100644 --- a/printrun/gui/toolbar.py +++ b/printrun/gui/toolbar.py @@ -52,7 +52,8 @@ def MainToolbar(root, parentpanel = None, use_wrapsizer = False): self.Add(root.baud) if not hasattr(root, "connectbtn"): - root.connectbtn = make_autosize_button(parentpanel, _("Connect"), root.connect, _("Connect to the printer")) + root.connectbtn_cb_var = root.connect + root.connectbtn = make_autosize_button(parentpanel, _("&Connect"), root.connectbtn_cb, _("Connect to the printer")) root.statefulControls.append(root.connectbtn) else: root.connectbtn.Reparent(parentpanel) diff --git a/printrun/gui/xybuttons.py b/printrun/gui/xybuttons.py index 5bb0a7492..05748860b 100644 --- a/printrun/gui/xybuttons.py +++ b/printrun/gui/xybuttons.py @@ -42,7 +42,7 @@ def drawFocusRect(self, dc): pen = wx.Pen(wx.BLACK, 1, wx.PENSTYLE_USER_DASH) pen.SetDashes(DASHES) dc.Pen = pen - dc.Brush = wx.NullBrush + dc.Brush = wx.Brush(wx.TRANSPARENT_BRUSH) dc.DrawRectangle(self.ClientRect) class XYButtons(FocusCanvas): @@ -333,8 +333,12 @@ def OnKey(self, evt): keypad = self.cycleKeypadIndex(not evt.ShiftDown()) self.setKeypadIndex(keypad) if keypad == -1: - # exit widget after largest step - evt.Skip() + # exit widget after largest step + # evt.Skip() + # On MS Windows if tab event is delivered, + # it is not handled + self.Navigate(not evt.ShiftDown()) + return elif key == wx.WXK_ESCAPE: self.setKeypadIndex(-1) elif key == wx.WXK_UP: diff --git a/printrun/gui/zbuttons.py b/printrun/gui/zbuttons.py index b9d020e8f..223943fb5 100644 --- a/printrun/gui/zbuttons.py +++ b/printrun/gui/zbuttons.py @@ -47,7 +47,9 @@ def __init__(self, parent, moveCallback = None, bgcolor = "#FFFFFF", ID=-1): self.bgcolor.Set(bgcolor) self.bgcolormask = wx.Colour(self.bgcolor.Red(), self.bgcolor.Green(), self.bgcolor.Blue(), 128) - super().__init__(parent, ID, size=self.bg_bmp.GetSize()) + # On MS Windows super(style=WANTS_CHARS) prevents tab cycling + # pass empty style explicitly + super().__init__(parent, ID, size=self.bg_bmp.GetSize(), style=0) # Set up mouse and keyboard event capture self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) diff --git a/printrun/pronterface.py b/printrun/pronterface.py index edc47c86a..8f3c89b86 100644 --- a/printrun/pronterface.py +++ b/printrun/pronterface.py @@ -346,6 +346,27 @@ def on_key(self, event): #ignore Alt+(S, H), so it can open Settings, Help menu if widget and (ch not in 'SH' or not event.AltDown()): widget.SetFocus() + return + # On MSWindows button mnemonics are processed only if the + # focus is in the parent panel + if event.AltDown() and ch < 'Z': + in_toolbar = self.toolbarsizer.GetItem(event.EventObject) + candidates = (self.connectbtn, self.connectbtn_cb_var), \ + (self.pausebtn, self.pause), \ + (self.printbtn, self.printfile) + for ctl, cb in candidates: + match = ('&' + ch) in ctl.Label.upper() + handled = in_toolbar and match + if handled: + break + # react to 'P' even for 'Restrart', 'Resume' + # print('match', match, 'handled', handled, ctl.Label, ctl.Enabled) + if (match or ch == 'P' and ctl != self.connectbtn) and ctl.Enabled: + # print('call', ch, cb) + cb() + # react to only 1 of 'P' buttons, prefer Resume + return + event.Skip() def closewin(self, e): @@ -1142,6 +1163,12 @@ def lock(self, event = None, force = None): # Printer connection handling # -------------------------------------------------------------- + def connectbtn_cb(self, event): + # Implement toggle behavior with a single Bind + # and switched variable, so we have reference to + # the actual callback to use in on_key + self.connectbtn_cb_var() + def connect(self, event = None): self.log(_("Connecting...")) port = None @@ -1190,11 +1217,12 @@ def disconnect(self, event = None): self.status_thread.join() self.status_thread = None - wx.CallAfter(self.connectbtn.SetLabel, _("&Connect")) - wx.CallAfter(self.connectbtn.SetToolTip, wx.ToolTip(_("Connect to the printer"))) - wx.CallAfter(self.connectbtn.Bind, wx.EVT_BUTTON, self.connect) - - wx.CallAfter(self.gui_set_disconnected) + def toggle(): + self.connectbtn.SetLabel(_("&Connect")) + self.connectbtn.SetToolTip(wx.ToolTip(_("Connect to the printer"))) + self.connectbtn_cb_var = self.connect + self.gui_set_disconnected() + wx.CallAfter(toggle) if self.paused: self.p.paused = 0 @@ -1234,7 +1262,7 @@ def on_startprint(self): wx.CallAfter(self.printbtn.SetLabel, _("Restart")) wx.CallAfter(self.toolbarsizer.Layout) - def printfile(self, event): + def printfile(self, event=None): self.extra_print_time = 0 if self.paused: self.p.paused = 0 @@ -1700,7 +1728,7 @@ def online_gui(self): """Callback when printer goes online (graphical bits)""" self.connectbtn.SetLabel(_("Dis&connect")) self.connectbtn.SetToolTip(wx.ToolTip("Disconnect from the printer")) - self.connectbtn.Bind(wx.EVT_BUTTON, self.disconnect) + self.connectbtn_cb_var = self.disconnect if hasattr(self, "extrudersel"): self.do_tool(self.extrudersel.GetValue())