Skip to content

Commit

Permalink
Use ErrorControlMixin to handle set/remove errors on basically all co…
Browse files Browse the repository at this point in the history
…ntrols
  • Loading branch information
emersonrp committed Jun 7, 2024
1 parent 01ccd77 commit 32d5ef9
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 63 deletions.
18 changes: 10 additions & 8 deletions Page/CustomBinds.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,17 +147,19 @@ def SetBindPaneLabel(self, evt, bindpane = None, new = False):
if new:
bindpane.Destroy()

if bindpane.IsCollapsed():
bindpane.Expand()
bindpane.Collapse()
else:
bindpane.Collapse()
bindpane.Expand()
if bindpane:
if bindpane.IsCollapsed():
bindpane.Expand()
bindpane.Collapse()
else:
bindpane.Collapse()
bindpane.Expand()
except Exception as e:
raise e
finally:
bindpane.Parent.Layout()
bindpane.Thaw()
if bindpane:
bindpane.Parent.Layout()
bindpane.Thaw()

dlg.Destroy()

Expand Down
6 changes: 3 additions & 3 deletions UI/ComplexBindPane.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,10 @@ def checkIfWellFormed(self):
isWellFormed = False

bk = self.Ctrls[self.MakeCtlName('BindKey')]
if bk.Key:
bk.SetError(False)
if not bk.Key:
bk.AddError('undef', 'The keybind has not been selected')
else:
bk.SetError(True)
bk.RemoveError('undef')
isWellFormed = False

return isWellFormed
Expand Down
52 changes: 26 additions & 26 deletions UI/ControlGroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from wx.adv import BitmapComboBox
import wx.lib.stattext as ST

from UI.ErrorControls import ErrorControlMixin
from Page import Page
import UI
from UI.KeySelectDialog import bcKeyButton
Expand Down Expand Up @@ -153,55 +154,54 @@ def OnCBLabelClick(self, evt):
wx.PostEvent(cblabel.control, fakeevt)
evt.Skip()

### Deep magic for linting / pytight / mypy
class CGControlProtocol(Protocol):
Enable : Callable
GetContainingSizer : Callable
CtlLabel : ST.GenStaticText | wx.StaticText | None
Page : Page | None
Data : Any

# Mixin to enable/show controls' labels when they are enabled/shown
class CGControlMixin:
def __init__(self: CGControlProtocol, *args, **kwargs):
GetContainingSizer : Callable
SetBackgroundColour : Callable
SetOwnBackgroundColour : Callable
CtlLabel : ST.GenStaticText | wx.StaticText | None
Page : Page # pyright: ignore
Data : Any

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.CtlLabel : ST.GenStaticText | wx.StaticText | None = None
self.Page = None
self.Data = None

def Enable(self: CGControlProtocol, enable = True):
super().Enable(enable)
def Enable(self, enable = True):
super().Enable(enable) # pyright: ignore
if self.CtlLabel: self.CtlLabel.Enable(enable)

def Show(self: CGControlProtocol, show = True):
def Show(self, show = True):
self.GetContainingSizer().Show(self, show = show)
self.Enable(show)
if self.CtlLabel:
self.GetContainingSizer().Show(self.CtlLabel, show = show)
self.Enable(show)
self.CtlLabel.Enable(show)
if self.Page: self.Page.Layout()

def SetToolTip(self, tooltip):
super().SetToolTip(tooltip) # pyright: ignore
if self.CtlLabel:
self.CtlLabel.SetToolTip(tooltip)

# Miniclasses to use the above mixin
class cgbcKeyButton (CGControlMixin, bcKeyButton) : pass
class cgComboBox (CGControlMixin, wx.ComboBox) : pass
class cgBMComboBox (CGControlMixin, BitmapComboBox) : pass
class cgTextCtrl (CGControlMixin, wx.TextCtrl) : pass
class cgChoice (CGControlMixin, wx.Choice) :
# Miniclasses to use mixins
class cgbcKeyButton (CGControlMixin, bcKeyButton) : pass
class cgComboBox (CGControlMixin, ErrorControlMixin, wx.ComboBox) : pass
class cgBMComboBox (CGControlMixin, ErrorControlMixin, BitmapComboBox) : pass
class cgTextCtrl (CGControlMixin, ErrorControlMixin, wx.TextCtrl) : pass
class cgStaticText (CGControlMixin, ErrorControlMixin, wx.StaticText) : pass
class cgCheckBox (CGControlMixin, ErrorControlMixin, wx.CheckBox) : pass
class cgSpinCtrl (CGControlMixin, ErrorControlMixin, wx.SpinCtrl) : pass
class cgSpinCtrlDouble (CGControlMixin, ErrorControlMixin, wx.SpinCtrlDouble) : pass
class cgDirPickerCtrl (CGControlMixin, ErrorControlMixin, wx.DirPickerCtrl) : pass
class cgColourPickerCtrl(CGControlMixin, ErrorControlMixin, wx.ColourPickerCtrl) : pass
class cgChoice (CGControlMixin, ErrorControlMixin, wx.Choice) :
def ShowEntryIf(self, entry: str, condition: bool):
idx = self.FindString(entry)
exists = idx != wx.NOT_FOUND
if condition:
if not exists: self.Append(entry)
else:
if exists: self.Delete(idx)

class cgStaticText (CGControlMixin, wx.StaticText) : pass
class cgCheckBox (CGControlMixin, wx.CheckBox) : pass
class cgSpinCtrl (CGControlMixin, wx.SpinCtrl) : pass
class cgSpinCtrlDouble (CGControlMixin, wx.SpinCtrlDouble) : pass
class cgDirPickerCtrl (CGControlMixin, wx.DirPickerCtrl) : pass
class cgColourPickerCtrl(CGControlMixin, wx.ColourPickerCtrl) : pass
32 changes: 32 additions & 0 deletions UI/ErrorControls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from typing import Callable
import wx
# Mixin to handle setting/showing errors and tooltips
class ErrorControlMixin:
Errors : dict
SetBackgroundColour : Callable
SetOwnBackgroundColour : Callable
SetToolTip : Callable

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.Errors = {}

def AddError(self, errname, tooltip = None):
self.SetBackgroundColour((255,200,200))
self.Errors[errname] = tooltip
self.SetErrorToolTip()

def RemoveError(self, errname):
self.Errors.pop(errname, None)
if not self.Errors:
self.SetOwnBackgroundColour(wx.NullColour)
self.SetErrorToolTip()

def SetErrorToolTip(self):
tipstrings = self.Errors.values()
# if we have any non-empty string, set the tooltip
for tip in tipstrings:
if tip:
self.SetToolTip("\n".join(tipstrings))
return
self.SetToolTip('')
33 changes: 9 additions & 24 deletions UI/KeySelectDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import wx.lib.newevent

import UI
from UI.ErrorControls import ErrorControlMixin
from bcController import bcController

KeyChanged, EVT_KEY_CHANGED = wx.lib.newevent.NewEvent()
Expand Down Expand Up @@ -400,15 +401,15 @@ def SetKeymap(self):

from BindFile import KeyBind
from Page import Page
class bcKeyButton(wx.Button):
class bcKeyButton(ErrorControlMixin, wx.Button):

def __init__(self, parent, id, init = {}):
wx.Button.__init__(self, parent, id)
self.CtlName : str = init.get('CtlName', None)
self.CtlName : str = init.get('CtlName', None)
self.CtlLabel : ST.GenStaticText | wx.StaticText | None = init.get('CtlLabel', None)
self.Key : str = init.get('Key', '')
self.Page : Page = parent
self.HasError : bool = False
self.Key : str = init.get('Key', '')
self.Page : Page = parent
self.Errors : dict = {}

self.SetLabel(self.Key)

Expand Down Expand Up @@ -444,30 +445,14 @@ def CheckConflicts(self, newbinding = None):
Profile = wx.App.Get().Profile
if Profile:
conflicts = Profile.CheckConflict(newbinding or self.Key, self.CtlName)
if conflicts:
self.SetError(True, conflicts = conflicts)
else:
if not self.HasError: # don't clear errors if we already had one
self.SetError(False)
return conflicts

# TODO - maybe? move this into UI/ControlGroup's mixin so we can 'seterror' on any control.
# Will need to dig out / generalize the 'conflicts' notion
def SetError(self, iserror = True, conflicts = None):
if iserror:
self.SetBackgroundColour((255,200,200))
if conflicts:
conflictStrings = []
for conflict in conflicts:
conflictStrings.append(f'This key conflicts with \"{conflict["ctrl"]}\" on the \"{conflict["page"]}\" tab.')
self.SetToolTip('\n'.join(conflictStrings))
self.AddError('conflict', '\n'.join(conflictStrings))
else:
self.SetToolTip("This key must be defined to complete your bind.")
self.HasError = True
else:
self.SetOwnBackgroundColour(wx.NullColour)
self.SetToolTip('')
self.HasError = False
self.RemoveError('conflict')
return conflicts

def KeySelectEventHandler(self, evt):
button = evt.EventObject
Expand Down
4 changes: 2 additions & 2 deletions UI/SimpleBindPane.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ def checkIfWellFormed(self):

bk = self.Ctrls[self.MakeCtlName('BindKey')]
if bk.Key:
bk.SetError(False)
bk.RemoveError('undef')
else:
bk.SetError(True)
bk.AddError('undef', 'The keybind has not been selected')
isWellFormed = False

return isWellFormed
Expand Down

0 comments on commit 32d5ef9

Please sign in to comment.