From f6dd43c25823150f7ed212130db75a58e0c87649 Mon Sep 17 00:00:00 2001 From: Russell Pickett Date: Sat, 25 Jan 2025 13:09:58 -0500 Subject: [PATCH 1/2] NOT WORKING: Start of refactor of PowerBinder commands into modules --- UI/PowerBinderCommand/AFKCmd.py | 26 + UI/PowerBinderCommand/AttributeMonitorCmd.py | 1800 ++++++++++++++++++ UI/PowerBinderCommand/AutoPowerCmd.py | 1800 ++++++++++++++++++ UI/PowerBinderCommand/BuffDisplayCmd.py | 1800 ++++++++++++++++++ UI/PowerBinderCommand/ChatCmd.py | 1800 ++++++++++++++++++ UI/PowerBinderCommand/ChatGlobalCmd.py | 1800 ++++++++++++++++++ UI/PowerBinderCommand/CostumeChangeCmd.py | 1800 ++++++++++++++++++ UI/PowerBinderCommand/CustomBindCmd.py | 1800 ++++++++++++++++++ UI/PowerBinderCommand/EmoteCmd.py | 1800 ++++++++++++++++++ UI/PowerBinderCommand/GraphicsCmd.py | 1800 ++++++++++++++++++ UI/PowerBinderCommand/LoadBindsDir.py | 1800 ++++++++++++++++++ UI/PowerBinderCommand/MovementCmd.py | 1800 ++++++++++++++++++ UI/PowerBinderCommand/PowerAbortCmd.py | 1800 ++++++++++++++++++ UI/PowerBinderCommand/PowerUnqueueCmd.py | 1800 ++++++++++++++++++ UI/PowerBinderCommand/SGModeCmd.py | 1800 ++++++++++++++++++ UI/PowerBinderCommand/TargetCustomCmd.py | 1800 ++++++++++++++++++ UI/PowerBinderCommand/TargetEnemyCmd.py | 1800 ++++++++++++++++++ UI/PowerBinderCommand/TargetFriendCmd.py | 1800 ++++++++++++++++++ UI/PowerBinderCommand/TeamPetSelectCmd.py | 1800 ++++++++++++++++++ UI/PowerBinderCommand/UnselectCmd.py | 1800 ++++++++++++++++++ UI/PowerBinderCommand/UseInspByNameCmd.py | 1800 ++++++++++++++++++ UI/PowerBinderCommand/UseInspRowColCmd.py | 1800 ++++++++++++++++++ UI/PowerBinderCommand/UsePowerCmd.py | 1800 ++++++++++++++++++ UI/PowerBinderCommand/UsePowerFromTrayCmd.py | 1800 ++++++++++++++++++ UI/PowerBinderCommand/WindowColorCmd.py | 1800 ++++++++++++++++++ UI/PowerBinderCommand/WindowSaveLoadCmd.py | 1800 ++++++++++++++++++ UI/PowerBinderCommand/WindowToggleCmd.py | 1800 ++++++++++++++++++ UI/PowerBinderCommand/__init__.py | 23 + UI/PowerBinderDialog.py | 134 +- 29 files changed, 46898 insertions(+), 85 deletions(-) create mode 100644 UI/PowerBinderCommand/AFKCmd.py create mode 100644 UI/PowerBinderCommand/AttributeMonitorCmd.py create mode 100644 UI/PowerBinderCommand/AutoPowerCmd.py create mode 100644 UI/PowerBinderCommand/BuffDisplayCmd.py create mode 100644 UI/PowerBinderCommand/ChatCmd.py create mode 100644 UI/PowerBinderCommand/ChatGlobalCmd.py create mode 100644 UI/PowerBinderCommand/CostumeChangeCmd.py create mode 100644 UI/PowerBinderCommand/CustomBindCmd.py create mode 100644 UI/PowerBinderCommand/EmoteCmd.py create mode 100644 UI/PowerBinderCommand/GraphicsCmd.py create mode 100644 UI/PowerBinderCommand/LoadBindsDir.py create mode 100644 UI/PowerBinderCommand/MovementCmd.py create mode 100644 UI/PowerBinderCommand/PowerAbortCmd.py create mode 100644 UI/PowerBinderCommand/PowerUnqueueCmd.py create mode 100644 UI/PowerBinderCommand/SGModeCmd.py create mode 100644 UI/PowerBinderCommand/TargetCustomCmd.py create mode 100644 UI/PowerBinderCommand/TargetEnemyCmd.py create mode 100644 UI/PowerBinderCommand/TargetFriendCmd.py create mode 100644 UI/PowerBinderCommand/TeamPetSelectCmd.py create mode 100644 UI/PowerBinderCommand/UnselectCmd.py create mode 100644 UI/PowerBinderCommand/UseInspByNameCmd.py create mode 100644 UI/PowerBinderCommand/UseInspRowColCmd.py create mode 100644 UI/PowerBinderCommand/UsePowerCmd.py create mode 100644 UI/PowerBinderCommand/UsePowerFromTrayCmd.py create mode 100644 UI/PowerBinderCommand/WindowColorCmd.py create mode 100644 UI/PowerBinderCommand/WindowSaveLoadCmd.py create mode 100644 UI/PowerBinderCommand/WindowToggleCmd.py create mode 100644 UI/PowerBinderCommand/__init__.py diff --git a/UI/PowerBinderCommand/AFKCmd.py b/UI/PowerBinderCommand/AFKCmd.py new file mode 100644 index 0000000..158535f --- /dev/null +++ b/UI/PowerBinderCommand/AFKCmd.py @@ -0,0 +1,26 @@ +import wx +from UI.PowerBinderCommand import PowerBinderCommand + +####### Away From Keyboard +class AFKCmd(PowerBinderCommand): + Name = "Away From Keyboard" + Menu = "Social" + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) diff --git a/UI/PowerBinderCommand/AttributeMonitorCmd.py b/UI/PowerBinderCommand/AttributeMonitorCmd.py new file mode 100644 index 0000000..4c02ab7 --- /dev/null +++ b/UI/PowerBinderCommand/AttributeMonitorCmd.py @@ -0,0 +1,1800 @@ +import wx +import re +import UI +import UI.EmotePicker +from UI.ControlGroup import ControlGroup +from UI.PowerPicker import PowerPicker +from Help import HelpButton +import wx.adv +from wx.adv import BitmapComboBox, EditableListBox +from pathlib import PureWindowsPath +import GameData +import Profile +from Icon import GetIcon + +class PowerBinderDialog(wx.Dialog): + def __init__(self, parent, button, init = {}): + wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) + + self.Page = parent.Page + self.EditDialog = PowerBinderEditDialog(self) + self.Button = button + self.AddStepMenu = self.makeAddStepMenu() + + sizer = wx.BoxSizer(wx.VERTICAL); + self.mainSizer = sizer + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) + # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) + # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) + #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) + AddStepButton = wx.Button(self, -1, 'Add Step') + AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) + AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) + choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) + choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) + sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) + + rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) + + self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) + self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) + self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) + rearrangeCtrl.Add(self.RearrangeList, 1) + + rearrangeButtons = wx.BoxSizer(wx.VERTICAL) + self.DelButton = wx.Button(self, -1, "Delete") + self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) + self.EditButton = wx.Button(self, -1, "Edit") + self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) + self.EditButton.Disable() + upButton = wx.Button(self, -1, "\u25B2") + upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) + downButton = wx.Button(self, -1, "\u25BC") + downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) + rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) + rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) + + sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.BindStringDisplay = wx.TextCtrl(self, -1) + self.BindStringDisplay.Disable() + choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, + wx.ALIGN_CENTER_VERTICAL) + choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) + + sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) + + sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) + + # need to dig around and get the OK button since we show this dialog modelessly now. + okButton = self.FindWindow(self.GetAffirmativeId()) + okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) + + # Wrap everything in a vbox to add some padding + vbox = wx.BoxSizer(wx.VERTICAL); + vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); + + self.SetSizerAndFit(vbox); + self.Layout() + self.Fit() + self.SetFocus() + + # if we are loading from profile, ie, have "init", build the list from it + if init: self.LoadFromData(init) + + def LoadFromData(self, init): + for item in init: + for type, data in item.items(): + commandClass = commandClasses.get(type, None) + if not commandClass: + commandClass = deprecatedCommandClasses.get(type, None) + if not commandClass: + wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") + continue + newCommand = commandClass(self.EditDialog, data) + index = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.SetClientData(index, newCommand) + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) + self.EditDialog.mainSizer.Hide(newCommand.UI) + self.UpdateBindStringDisplay() + + def SaveToData(self): + data = [] + index = 0 + for _ in self.RearrangeList.GetItems(): + # check whether we have an object already attached to this choice + cmdObject = self.RearrangeList.GetClientData(index) + commandClassName = commandRevClasses[type(cmdObject)] + data.append({commandClassName: cmdObject.Serialize()}) + index = index + 1 + return data + + def OnAddStepButton(self, evt): + button = evt.EventObject + if not self.AddStepMenu: + self.AddStepMenu = self.makeAddStepMenu() + button.PopupMenu(self.AddStepMenu) + + + def OnOKButton(self, _): + if self.Button.tgtTxtCtrl: + bindString = self.MakeBindString() + if bindString != self.Button.tgtTxtCtrl.GetValue(): + self.Button.tgtTxtCtrl.SetValue(bindString) + wx.App.Get().Main.Profile.SetModified() + self.Close() + + def OnRearrangeDelete(self, _): + current = self.RearrangeList.GetSelection() + if current == wx.NOT_FOUND: return + + self.RearrangeList.Delete(current) + self.UpdateBindStringDisplay() + + def OnRearrangeUp(self, _): + self.RearrangeList.MoveCurrentUp() + self.UpdateBindStringDisplay() + + def OnRearrangeDown(self, _): + self.RearrangeList.MoveCurrentDown() + self.UpdateBindStringDisplay() + + def OnRearrangeEdit(self, _): + index = self.RearrangeList.GetSelection() + + # check whether we have an object already attached to this choice + cmdObject = None + try: + cmdObject = self.RearrangeList.GetClientData(index) + except Exception: + pass + + if cmdObject: + self.ShowEditDialogFor(cmdObject) + self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) + else: + print("cmdObject was None") + self.UpdateBindStringDisplay() + + # OnAddStepMenu creates a new step and adds it to the rearrangelist + def OnAddStepMenu(self, evt): + menuitem = self.AddStepMenu.FindItemById(evt.GetId()) + chosenName = menuitem.GetItemLabel() + + # make a new command object, attached to the parent dialog + newCommandClass = commandClasses[chosenName] + newCommand = newCommandClass(self.EditDialog) + + # show the edit dialog if this command needs it + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) + if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): + self.EditDialog.mainSizer.Remove(newCommand.UI) + return + + newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.Select(newBindIndex) + self.RearrangeList.SetClientData(newBindIndex, newCommand) + + self.OnListSelect() + self.UpdateBindStringDisplay() + + def OnListSelect(self, _ = None): + selected = self.RearrangeList.GetSelection() + + if selected != wx.NOT_FOUND: + selCommand = self.RearrangeList.GetClientData(selected) + if selCommand.UI: + self.EditButton.Enable() + else: + self.EditButton.Disable() + + def UpdateBindStringDisplay(self): + self.BindStringDisplay.SetValue(self.MakeBindString()) + self.BindStringDisplay.SetToolTip(self.MakeBindString()) + + def MakeBindString(self): + cmdBindStrings = [] + for index in range(self.RearrangeList.GetCount()): + c = self.RearrangeList.GetClientData(index) + if c: cmdBindStrings.append(c.MakeBindString()) + + bindstring = ('$$'.join(cmdBindStrings)) + return bindstring + + def ShowEditDialogFor(self, command): + if not command.UI: return + + self.EditDialog.mainSizer.Show(command.UI) + + self.EditDialog.Layout() + self.EditDialog.Fit() + + self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') + returnval = self.EditDialog.ShowModal() + + self.EditDialog.mainSizer.Hide(command.UI) + + return returnval + + def makeAddStepMenu(self): + + stepMenu = wx.Menu() + + for subname in menuStructure: + submenu = wx.Menu() + stepMenu.AppendSubMenu(submenu, subname) + for classname in menuStructure[subname]: + submenu.Append(wx.ID_ANY, classname) + + stepMenu.Append(wx.ID_ANY, 'Custom Bind') + + return stepMenu + +class PowerBinderButton(wx.BitmapButton): + + def __init__(self, parent, tgtTxtCtrl, init = {}): + wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) + self.Init = init + self.Dialog = None + self.DialogParent = parent + + self.tgtTxtCtrl = tgtTxtCtrl + self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) + self.SetToolTip("Launch PowerBinder") + + def PowerBinderEventHandler(self, _): + self.PowerBinderDialog().Show() + + def LoadFromData(self, data): + self.PowerBinderDialog().LoadFromData(data) + + def SaveToData(self): + return self.PowerBinderDialog().SaveToData() + + def PowerBinderDialog(self): + if not self.Dialog: + self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) + return self.Dialog + + +class PowerBinderEditDialog(wx.Dialog): + def __init__(self, parent): + wx.Dialog.__init__(self, parent, -1, "Edit Step", + style = wx.DEFAULT_DIALOG_STYLE) + + outerSizer = wx.BoxSizer(wx.VERTICAL) + + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + self.mainSizer.SetMinSize([500, 150]) + + self.Page = parent.Page + + self.mainSizer.Add( + self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), + 0, wx.EXPAND|wx.ALL, 10) + + outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) + + self.SetSizerAndFit(outerSizer) + self.Layout() + self.Fit() + +########### Power Binder Command Objects +class PowerBindCmd(): + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + commandClassName = commandRevClasses[type(self)] + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{commandClassName} - {short_bindstr}" + + +####### Away From Keyboard +class AFKCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) + +####### Attribute Monitor +class AttributeMonitorCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.Groups = {} + self.AttributeTable = { + 'Base' : { + 'Current Hit Points' : 'NT H', + 'Max Hit Points' : 'X H', + 'Current Endurance' : 'T E', + 'Max Endurance' : 'X EN', + 'Regeneration Rate' : 'N RAT', + 'Recovery Rate' : 'Y RA', + 'Endurance Consumption' : 'SU', + 'ToHit Bonus' : 'T B', + 'Accuracy Bonus' : 'CC', + 'Last Hit Chance' : 'T C', + 'Damage Bonus' : 'DA', + 'Healing Bonus' : 'NG B', + 'Recharge Time Bonus' : 'ME B', + 'Endurance Discount' : 'CE DIS', + 'Stealth Radius (PvP)' : 'PVP', + 'Stealth Radius (PvE)' : 'PVE', + 'Perception Radius' : 'RC', + 'Range Bonus' : 'GE B', + 'Threat Level' : 'AT L', + 'Experience to Next Level' : 'XT', + 'Experience Debt' : 'XP', + 'Influence / Infamy' : 'INF', + 'Inherent' : 'NH', + }, + 'Movement Speed' : { + 'Flying Speed' : 'FL', + 'Jumping Speed' : 'PI', + 'Max Jump Height' : 'X J', + 'Run Speed' : 'RU', + }, + 'Damage Resistance' : { + 'Smashing Resistance' : 'G R', + 'Lethal Resistance' : 'L R', + 'Fire Resistance' : 'RE R', + 'Cold Resistance' : 'COLD R', + 'Energy Resistance' : 'DamageType[4]', + 'Negative Energy Resistance' : 'GY R', + 'Psyonic Resistance' : 'NIC R', + 'Toxic Resistance' : 'XIC R', + }, + 'Defense' : { + 'Base Defense' : 'BAS', + 'Ranged Defense' : 'ED', + 'Melee Defense' : 'MEL', + 'AoE Defense' : '2', + 'Smashing Defense' : '3', + 'Lethal Defense' : '4', + 'Fire Defense' : '5', + 'Cold Defense' : '6', + 'Energy Defense' : '7', + 'Negative Energy Defense' : '8', + 'Psionic Defense' : '9', + 'Toxic Defense' : '1', + }, + 'Debuff Resistance' : { + 'Regeneration Resistance' : 'ON R', + 'Recovery Resistance' : 'RY R', + 'To Hit Resistance' : 'IT R', + 'Defense Resistance' : 'NSE RES', + }, + 'Status Effect Protection' : { + 'Hold Protection' : 'D P', + 'Immobilize Protection' : 'LIZE P', + 'Stun Protection' : 'N P', + 'Sleep Protection' : 'P P', + 'Knockback Protection' : 'K P', + 'Confuse Protection' : 'SE P', + 'Terrorize Protection' : 'ZE P', + 'Repel Protection' : 'EL P', + 'Teleport Protection' : 'T P', + }, + 'Status Effect Resistance' : { + 'Hold Resistance' : 'D R', + 'Immobilize Resistance' : 'LIZE R', + 'Stun Resistance' : 'N R', + 'Sleep Resistance' : 'P R', + 'Knockback Resistance' : 'K R', + 'Confuse Resistance' : 'SE R', + 'Terrorize Resistance' : 'ZE R', + 'Placate Resistance' : 'TE R', + 'Taunt Resistance' : 'NT R', + }, + 'Miscellaneous' : { + 'Level Shift' : 'L S', + }, + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.AttributeMenu = wx.Menu() + for group, controls in self.AttributeTable.items(): + submenu = wx.Menu() + self.AttributeMenu.AppendSubMenu(submenu, group) + for cb in controls: + submenu.Append(wx.ID_ANY, cb) + + self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) + + self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) + groupSizer.Add(self.editbox) + + newButton = self.editbox.GetNewButton() + newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) + + return groupSizer + + def MakeBindString(self): + map = {} + bindstrings = [] + for _, controls in self.AttributeTable.items(): + for cb, data in controls.items(): + map[cb] = data + + for string in self.editbox.GetStrings(): + if string: + bindstrings.append(f'monitorattribute {map[string]}') + + return '$$'.join(bindstrings) + + def Serialize(self): + return { + 'attributes' : self.editbox.GetStrings() + } + + def Deserialize(self, init): + self.editbox.SetStrings(init.get('attributes', [])) + + def OnNewButton(self, evt): + evt.GetEventObject().PopupMenu(self.AttributeMenu) + + def OnMenuItem(self, evt): + menuitem = evt.EventObject.FindItemById(evt.GetId()) + existingstrings = self.editbox.GetStrings() + existingstrings.append(menuitem.GetItemLabel()) + self.editbox.SetStrings(existingstrings) + +####### Auto Power +class AutoPowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) + autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.autoPowerName = PowerPicker(dialog) + autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) + + return autoPowerSizer + + def MakeBindString(self): + return f"powexecauto {self.autoPowerName.GetLabel()}" + + def Serialize(self): + return { + 'pname' : self.autoPowerName.GetLabel(), + 'picon' : self.autoPowerName.IconFilename + } + + def Deserialize(self, init): + if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) + +####### Buff Display Command +class BuffDisplayCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.buffDisplayMap = { + 'Status Window' : { + 'Hide Auto' : 1, + 'Hide Toggles' : 2, + 'No Blinking' : 4, + 'No Stacking' : 8, + 'Numeric Stacking' : 16, + 'Hide Buff Numbers' : 32, + 'Stop Sending Buffs' : 64, + }, + 'Group Window' : { + 'Hide Auto' : 256, + 'Hide Toggles' : 512, + 'No Blinking' : 1024, + 'No Stacking' : 2048, + 'Numeric Stacking' : 4096, + 'Hide Buff Numbers' : 8192, + 'Stop Sending Buffs' : 16384, + }, + 'Pet Window' : { + 'Hide Auto' : 65536, + 'Hide Toggles' : 131072, + 'No Blinking' : 262144, + 'No Stacking' : 524288, + 'Numeric Stacking' : 1048576, + 'Hide Buff Numbers' : 2097152, + 'Stop Sending Buffs' : 4194304, + }, + } + self.Groups = {} + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + for group, controls in self.buffDisplayMap.items(): + self.Groups[group] = ControlGroup(dialog, self.Page, label = group) + groupid = self.Groups[group].GetStaticBox().GetId() + for cb, data in controls.items(): + self.Groups[group].AddControl( + ctlType = 'checkbox', + ctlName = f"{groupid}_{group}_{cb}", + label = cb, + data = data, + ) + + groupSizer.Add(self.Groups[group]) + + return groupSizer + + def CalculateValue(self): + page = wx.App.Get().Main.Profile.CustomBinds + + total = 0 + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] + if checkbox.IsChecked(): + total = total + checkbox.Data + return total + + def MakeBindString(self): + return f"optionset buffsettings {self.CalculateValue()}" + + def Serialize(self): + return { 'value' : self.CalculateValue() } + + def Deserialize(self, init): + value = init.get('value', 0) + + value = value or 0 # in case we had for some reason 'None' stashed in the init values + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] + checkbox.SetValue( checkbox.Data & value ) + +####### Chat Command +class ChatCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.chatChannelMap = { # before __init__ + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + chatCommandSizer = wx.GridBagSizer(5, 5) + self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") + chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) + # row 1 + self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) + self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) + self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) + # row 2 + self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) + self.chatCommandDuration.SetRange(1, 20) + self.chatCommandDuration.SetValue(7) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandDuration, (2,1)) + self.chatCommandChatSize = wx.Choice(dialog, -1, + choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) + self.chatCommandChatSize.SetSelection(5) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) + self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) + self.chatCommandChannel.SetSelection(0) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChannel, (2,5)) + # row 3 + self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") + chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) + self.chatCommandMessage = wx.TextCtrl(dialog, -1) + self.chatCommandMessage.SetHint('Chat Command Text') + chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) + + return chatCommandSizer + + def MakeBindString(self): + duration = self.chatCommandDuration.GetValue() + + choice = self.chatCommandChatSize + index = choice.GetSelection() + size = choice.GetString(index) + + duration = f"" if duration != 7 else "" + size = f"" if size != "1" else "" + + bdcolor = fgcolor = bgcolor = '' + if self.chatCommandUseColorsCB.IsChecked(): + bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + + bdcolor = f"" + fgcolor = f"" + bgcolor = f"" + + beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' + text = self.chatCommandMessage.GetValue() + + choice = self.chatCommandChannel + index = choice.GetSelection() + channel = choice.GetString(index) + + return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" + + def Serialize(self): + return { + 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), + 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), + 'channel' : self.chatCommandChannel .GetSelection(), + 'size' : self.chatCommandChatSize.GetSelection(), + 'duration' : self.chatCommandDuration.GetValue(), + 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'text' : self.chatCommandMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) + if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) + if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) + if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) + if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) + if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) + if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) + if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) + if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) + + +####### Chat Command Global +class ChatGlobalCmd(PowerBindCmd): + def BuildUI(self, dialog): + chatCommandGlobalSizer = wx.GridBagSizer(5,5) + + self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") + chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) + + self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalChannel.SetHint("Channel") + chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) + + self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') + chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) + + chatCommandGlobalSizer.AddGrowableCol(1) + + return chatCommandGlobalSizer + + def MakeBindString(self): + useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() + channel = self.chatCommandGlobalChannel.GetValue() + message = self.chatCommandGlobalMessage.GetValue() + + preface = "beginchat /" if useBeginchat else "" + + return f'{preface}send "{channel}" {message}' + + def Serialize(self): + return { + 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), + 'channel' : self.chatCommandGlobalChannel.GetValue(), + 'message' : self.chatCommandGlobalMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) + if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) + if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) + +#######Costume Change +class CostumeChangeCmd(PowerBindCmd): + def BuildUI(self, dialog): + costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeCostume = wx.Choice(dialog, -1, + choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) + self.costumeChangeCostume.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeEmote = wx.Choice(dialog, -1, + choices = GameData.Emotes['costumechange']) + self.costumeChangeEmote.Insert("- None -", 0) + self.costumeChangeEmote.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return costumeChangeSizer + + def MakeBindString(self): + costumeNumber = self.costumeChangeCostume.GetSelection() + costumeEmote = self.costumeChangeEmote.GetSelection() + + if costumeEmote: # None, or 0 == "- None -" + ccCmd = 'cce' + emoteName = self.costumeChangeEmote.GetString(costumeEmote) + emoteName = " CC" + emoteName.replace(" ","") + else: + ccCmd = 'cc' + emoteName = '' + + return f"{ccCmd} {costumeNumber}{emoteName}" + + def Serialize(self): + return{ + 'costumeNumber': self.costumeChangeCostume.GetSelection(), + 'costumeEmote' : self.costumeChangeEmote.GetSelection(), + } + + def Deserialize(self, init): + if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) + if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) + +####### Movement Command +class MovementCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + self.plusbutton.SetValue(True) + + self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.commandchoice = wx.Choice(dialog, choices = [ + "forward", "left", "right", "backward", "up", "down", + "turnleft", "turnright", "first", "autorun", "clicktomove", + ],) + sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) + self.commandchoice.SetSelection(0) + + self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + pre = post = '' + if self.plusbutton.GetValue() : pre = "+" + elif self.plusplusbutton.GetValue() : pre = "++" + elif self.minusbutton.GetValue() : pre = "-" + elif self.zerobutton.GetValue() : post = " 0" + elif self.onebutton.GetValue() : post = " 1" + + command = self.commandchoice.GetString(self.commandchoice.GetSelection()) + + return f"{pre}{command}{post}" + + def Serialize(self): + mod = '' + if self.plusbutton.GetValue() : mod = "plus" + elif self.plusplusbutton.GetValue() : mod = "plusplus" + elif self.minusbutton.GetValue() : mod = "minus" + elif self.zerobutton.GetValue() : mod = "zero" + elif self.onebutton.GetValue() : mod = "one" + + return { + 'mod' : mod, + 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), + } + + def Deserialize(self, init): + mod = init.get('mod', 'plus') + + if mod == 'plus' : self.plusbutton.SetValue(True) + elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) + elif mod == 'minus' : self.minusbutton.SetValue(True) + elif mod == 'zero' : self.zerobutton.SetValue(True) + elif mod == 'one' : self.onebutton.SetValue(True) + + self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) + +####### Graphics Command +class GraphicsCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.FlexGridSizer(2) + + self.visscalecb = wx.CheckBox(dialog, label = "visscale") + sizer.Add(self.visscalecb) + self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) + sizer.Add(self.visscalesc) + + self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") + sizer.Add(self.dofweightcb) + self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) + sizer.Add(self.dofweightsc) + + self.fsaacb = wx.CheckBox(dialog, label = "fsaa") + sizer.Add(self.fsaacb) + self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) + self.fsaach.SetSelection(0) + sizer.Add(self.fsaach) + + self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") + sizer.Add(self.bloomscalecb) + self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) + self.bloomscalech.SetSelection(0) + sizer.Add(self.bloomscalech) + + self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") + sizer.Add(self.bloomweightcb) + self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) + sizer.Add(self.bloomweightsc) + + self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") + sizer.Add(self.lodbiascb) + self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) + sizer.Add(self.lodbiassc) + + self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") + sizer.Add(self.renderscalecb) + self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) + sizer.Add(self.renderscalesc) + + return sizer + + def MakeBindString(self): + # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. + bindstrings = [] + if self.visscalecb.IsChecked(): + bindstrings.append("visscale " + str(self.visscalesc.GetValue())) + if self.dofweightcb.IsChecked(): + bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) + if self.fsaacb.IsChecked(): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bindstrings.append("fsaa " + fsaavalue) + if self.bloomscalecb.IsChecked(): + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + bindstrings.append("bloomscale " + bloomscalevalue) + if self.bloomweightcb.IsChecked(): + bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) + if self.lodbiascb.IsChecked(): + bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) + if self.renderscalecb.IsChecked(): + bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) + + return '$$'.join(bindstrings) + + def Serialize(self): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + return { + 'visscalecb' : self.visscalecb.IsChecked(), + 'visscalesc' : self.visscalesc.GetValue(), + 'dofweightcb' : self.dofweightcb.IsChecked(), + 'dofweightsc' : self.dofweightsc.GetValue(), + 'fsaacb' : self.fsaacb.IsChecked(), + 'fsaach' : fsaavalue, + 'bloomscalecb' : self.bloomscalecb.IsChecked(), + 'bloomscalech' : bloomscalevalue, + 'bloomweightcb' : self.bloomweightcb.IsChecked(), + 'bloomweightsc' : self.bloomweightsc.GetValue(), + 'lodbiascb' : self.lodbiascb.IsChecked(), + 'lodbiassc' : self.lodbiassc.GetValue(), + 'renderscalecb' : self.renderscalecb.IsChecked(), + 'renderscalesc' : self.renderscalesc.GetValue(), + } + + def Deserialize(self, init): + self.visscalecb.SetValue(init.get('visscalecb', False)) + self.visscalesc.SetValue(init.get('visscalesc', 1.0)) + self.dofweightcb.SetValue(init.get('dofweightcb', False)) + self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) + self.fsaacb.SetValue(init.get('fsaacb', False)) + self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) + self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) + self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) + self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) + self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) + self.lodbiascb.SetValue(init.get('lodbiascb', False)) + self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) + self.renderscalecb.SetValue(init.get('renderscalecb', False)) + self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) + +####### Custom Bind +class CustomBindCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.customBindName = wx.TextCtrl(dialog, -1) + self.customBindName.SetHint('Custom Bind Text') + sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + return self.customBindName.GetValue() + + def Serialize(self): + return { 'customBindName': self.customBindName.GetValue() } + + def Deserialize(self,init): + if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) + +####### Emote +class EmoteCmd(PowerBindCmd): + def BuildUI(self, dialog): + emoteSizer = wx.BoxSizer(wx.HORIZONTAL) + self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") + emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + self.emoteName = wx.Button(dialog, -1, "...") + self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) + emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) + + return emoteSizer + + def MakeBindString(self): + displayedEmoteName = self.emoteName.GetLabel() + actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] + + return actualEmotePayload + + def Serialize(self): + return {'emoteName': self.emoteName.GetLabel()} + + def Deserialize(self, init): + if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) + +####### Load Binds Directory +class LoadBindsDir(PowerBindCmd): + def BuildUI(self, dialog): + mainSizer = wx.BoxSizer(wx.VERTICAL) + + lbSizer = wx.BoxSizer(wx.HORIZONTAL) + lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") + lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + profiles = Profile.GetAllProfileBindsDirs() + + self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) + lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") + self.lbResetCB.SetValue(True) + + mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + return mainSizer + + def MakeBindString(self): + + # If the specified binds directory disappeared between runs, we'd crash, so handle that. + if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' + + config = wx.ConfigBase.Get() + if config.Exists('GameBindPath'): + bindpath = config.Read('GameBindPath') + else: + bindpath = config.Read('BindPath') + + reset = "" + if self.lbResetCB.GetValue(): + reset = "keybind_reset$$" + + resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' + return reset + 'bindloadfile ' + str(resetfilepath) + + def Serialize(self): + return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), + 'ResetKeybinds' : self.lbResetCB.GetValue(), + } + + def Deserialize(self, init): + if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) + self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) + +####### Power Abort +class PowerAbortCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecabort' + +####### Power Unqueue +class PowerUnqueueCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecunqueue' + +####### SG Mode +class SGModeCmd(PowerBindCmd): + def BuildUI(self, dialog): + sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) + sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") + self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") + + sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) + + return sgmodeSizer + + def MakeBindString(self): + if self.sgmodeOnRB.GetValue(): + return 'sgmodeset 1' + elif self.sgmodeOffRB.GetValue(): + return 'sgmodeset 0' + else: + return 'sgmode' + + def Serialize(self): + if self.sgmodeOnRB.GetValue(): + val = "On" + elif self.sgmodeOffRB.GetValue(): + val = "Off" + else: + val = "Toggle" + + return {"value" : val} + + def Deserialize(self, init): + val = init.get('value', '') + if val == "On": + self.sgmodeOnRB.SetValue(True) + elif val == "Off": + self.sgmodeOffRB.SetValue(True) + else: + self.sgmodeToggleRB.SetValue(True) + +####### Target Custom +class TargetCustomCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetCustomSizer = wx.GridBagSizer(5,5) + targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), + flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) + self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetCustomModeChoice.SetSelection(0) + targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) + self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) + self.targetCustomOptionalName.SetHint("Optional name to match") + targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) + self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") + targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) + self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") + targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) + self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") + targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) + self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") + targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) + self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") + targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) + self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") + targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) + self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") + targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) + self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") + targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) + + targetCustomSizer.AddGrowableCol(2) + + return targetCustomSizer + + def MakeBindString(self): + choice = self.targetCustomModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + targetCommand = "targetcustom" + mode.lower() + + enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" + friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" + defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" + alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" + mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" + notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" + base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" + notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" + + name = self.targetCustomOptionalName.GetValue() + + return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" + + def Serialize(self): + return { + 'mode' : self.targetCustomModeChoice.GetSelection(), + 'enemy' : self.targetCustomCBEnemies. IsChecked(), + 'friend' : self.targetCustomCBFriends. IsChecked(), + 'defeated' : self.targetCustomCBDefeated. IsChecked(), + 'alive' : self.targetCustomCBAlive. IsChecked(), + 'mypet' : self.targetCustomCBMyPets. IsChecked(), + 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), + 'base' : self.targetCustomCBBaseItems. IsChecked(), + 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), + 'name' : self.targetCustomOptionalName.GetValue(), + } + + def Deserialize(self, init): + if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) + if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) + if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) + if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) + if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) + if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) + if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) + if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) + if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) + if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) + + +####### Target Enemy +class TargetEnemyCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) + targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetEnemyModeChoice.SetSelection(0) + targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetEnemySizer + + def MakeBindString(self): + choice = self.targetEnemyModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetenemy" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetEnemyModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) + +####### Target Friend +class TargetFriendCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) + targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetFriendModeChoice.SetSelection(0) + targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetFriendSizer + + def MakeBindString(self): + choice = self.targetFriendModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetfriend" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetFriendModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) + +####### Team/Pet Select +class TeamPetSelectCmd(PowerBindCmd): + def BuildUI(self, dialog): + teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], + style=wx.ALIGN_CENTER_VERTICAL) + self.teamPetSelectNumber.SetSelection(0) + teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) + + return teamPetSelectSizer + + def MakeBindString(self): + teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' + targetNumber = self.teamPetSelectNumber.GetSelection()+1 + + return f"{teamOrPet}select {targetNumber}" + + def Serialize(self): + return { + 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', + 'targetNum': self.teamPetSelectNumber.GetSelection(), + } + + def Deserialize(self, init): + ToP = init.get('teamOrPet', '') + if ToP == 'pet': + self.teamPetSelectPetRB.SetValue(True) + else: + self.teamPetSelectTeamRB.SetValue(True) + if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) + +####### Unselect +class UnselectCmd(PowerBindCmd): + def MakeBindString(self): + return 'unselect' + +####### Use Insp By Name +class UseInspByNameCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) + for _, types in GameData.Inspirations.items(): + for _, info in types.items(): + for insp in info['tiers']: + name = re.sub(' ', '', str(insp)) + icon = GetIcon(f'Inspirations/{name}') + self.useInspByNameModeChoice.Append(insp, icon) + self.useInspByNameModeChoice.SetSelection(0) + useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) + + return useInspByNameSizer + + def MakeBindString(self): + choice = self.useInspByNameModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "inspexecname " + mode.lower() + + def GetAllInsps(self): + Insplist = [] + for _, info in GameData.Inspirations.items(): + for insp in info['tiers']: + Insplist.append(insp) + Insplist.append("---") + Insplist.pop(-1) # snip the terminal "---" + + return Insplist + + def Serialize(self): + return { 'insp' : self.useInspByNameModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) + +####### Use Insp From Row / Column +class UseInspRowColCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnRow.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) + self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnCol.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) + + return useInspRowColumnSizer + + def MakeBindString(self): + row = self.useInspRowColumnRow.GetSelection()+1 + col = self.useInspRowColumnCol.GetSelection()+1 + + return f"inspexectray {col} {row}" + + def Serialize(self): + return { + 'col' : self.useInspRowColumnCol.GetSelection(), + 'row' : self.useInspRowColumnRow.GetSelection(), + } + + def Deserialize(self, init): + if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) + if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) + +####### Use Power +class UsePowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + outerSizer = wx.BoxSizer(wx.HORIZONTAL) + + usePowerSizer = wx.GridBagSizer(5,5) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBToggle, (0,1)) + self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOn, (0,2)) + self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOff, (0,3)) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerName = PowerPicker(dialog) + usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) + usePowerSizer.AddGrowableCol(3) + + outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) + + return outerSizer + + def MakeBindString(self): + if self.usePowerRBToggle.GetValue(): + method = "powexecname" + elif self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') + return '' + + return f"{method} {self.usePowerName.GetLabel()}" + + def Serialize(self): + if self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + method = "powexecname" + return { + 'method': method, + 'pname' : self.usePowerName.GetLabel(), + 'picon' : self.usePowerName.IconFilename + } + + def Deserialize(self, init): + method = init.get('method', '') + if method == 'powexectoggleon': + self.usePowerRBOn.SetValue(True) + elif method == 'powexectoggleoff': + self.usePowerRBOff.SetValue(True) + else: + self.usePowerRBToggle.SetValue(True) + if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) + +####### Use Power From Tray +class UsePowerFromTrayCmd(PowerBindCmd): + def BuildUI(self, dialog): + usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTrayTray = wx.Choice(dialog, -1, + choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', + 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) + self.usePowerFromTrayTray.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) + self.usePowerFromTraySlot.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return usePowerFromTraySizer + + def MakeBindString(self): + choice = self.usePowerFromTrayTray + tray = choice.GetSelection() + + choice = self.usePowerFromTraySlot + slot = choice.GetSelection()+1 + + mode = "slot" + mode2 = '' + if tray > 3: + mode = "tray" + mode2 = f" {tray - 3}" + elif tray == 3: + mode = "alt2slot" + elif tray == 2: + mode = "altslot" + + return f"powexec{mode} {slot}{mode2}" + + def Serialize(self): + return { + 'tray' : self.usePowerFromTrayTray.GetSelection(), + 'slot' : self.usePowerFromTraySlot.GetSelection(), + } + + def Deserialize(self, init): + if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) + if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) + +####### Window Color +class WindowColorCmd(PowerBindCmd): + def BuildUI(self, dialog): + windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) + borderSizer = wx.BoxSizer(wx.VERTICAL) + self.ColorBorder.SetSizer(borderSizer) + self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) + borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) + + windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) + + RGBASizer = wx.FlexGridSizer(3, 4, 5) + + RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) + self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) + self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + windowColorSizer.Add(RGBASizer) + + self.UpdateFromSlider() + + return windowColorSizer + + def MakeBindString(self): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + return f"windowcolor {Rval} {Gval} {Bval} {Aval}" + + def Serialize(self): + return { + 'Rval' : self.RSlider.GetValue(), + 'Gval' : self.GSlider.GetValue(), + 'Bval' : self.BSlider.GetValue(), + 'Aval' : self.ASlider.GetValue(), + } + + def Deserialize(self, init): + self.RSlider.SetValue(init['Rval']) + self.GSlider.SetValue(init['Gval']) + self.BSlider.SetValue(init['Bval']) + self.ASlider.SetValue(init['Aval']) + self.UpdateFromSlider() + + def UpdateFromSlider(self, _ = None): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RReadout.SetValue(Rval) + self.GReadout.SetValue(Gval) + self.BReadout.SetValue(Bval) + self.AReadout.SetValue(Aval) + self.ColorBorder.Refresh() + + def UpdateFromText(self, _ = None): + Rval = self.RReadout.GetValue() + Gval = self.GReadout.GetValue() + Bval = self.BReadout.GetValue() + Aval = self.AReadout.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RSlider.SetValue(Rval) + self.GSlider.SetValue(Gval) + self.BSlider.SetValue(Bval) + self.ASlider.SetValue(Aval) + self.ColorBorder.Refresh() + +####### Window Save / Load +class WindowSaveLoadCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) + self.CommandChoice.SetSelection(0) + sizer.Add(self.CommandChoice, 0, wx.ALL, 5) + + self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), + value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) + sizer.Add(self.FilePath, 0, wx.ALL, 5) + + return sizer + + def MakeBindString(self): + command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] + return f'{command} "{self.FilePath.GetValue()}"' + + def Serialize(self): + return { + 'command' : self.CommandChoice.GetSelection(), + 'filename' : self.FilePath.GetValue(), + } + + def Deserialize(self, init): + self.CommandChoice.SetSelection(init.get('command', 0)) + self.FilePath.SetValue(init.get('filename', '')) + +####### Window Toggle +class WindowToggleCmd(PowerBindCmd): + def BuildUI(self, dialog): + self.WindowNames = { + 'Actions' : 'actions', + 'Auction House' : 'ah', + 'Badge' : 'badge', + 'Channel Search' : 'chansearch', + 'Chat' : 'chat', + 'Custom Chat 1' : 'chat1', + 'Custom Chat 2' : 'chat2', + 'Custom Chat 3' : 'chat3', + 'Custom Chat 4' : 'chat4', + 'Clues' : 'clue', + 'Combat Numbers' : 'combatnumbers', + 'Contacts' : 'contact', + 'Contact Finder' : 'contactfinder', + 'Costumes' : 'costume', + 'Email' : 'email', + 'Enhancements' : 'enhancements', + 'Friends' : 'friend', + 'Group' : 'group', + 'Help' : 'helpwindow', + 'Incarnate' : 'incarnate', + 'Inspirations' : 'insp', + 'League' : 'league', + 'LFG' : 'lfg', + 'Map' : 'map', + 'Mission' : 'mission', + 'Nav / Compass' : 'nav', + 'Options' : 'options', + 'Pets' : 'pet', + 'Petition' : 'petition', + 'Power Tray' : 'powers', + 'Power List' : 'powerlist', + 'Quit' : 'quit', + 'Recipes' : 'recipe', + 'Salvage' : 'salvage', + 'Search' : 'search', + 'Supergroup' : 'sg', + 'Target' : 'target', + 'Team' : 'team', + 'Tray' : 'tray', + 'Tray1' : 'tray1', + 'Tray2' : 'tray2', + 'Tray3' : 'tray3', + 'Tray4' : 'tray4', + 'Tray5' : 'tray5', + 'Tray6' : 'tray6', + 'Tray7' : 'tray7', + 'Tray8' : 'tray8', + 'Vault' : 'vault', + } + + self.ShortToggleCommands = { + 'Auction House' : 'ah', + 'Chat' : 'chat', + 'Help' : 'helpwindow', + 'Map' : 'map', + 'Nav / Compass' : 'nav', + 'Power Tray' : 'powers', + 'Target' : 'target', + 'Tray' : 'tray', + } + + windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) + windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) + self.windowToggleTray.SetSelection(0) + windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.windowShowRB = wx.RadioButton(dialog, -1, "Show") + self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") + + windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) + + return windowToggleSizer + + def MakeBindString(self): + choice = self.windowToggleTray + index = choice.GetSelection() + windowdesc = choice.GetString(index) + windowname = self.WindowNames[windowdesc] + + if self.windowShowRB.GetValue(): + return 'show ' + windowname + elif self.windowHideRB.GetValue(): + return 'windowhide ' + windowname + else: + if shortcmd := self.ShortToggleCommands.get(windowdesc, None): + return shortcmd + else: + return 'toggle ' + windowname + + + def Serialize(self): + choice = self.windowToggleTray + if self.windowShowRB.GetValue(): + action = "Show" + elif self.windowHideRB.GetValue(): + action = "Hide" + else: + action = "Toggle" + return { + 'window': choice.GetString(choice.GetSelection()), + 'action': action, + } + + def Deserialize(self, init): + choice = self.windowToggleTray + if window := init.get('window', ''): + if isinstance(window, int): + choice.SetSelection(window) + else: + choice.SetSelection(choice.FindString(window)) + + if choice.GetSelection() == wx.NOT_FOUND: + choice.SetSelection(0) + + action = init.get('action', '') + if action == "Show": + self.windowShowRB.SetValue(True) + elif action == "Hide": + self.windowHideRB.SetValue(True) + else: + self.windowToggleRB.SetValue(True) + + +# Must always add to this list when adding a new command class above +menuStructure = { + 'Graphics / UI' : [ + 'Attribute Monitor', + 'Buff Display Settings', + 'Graphics Settings', + 'Window Color', + 'Window Save / Load', + 'Window Toggle', + ], + 'Inspirations' : [ + 'Use Inspiration By Name', + 'Use Inspiration From Row/Column', + ], + 'Powers' : [ + 'Auto Power', + 'Power Abort', + 'Power Unqueue', + 'Use Power', + 'Use Power From Tray', + ], + 'Social' : [ + 'Away From Keyboard', + 'Chat Command', + 'Chat Command (Global)', + 'Costume Change', + 'Emote', + 'Supergroup Mode', + ], + 'Targeting' : [ + 'Target Custom', + 'Target Enemy', + 'Target Frield', + 'Team/Pet Select', + 'Unselect', + ], + 'Misc' : [ + 'Load Binds Directory', + 'Movement Commands', + ], + # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, + # but I'm leaving it here to remind myself that we do that. + } + +# Must always add to this list when adding a new command class above +commandClasses = { + 'Auto Power' : AutoPowerCmd, + 'Away From Keyboard' : AFKCmd, + 'Attribute Monitor' : AttributeMonitorCmd, + 'Buff Display Settings' : BuffDisplayCmd, + 'Chat Command' : ChatCmd, + 'Chat Command (Global)' : ChatGlobalCmd, + 'Costume Change' : CostumeChangeCmd, + 'Custom Bind' : CustomBindCmd, + 'Emote' : EmoteCmd, + 'Graphics Settings' : GraphicsCmd, + 'Load Binds Directory' : LoadBindsDir, + 'Movement Commands' : MovementCmd, + 'Power Abort' : PowerAbortCmd, + 'Power Unqueue' : PowerUnqueueCmd, + 'Supergroup Mode' : SGModeCmd, + 'Target Custom' : TargetCustomCmd, + 'Target Enemy' : TargetEnemyCmd, + 'Target Friend' : TargetFriendCmd, + 'Team/Pet Select' : TeamPetSelectCmd, + 'Unselect' : UnselectCmd, + 'Use Inspiration By Name' : UseInspByNameCmd, + 'Use Inspiration From Row/Column' : UseInspRowColCmd, + 'Use Power' : UsePowerCmd, + 'Use Power From Tray' : UsePowerFromTrayCmd, + 'Window Color' : WindowColorCmd, + 'Window Save / Load' : WindowSaveLoadCmd, + 'Window Toggle' : WindowToggleCmd, +} +# use these when we rename a commandClass so that old Profiles will still load correctly. +# If we've also updated the class, we need to try to make sure the new class will still +# Deserialize the legacy data, or at least not crash. +deprecatedCommandClasses = { + 'SG Mode Toggle' : SGModeCmd, + 'Use Insp By Name' : UseInspByNameCmd, + 'Use Insp From Row/Column' : UseInspRowColCmd, +} +commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/AutoPowerCmd.py b/UI/PowerBinderCommand/AutoPowerCmd.py new file mode 100644 index 0000000..4c02ab7 --- /dev/null +++ b/UI/PowerBinderCommand/AutoPowerCmd.py @@ -0,0 +1,1800 @@ +import wx +import re +import UI +import UI.EmotePicker +from UI.ControlGroup import ControlGroup +from UI.PowerPicker import PowerPicker +from Help import HelpButton +import wx.adv +from wx.adv import BitmapComboBox, EditableListBox +from pathlib import PureWindowsPath +import GameData +import Profile +from Icon import GetIcon + +class PowerBinderDialog(wx.Dialog): + def __init__(self, parent, button, init = {}): + wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) + + self.Page = parent.Page + self.EditDialog = PowerBinderEditDialog(self) + self.Button = button + self.AddStepMenu = self.makeAddStepMenu() + + sizer = wx.BoxSizer(wx.VERTICAL); + self.mainSizer = sizer + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) + # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) + # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) + #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) + AddStepButton = wx.Button(self, -1, 'Add Step') + AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) + AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) + choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) + choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) + sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) + + rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) + + self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) + self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) + self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) + rearrangeCtrl.Add(self.RearrangeList, 1) + + rearrangeButtons = wx.BoxSizer(wx.VERTICAL) + self.DelButton = wx.Button(self, -1, "Delete") + self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) + self.EditButton = wx.Button(self, -1, "Edit") + self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) + self.EditButton.Disable() + upButton = wx.Button(self, -1, "\u25B2") + upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) + downButton = wx.Button(self, -1, "\u25BC") + downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) + rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) + rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) + + sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.BindStringDisplay = wx.TextCtrl(self, -1) + self.BindStringDisplay.Disable() + choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, + wx.ALIGN_CENTER_VERTICAL) + choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) + + sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) + + sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) + + # need to dig around and get the OK button since we show this dialog modelessly now. + okButton = self.FindWindow(self.GetAffirmativeId()) + okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) + + # Wrap everything in a vbox to add some padding + vbox = wx.BoxSizer(wx.VERTICAL); + vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); + + self.SetSizerAndFit(vbox); + self.Layout() + self.Fit() + self.SetFocus() + + # if we are loading from profile, ie, have "init", build the list from it + if init: self.LoadFromData(init) + + def LoadFromData(self, init): + for item in init: + for type, data in item.items(): + commandClass = commandClasses.get(type, None) + if not commandClass: + commandClass = deprecatedCommandClasses.get(type, None) + if not commandClass: + wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") + continue + newCommand = commandClass(self.EditDialog, data) + index = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.SetClientData(index, newCommand) + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) + self.EditDialog.mainSizer.Hide(newCommand.UI) + self.UpdateBindStringDisplay() + + def SaveToData(self): + data = [] + index = 0 + for _ in self.RearrangeList.GetItems(): + # check whether we have an object already attached to this choice + cmdObject = self.RearrangeList.GetClientData(index) + commandClassName = commandRevClasses[type(cmdObject)] + data.append({commandClassName: cmdObject.Serialize()}) + index = index + 1 + return data + + def OnAddStepButton(self, evt): + button = evt.EventObject + if not self.AddStepMenu: + self.AddStepMenu = self.makeAddStepMenu() + button.PopupMenu(self.AddStepMenu) + + + def OnOKButton(self, _): + if self.Button.tgtTxtCtrl: + bindString = self.MakeBindString() + if bindString != self.Button.tgtTxtCtrl.GetValue(): + self.Button.tgtTxtCtrl.SetValue(bindString) + wx.App.Get().Main.Profile.SetModified() + self.Close() + + def OnRearrangeDelete(self, _): + current = self.RearrangeList.GetSelection() + if current == wx.NOT_FOUND: return + + self.RearrangeList.Delete(current) + self.UpdateBindStringDisplay() + + def OnRearrangeUp(self, _): + self.RearrangeList.MoveCurrentUp() + self.UpdateBindStringDisplay() + + def OnRearrangeDown(self, _): + self.RearrangeList.MoveCurrentDown() + self.UpdateBindStringDisplay() + + def OnRearrangeEdit(self, _): + index = self.RearrangeList.GetSelection() + + # check whether we have an object already attached to this choice + cmdObject = None + try: + cmdObject = self.RearrangeList.GetClientData(index) + except Exception: + pass + + if cmdObject: + self.ShowEditDialogFor(cmdObject) + self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) + else: + print("cmdObject was None") + self.UpdateBindStringDisplay() + + # OnAddStepMenu creates a new step and adds it to the rearrangelist + def OnAddStepMenu(self, evt): + menuitem = self.AddStepMenu.FindItemById(evt.GetId()) + chosenName = menuitem.GetItemLabel() + + # make a new command object, attached to the parent dialog + newCommandClass = commandClasses[chosenName] + newCommand = newCommandClass(self.EditDialog) + + # show the edit dialog if this command needs it + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) + if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): + self.EditDialog.mainSizer.Remove(newCommand.UI) + return + + newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.Select(newBindIndex) + self.RearrangeList.SetClientData(newBindIndex, newCommand) + + self.OnListSelect() + self.UpdateBindStringDisplay() + + def OnListSelect(self, _ = None): + selected = self.RearrangeList.GetSelection() + + if selected != wx.NOT_FOUND: + selCommand = self.RearrangeList.GetClientData(selected) + if selCommand.UI: + self.EditButton.Enable() + else: + self.EditButton.Disable() + + def UpdateBindStringDisplay(self): + self.BindStringDisplay.SetValue(self.MakeBindString()) + self.BindStringDisplay.SetToolTip(self.MakeBindString()) + + def MakeBindString(self): + cmdBindStrings = [] + for index in range(self.RearrangeList.GetCount()): + c = self.RearrangeList.GetClientData(index) + if c: cmdBindStrings.append(c.MakeBindString()) + + bindstring = ('$$'.join(cmdBindStrings)) + return bindstring + + def ShowEditDialogFor(self, command): + if not command.UI: return + + self.EditDialog.mainSizer.Show(command.UI) + + self.EditDialog.Layout() + self.EditDialog.Fit() + + self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') + returnval = self.EditDialog.ShowModal() + + self.EditDialog.mainSizer.Hide(command.UI) + + return returnval + + def makeAddStepMenu(self): + + stepMenu = wx.Menu() + + for subname in menuStructure: + submenu = wx.Menu() + stepMenu.AppendSubMenu(submenu, subname) + for classname in menuStructure[subname]: + submenu.Append(wx.ID_ANY, classname) + + stepMenu.Append(wx.ID_ANY, 'Custom Bind') + + return stepMenu + +class PowerBinderButton(wx.BitmapButton): + + def __init__(self, parent, tgtTxtCtrl, init = {}): + wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) + self.Init = init + self.Dialog = None + self.DialogParent = parent + + self.tgtTxtCtrl = tgtTxtCtrl + self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) + self.SetToolTip("Launch PowerBinder") + + def PowerBinderEventHandler(self, _): + self.PowerBinderDialog().Show() + + def LoadFromData(self, data): + self.PowerBinderDialog().LoadFromData(data) + + def SaveToData(self): + return self.PowerBinderDialog().SaveToData() + + def PowerBinderDialog(self): + if not self.Dialog: + self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) + return self.Dialog + + +class PowerBinderEditDialog(wx.Dialog): + def __init__(self, parent): + wx.Dialog.__init__(self, parent, -1, "Edit Step", + style = wx.DEFAULT_DIALOG_STYLE) + + outerSizer = wx.BoxSizer(wx.VERTICAL) + + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + self.mainSizer.SetMinSize([500, 150]) + + self.Page = parent.Page + + self.mainSizer.Add( + self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), + 0, wx.EXPAND|wx.ALL, 10) + + outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) + + self.SetSizerAndFit(outerSizer) + self.Layout() + self.Fit() + +########### Power Binder Command Objects +class PowerBindCmd(): + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + commandClassName = commandRevClasses[type(self)] + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{commandClassName} - {short_bindstr}" + + +####### Away From Keyboard +class AFKCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) + +####### Attribute Monitor +class AttributeMonitorCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.Groups = {} + self.AttributeTable = { + 'Base' : { + 'Current Hit Points' : 'NT H', + 'Max Hit Points' : 'X H', + 'Current Endurance' : 'T E', + 'Max Endurance' : 'X EN', + 'Regeneration Rate' : 'N RAT', + 'Recovery Rate' : 'Y RA', + 'Endurance Consumption' : 'SU', + 'ToHit Bonus' : 'T B', + 'Accuracy Bonus' : 'CC', + 'Last Hit Chance' : 'T C', + 'Damage Bonus' : 'DA', + 'Healing Bonus' : 'NG B', + 'Recharge Time Bonus' : 'ME B', + 'Endurance Discount' : 'CE DIS', + 'Stealth Radius (PvP)' : 'PVP', + 'Stealth Radius (PvE)' : 'PVE', + 'Perception Radius' : 'RC', + 'Range Bonus' : 'GE B', + 'Threat Level' : 'AT L', + 'Experience to Next Level' : 'XT', + 'Experience Debt' : 'XP', + 'Influence / Infamy' : 'INF', + 'Inherent' : 'NH', + }, + 'Movement Speed' : { + 'Flying Speed' : 'FL', + 'Jumping Speed' : 'PI', + 'Max Jump Height' : 'X J', + 'Run Speed' : 'RU', + }, + 'Damage Resistance' : { + 'Smashing Resistance' : 'G R', + 'Lethal Resistance' : 'L R', + 'Fire Resistance' : 'RE R', + 'Cold Resistance' : 'COLD R', + 'Energy Resistance' : 'DamageType[4]', + 'Negative Energy Resistance' : 'GY R', + 'Psyonic Resistance' : 'NIC R', + 'Toxic Resistance' : 'XIC R', + }, + 'Defense' : { + 'Base Defense' : 'BAS', + 'Ranged Defense' : 'ED', + 'Melee Defense' : 'MEL', + 'AoE Defense' : '2', + 'Smashing Defense' : '3', + 'Lethal Defense' : '4', + 'Fire Defense' : '5', + 'Cold Defense' : '6', + 'Energy Defense' : '7', + 'Negative Energy Defense' : '8', + 'Psionic Defense' : '9', + 'Toxic Defense' : '1', + }, + 'Debuff Resistance' : { + 'Regeneration Resistance' : 'ON R', + 'Recovery Resistance' : 'RY R', + 'To Hit Resistance' : 'IT R', + 'Defense Resistance' : 'NSE RES', + }, + 'Status Effect Protection' : { + 'Hold Protection' : 'D P', + 'Immobilize Protection' : 'LIZE P', + 'Stun Protection' : 'N P', + 'Sleep Protection' : 'P P', + 'Knockback Protection' : 'K P', + 'Confuse Protection' : 'SE P', + 'Terrorize Protection' : 'ZE P', + 'Repel Protection' : 'EL P', + 'Teleport Protection' : 'T P', + }, + 'Status Effect Resistance' : { + 'Hold Resistance' : 'D R', + 'Immobilize Resistance' : 'LIZE R', + 'Stun Resistance' : 'N R', + 'Sleep Resistance' : 'P R', + 'Knockback Resistance' : 'K R', + 'Confuse Resistance' : 'SE R', + 'Terrorize Resistance' : 'ZE R', + 'Placate Resistance' : 'TE R', + 'Taunt Resistance' : 'NT R', + }, + 'Miscellaneous' : { + 'Level Shift' : 'L S', + }, + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.AttributeMenu = wx.Menu() + for group, controls in self.AttributeTable.items(): + submenu = wx.Menu() + self.AttributeMenu.AppendSubMenu(submenu, group) + for cb in controls: + submenu.Append(wx.ID_ANY, cb) + + self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) + + self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) + groupSizer.Add(self.editbox) + + newButton = self.editbox.GetNewButton() + newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) + + return groupSizer + + def MakeBindString(self): + map = {} + bindstrings = [] + for _, controls in self.AttributeTable.items(): + for cb, data in controls.items(): + map[cb] = data + + for string in self.editbox.GetStrings(): + if string: + bindstrings.append(f'monitorattribute {map[string]}') + + return '$$'.join(bindstrings) + + def Serialize(self): + return { + 'attributes' : self.editbox.GetStrings() + } + + def Deserialize(self, init): + self.editbox.SetStrings(init.get('attributes', [])) + + def OnNewButton(self, evt): + evt.GetEventObject().PopupMenu(self.AttributeMenu) + + def OnMenuItem(self, evt): + menuitem = evt.EventObject.FindItemById(evt.GetId()) + existingstrings = self.editbox.GetStrings() + existingstrings.append(menuitem.GetItemLabel()) + self.editbox.SetStrings(existingstrings) + +####### Auto Power +class AutoPowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) + autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.autoPowerName = PowerPicker(dialog) + autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) + + return autoPowerSizer + + def MakeBindString(self): + return f"powexecauto {self.autoPowerName.GetLabel()}" + + def Serialize(self): + return { + 'pname' : self.autoPowerName.GetLabel(), + 'picon' : self.autoPowerName.IconFilename + } + + def Deserialize(self, init): + if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) + +####### Buff Display Command +class BuffDisplayCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.buffDisplayMap = { + 'Status Window' : { + 'Hide Auto' : 1, + 'Hide Toggles' : 2, + 'No Blinking' : 4, + 'No Stacking' : 8, + 'Numeric Stacking' : 16, + 'Hide Buff Numbers' : 32, + 'Stop Sending Buffs' : 64, + }, + 'Group Window' : { + 'Hide Auto' : 256, + 'Hide Toggles' : 512, + 'No Blinking' : 1024, + 'No Stacking' : 2048, + 'Numeric Stacking' : 4096, + 'Hide Buff Numbers' : 8192, + 'Stop Sending Buffs' : 16384, + }, + 'Pet Window' : { + 'Hide Auto' : 65536, + 'Hide Toggles' : 131072, + 'No Blinking' : 262144, + 'No Stacking' : 524288, + 'Numeric Stacking' : 1048576, + 'Hide Buff Numbers' : 2097152, + 'Stop Sending Buffs' : 4194304, + }, + } + self.Groups = {} + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + for group, controls in self.buffDisplayMap.items(): + self.Groups[group] = ControlGroup(dialog, self.Page, label = group) + groupid = self.Groups[group].GetStaticBox().GetId() + for cb, data in controls.items(): + self.Groups[group].AddControl( + ctlType = 'checkbox', + ctlName = f"{groupid}_{group}_{cb}", + label = cb, + data = data, + ) + + groupSizer.Add(self.Groups[group]) + + return groupSizer + + def CalculateValue(self): + page = wx.App.Get().Main.Profile.CustomBinds + + total = 0 + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] + if checkbox.IsChecked(): + total = total + checkbox.Data + return total + + def MakeBindString(self): + return f"optionset buffsettings {self.CalculateValue()}" + + def Serialize(self): + return { 'value' : self.CalculateValue() } + + def Deserialize(self, init): + value = init.get('value', 0) + + value = value or 0 # in case we had for some reason 'None' stashed in the init values + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] + checkbox.SetValue( checkbox.Data & value ) + +####### Chat Command +class ChatCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.chatChannelMap = { # before __init__ + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + chatCommandSizer = wx.GridBagSizer(5, 5) + self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") + chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) + # row 1 + self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) + self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) + self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) + # row 2 + self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) + self.chatCommandDuration.SetRange(1, 20) + self.chatCommandDuration.SetValue(7) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandDuration, (2,1)) + self.chatCommandChatSize = wx.Choice(dialog, -1, + choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) + self.chatCommandChatSize.SetSelection(5) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) + self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) + self.chatCommandChannel.SetSelection(0) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChannel, (2,5)) + # row 3 + self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") + chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) + self.chatCommandMessage = wx.TextCtrl(dialog, -1) + self.chatCommandMessage.SetHint('Chat Command Text') + chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) + + return chatCommandSizer + + def MakeBindString(self): + duration = self.chatCommandDuration.GetValue() + + choice = self.chatCommandChatSize + index = choice.GetSelection() + size = choice.GetString(index) + + duration = f"" if duration != 7 else "" + size = f"" if size != "1" else "" + + bdcolor = fgcolor = bgcolor = '' + if self.chatCommandUseColorsCB.IsChecked(): + bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + + bdcolor = f"" + fgcolor = f"" + bgcolor = f"" + + beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' + text = self.chatCommandMessage.GetValue() + + choice = self.chatCommandChannel + index = choice.GetSelection() + channel = choice.GetString(index) + + return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" + + def Serialize(self): + return { + 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), + 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), + 'channel' : self.chatCommandChannel .GetSelection(), + 'size' : self.chatCommandChatSize.GetSelection(), + 'duration' : self.chatCommandDuration.GetValue(), + 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'text' : self.chatCommandMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) + if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) + if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) + if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) + if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) + if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) + if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) + if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) + if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) + + +####### Chat Command Global +class ChatGlobalCmd(PowerBindCmd): + def BuildUI(self, dialog): + chatCommandGlobalSizer = wx.GridBagSizer(5,5) + + self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") + chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) + + self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalChannel.SetHint("Channel") + chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) + + self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') + chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) + + chatCommandGlobalSizer.AddGrowableCol(1) + + return chatCommandGlobalSizer + + def MakeBindString(self): + useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() + channel = self.chatCommandGlobalChannel.GetValue() + message = self.chatCommandGlobalMessage.GetValue() + + preface = "beginchat /" if useBeginchat else "" + + return f'{preface}send "{channel}" {message}' + + def Serialize(self): + return { + 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), + 'channel' : self.chatCommandGlobalChannel.GetValue(), + 'message' : self.chatCommandGlobalMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) + if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) + if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) + +#######Costume Change +class CostumeChangeCmd(PowerBindCmd): + def BuildUI(self, dialog): + costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeCostume = wx.Choice(dialog, -1, + choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) + self.costumeChangeCostume.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeEmote = wx.Choice(dialog, -1, + choices = GameData.Emotes['costumechange']) + self.costumeChangeEmote.Insert("- None -", 0) + self.costumeChangeEmote.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return costumeChangeSizer + + def MakeBindString(self): + costumeNumber = self.costumeChangeCostume.GetSelection() + costumeEmote = self.costumeChangeEmote.GetSelection() + + if costumeEmote: # None, or 0 == "- None -" + ccCmd = 'cce' + emoteName = self.costumeChangeEmote.GetString(costumeEmote) + emoteName = " CC" + emoteName.replace(" ","") + else: + ccCmd = 'cc' + emoteName = '' + + return f"{ccCmd} {costumeNumber}{emoteName}" + + def Serialize(self): + return{ + 'costumeNumber': self.costumeChangeCostume.GetSelection(), + 'costumeEmote' : self.costumeChangeEmote.GetSelection(), + } + + def Deserialize(self, init): + if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) + if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) + +####### Movement Command +class MovementCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + self.plusbutton.SetValue(True) + + self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.commandchoice = wx.Choice(dialog, choices = [ + "forward", "left", "right", "backward", "up", "down", + "turnleft", "turnright", "first", "autorun", "clicktomove", + ],) + sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) + self.commandchoice.SetSelection(0) + + self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + pre = post = '' + if self.plusbutton.GetValue() : pre = "+" + elif self.plusplusbutton.GetValue() : pre = "++" + elif self.minusbutton.GetValue() : pre = "-" + elif self.zerobutton.GetValue() : post = " 0" + elif self.onebutton.GetValue() : post = " 1" + + command = self.commandchoice.GetString(self.commandchoice.GetSelection()) + + return f"{pre}{command}{post}" + + def Serialize(self): + mod = '' + if self.plusbutton.GetValue() : mod = "plus" + elif self.plusplusbutton.GetValue() : mod = "plusplus" + elif self.minusbutton.GetValue() : mod = "minus" + elif self.zerobutton.GetValue() : mod = "zero" + elif self.onebutton.GetValue() : mod = "one" + + return { + 'mod' : mod, + 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), + } + + def Deserialize(self, init): + mod = init.get('mod', 'plus') + + if mod == 'plus' : self.plusbutton.SetValue(True) + elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) + elif mod == 'minus' : self.minusbutton.SetValue(True) + elif mod == 'zero' : self.zerobutton.SetValue(True) + elif mod == 'one' : self.onebutton.SetValue(True) + + self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) + +####### Graphics Command +class GraphicsCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.FlexGridSizer(2) + + self.visscalecb = wx.CheckBox(dialog, label = "visscale") + sizer.Add(self.visscalecb) + self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) + sizer.Add(self.visscalesc) + + self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") + sizer.Add(self.dofweightcb) + self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) + sizer.Add(self.dofweightsc) + + self.fsaacb = wx.CheckBox(dialog, label = "fsaa") + sizer.Add(self.fsaacb) + self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) + self.fsaach.SetSelection(0) + sizer.Add(self.fsaach) + + self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") + sizer.Add(self.bloomscalecb) + self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) + self.bloomscalech.SetSelection(0) + sizer.Add(self.bloomscalech) + + self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") + sizer.Add(self.bloomweightcb) + self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) + sizer.Add(self.bloomweightsc) + + self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") + sizer.Add(self.lodbiascb) + self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) + sizer.Add(self.lodbiassc) + + self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") + sizer.Add(self.renderscalecb) + self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) + sizer.Add(self.renderscalesc) + + return sizer + + def MakeBindString(self): + # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. + bindstrings = [] + if self.visscalecb.IsChecked(): + bindstrings.append("visscale " + str(self.visscalesc.GetValue())) + if self.dofweightcb.IsChecked(): + bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) + if self.fsaacb.IsChecked(): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bindstrings.append("fsaa " + fsaavalue) + if self.bloomscalecb.IsChecked(): + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + bindstrings.append("bloomscale " + bloomscalevalue) + if self.bloomweightcb.IsChecked(): + bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) + if self.lodbiascb.IsChecked(): + bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) + if self.renderscalecb.IsChecked(): + bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) + + return '$$'.join(bindstrings) + + def Serialize(self): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + return { + 'visscalecb' : self.visscalecb.IsChecked(), + 'visscalesc' : self.visscalesc.GetValue(), + 'dofweightcb' : self.dofweightcb.IsChecked(), + 'dofweightsc' : self.dofweightsc.GetValue(), + 'fsaacb' : self.fsaacb.IsChecked(), + 'fsaach' : fsaavalue, + 'bloomscalecb' : self.bloomscalecb.IsChecked(), + 'bloomscalech' : bloomscalevalue, + 'bloomweightcb' : self.bloomweightcb.IsChecked(), + 'bloomweightsc' : self.bloomweightsc.GetValue(), + 'lodbiascb' : self.lodbiascb.IsChecked(), + 'lodbiassc' : self.lodbiassc.GetValue(), + 'renderscalecb' : self.renderscalecb.IsChecked(), + 'renderscalesc' : self.renderscalesc.GetValue(), + } + + def Deserialize(self, init): + self.visscalecb.SetValue(init.get('visscalecb', False)) + self.visscalesc.SetValue(init.get('visscalesc', 1.0)) + self.dofweightcb.SetValue(init.get('dofweightcb', False)) + self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) + self.fsaacb.SetValue(init.get('fsaacb', False)) + self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) + self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) + self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) + self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) + self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) + self.lodbiascb.SetValue(init.get('lodbiascb', False)) + self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) + self.renderscalecb.SetValue(init.get('renderscalecb', False)) + self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) + +####### Custom Bind +class CustomBindCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.customBindName = wx.TextCtrl(dialog, -1) + self.customBindName.SetHint('Custom Bind Text') + sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + return self.customBindName.GetValue() + + def Serialize(self): + return { 'customBindName': self.customBindName.GetValue() } + + def Deserialize(self,init): + if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) + +####### Emote +class EmoteCmd(PowerBindCmd): + def BuildUI(self, dialog): + emoteSizer = wx.BoxSizer(wx.HORIZONTAL) + self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") + emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + self.emoteName = wx.Button(dialog, -1, "...") + self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) + emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) + + return emoteSizer + + def MakeBindString(self): + displayedEmoteName = self.emoteName.GetLabel() + actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] + + return actualEmotePayload + + def Serialize(self): + return {'emoteName': self.emoteName.GetLabel()} + + def Deserialize(self, init): + if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) + +####### Load Binds Directory +class LoadBindsDir(PowerBindCmd): + def BuildUI(self, dialog): + mainSizer = wx.BoxSizer(wx.VERTICAL) + + lbSizer = wx.BoxSizer(wx.HORIZONTAL) + lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") + lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + profiles = Profile.GetAllProfileBindsDirs() + + self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) + lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") + self.lbResetCB.SetValue(True) + + mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + return mainSizer + + def MakeBindString(self): + + # If the specified binds directory disappeared between runs, we'd crash, so handle that. + if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' + + config = wx.ConfigBase.Get() + if config.Exists('GameBindPath'): + bindpath = config.Read('GameBindPath') + else: + bindpath = config.Read('BindPath') + + reset = "" + if self.lbResetCB.GetValue(): + reset = "keybind_reset$$" + + resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' + return reset + 'bindloadfile ' + str(resetfilepath) + + def Serialize(self): + return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), + 'ResetKeybinds' : self.lbResetCB.GetValue(), + } + + def Deserialize(self, init): + if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) + self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) + +####### Power Abort +class PowerAbortCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecabort' + +####### Power Unqueue +class PowerUnqueueCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecunqueue' + +####### SG Mode +class SGModeCmd(PowerBindCmd): + def BuildUI(self, dialog): + sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) + sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") + self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") + + sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) + + return sgmodeSizer + + def MakeBindString(self): + if self.sgmodeOnRB.GetValue(): + return 'sgmodeset 1' + elif self.sgmodeOffRB.GetValue(): + return 'sgmodeset 0' + else: + return 'sgmode' + + def Serialize(self): + if self.sgmodeOnRB.GetValue(): + val = "On" + elif self.sgmodeOffRB.GetValue(): + val = "Off" + else: + val = "Toggle" + + return {"value" : val} + + def Deserialize(self, init): + val = init.get('value', '') + if val == "On": + self.sgmodeOnRB.SetValue(True) + elif val == "Off": + self.sgmodeOffRB.SetValue(True) + else: + self.sgmodeToggleRB.SetValue(True) + +####### Target Custom +class TargetCustomCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetCustomSizer = wx.GridBagSizer(5,5) + targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), + flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) + self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetCustomModeChoice.SetSelection(0) + targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) + self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) + self.targetCustomOptionalName.SetHint("Optional name to match") + targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) + self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") + targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) + self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") + targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) + self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") + targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) + self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") + targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) + self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") + targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) + self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") + targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) + self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") + targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) + self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") + targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) + + targetCustomSizer.AddGrowableCol(2) + + return targetCustomSizer + + def MakeBindString(self): + choice = self.targetCustomModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + targetCommand = "targetcustom" + mode.lower() + + enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" + friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" + defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" + alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" + mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" + notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" + base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" + notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" + + name = self.targetCustomOptionalName.GetValue() + + return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" + + def Serialize(self): + return { + 'mode' : self.targetCustomModeChoice.GetSelection(), + 'enemy' : self.targetCustomCBEnemies. IsChecked(), + 'friend' : self.targetCustomCBFriends. IsChecked(), + 'defeated' : self.targetCustomCBDefeated. IsChecked(), + 'alive' : self.targetCustomCBAlive. IsChecked(), + 'mypet' : self.targetCustomCBMyPets. IsChecked(), + 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), + 'base' : self.targetCustomCBBaseItems. IsChecked(), + 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), + 'name' : self.targetCustomOptionalName.GetValue(), + } + + def Deserialize(self, init): + if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) + if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) + if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) + if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) + if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) + if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) + if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) + if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) + if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) + if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) + + +####### Target Enemy +class TargetEnemyCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) + targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetEnemyModeChoice.SetSelection(0) + targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetEnemySizer + + def MakeBindString(self): + choice = self.targetEnemyModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetenemy" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetEnemyModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) + +####### Target Friend +class TargetFriendCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) + targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetFriendModeChoice.SetSelection(0) + targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetFriendSizer + + def MakeBindString(self): + choice = self.targetFriendModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetfriend" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetFriendModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) + +####### Team/Pet Select +class TeamPetSelectCmd(PowerBindCmd): + def BuildUI(self, dialog): + teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], + style=wx.ALIGN_CENTER_VERTICAL) + self.teamPetSelectNumber.SetSelection(0) + teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) + + return teamPetSelectSizer + + def MakeBindString(self): + teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' + targetNumber = self.teamPetSelectNumber.GetSelection()+1 + + return f"{teamOrPet}select {targetNumber}" + + def Serialize(self): + return { + 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', + 'targetNum': self.teamPetSelectNumber.GetSelection(), + } + + def Deserialize(self, init): + ToP = init.get('teamOrPet', '') + if ToP == 'pet': + self.teamPetSelectPetRB.SetValue(True) + else: + self.teamPetSelectTeamRB.SetValue(True) + if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) + +####### Unselect +class UnselectCmd(PowerBindCmd): + def MakeBindString(self): + return 'unselect' + +####### Use Insp By Name +class UseInspByNameCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) + for _, types in GameData.Inspirations.items(): + for _, info in types.items(): + for insp in info['tiers']: + name = re.sub(' ', '', str(insp)) + icon = GetIcon(f'Inspirations/{name}') + self.useInspByNameModeChoice.Append(insp, icon) + self.useInspByNameModeChoice.SetSelection(0) + useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) + + return useInspByNameSizer + + def MakeBindString(self): + choice = self.useInspByNameModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "inspexecname " + mode.lower() + + def GetAllInsps(self): + Insplist = [] + for _, info in GameData.Inspirations.items(): + for insp in info['tiers']: + Insplist.append(insp) + Insplist.append("---") + Insplist.pop(-1) # snip the terminal "---" + + return Insplist + + def Serialize(self): + return { 'insp' : self.useInspByNameModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) + +####### Use Insp From Row / Column +class UseInspRowColCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnRow.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) + self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnCol.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) + + return useInspRowColumnSizer + + def MakeBindString(self): + row = self.useInspRowColumnRow.GetSelection()+1 + col = self.useInspRowColumnCol.GetSelection()+1 + + return f"inspexectray {col} {row}" + + def Serialize(self): + return { + 'col' : self.useInspRowColumnCol.GetSelection(), + 'row' : self.useInspRowColumnRow.GetSelection(), + } + + def Deserialize(self, init): + if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) + if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) + +####### Use Power +class UsePowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + outerSizer = wx.BoxSizer(wx.HORIZONTAL) + + usePowerSizer = wx.GridBagSizer(5,5) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBToggle, (0,1)) + self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOn, (0,2)) + self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOff, (0,3)) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerName = PowerPicker(dialog) + usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) + usePowerSizer.AddGrowableCol(3) + + outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) + + return outerSizer + + def MakeBindString(self): + if self.usePowerRBToggle.GetValue(): + method = "powexecname" + elif self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') + return '' + + return f"{method} {self.usePowerName.GetLabel()}" + + def Serialize(self): + if self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + method = "powexecname" + return { + 'method': method, + 'pname' : self.usePowerName.GetLabel(), + 'picon' : self.usePowerName.IconFilename + } + + def Deserialize(self, init): + method = init.get('method', '') + if method == 'powexectoggleon': + self.usePowerRBOn.SetValue(True) + elif method == 'powexectoggleoff': + self.usePowerRBOff.SetValue(True) + else: + self.usePowerRBToggle.SetValue(True) + if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) + +####### Use Power From Tray +class UsePowerFromTrayCmd(PowerBindCmd): + def BuildUI(self, dialog): + usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTrayTray = wx.Choice(dialog, -1, + choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', + 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) + self.usePowerFromTrayTray.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) + self.usePowerFromTraySlot.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return usePowerFromTraySizer + + def MakeBindString(self): + choice = self.usePowerFromTrayTray + tray = choice.GetSelection() + + choice = self.usePowerFromTraySlot + slot = choice.GetSelection()+1 + + mode = "slot" + mode2 = '' + if tray > 3: + mode = "tray" + mode2 = f" {tray - 3}" + elif tray == 3: + mode = "alt2slot" + elif tray == 2: + mode = "altslot" + + return f"powexec{mode} {slot}{mode2}" + + def Serialize(self): + return { + 'tray' : self.usePowerFromTrayTray.GetSelection(), + 'slot' : self.usePowerFromTraySlot.GetSelection(), + } + + def Deserialize(self, init): + if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) + if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) + +####### Window Color +class WindowColorCmd(PowerBindCmd): + def BuildUI(self, dialog): + windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) + borderSizer = wx.BoxSizer(wx.VERTICAL) + self.ColorBorder.SetSizer(borderSizer) + self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) + borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) + + windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) + + RGBASizer = wx.FlexGridSizer(3, 4, 5) + + RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) + self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) + self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + windowColorSizer.Add(RGBASizer) + + self.UpdateFromSlider() + + return windowColorSizer + + def MakeBindString(self): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + return f"windowcolor {Rval} {Gval} {Bval} {Aval}" + + def Serialize(self): + return { + 'Rval' : self.RSlider.GetValue(), + 'Gval' : self.GSlider.GetValue(), + 'Bval' : self.BSlider.GetValue(), + 'Aval' : self.ASlider.GetValue(), + } + + def Deserialize(self, init): + self.RSlider.SetValue(init['Rval']) + self.GSlider.SetValue(init['Gval']) + self.BSlider.SetValue(init['Bval']) + self.ASlider.SetValue(init['Aval']) + self.UpdateFromSlider() + + def UpdateFromSlider(self, _ = None): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RReadout.SetValue(Rval) + self.GReadout.SetValue(Gval) + self.BReadout.SetValue(Bval) + self.AReadout.SetValue(Aval) + self.ColorBorder.Refresh() + + def UpdateFromText(self, _ = None): + Rval = self.RReadout.GetValue() + Gval = self.GReadout.GetValue() + Bval = self.BReadout.GetValue() + Aval = self.AReadout.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RSlider.SetValue(Rval) + self.GSlider.SetValue(Gval) + self.BSlider.SetValue(Bval) + self.ASlider.SetValue(Aval) + self.ColorBorder.Refresh() + +####### Window Save / Load +class WindowSaveLoadCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) + self.CommandChoice.SetSelection(0) + sizer.Add(self.CommandChoice, 0, wx.ALL, 5) + + self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), + value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) + sizer.Add(self.FilePath, 0, wx.ALL, 5) + + return sizer + + def MakeBindString(self): + command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] + return f'{command} "{self.FilePath.GetValue()}"' + + def Serialize(self): + return { + 'command' : self.CommandChoice.GetSelection(), + 'filename' : self.FilePath.GetValue(), + } + + def Deserialize(self, init): + self.CommandChoice.SetSelection(init.get('command', 0)) + self.FilePath.SetValue(init.get('filename', '')) + +####### Window Toggle +class WindowToggleCmd(PowerBindCmd): + def BuildUI(self, dialog): + self.WindowNames = { + 'Actions' : 'actions', + 'Auction House' : 'ah', + 'Badge' : 'badge', + 'Channel Search' : 'chansearch', + 'Chat' : 'chat', + 'Custom Chat 1' : 'chat1', + 'Custom Chat 2' : 'chat2', + 'Custom Chat 3' : 'chat3', + 'Custom Chat 4' : 'chat4', + 'Clues' : 'clue', + 'Combat Numbers' : 'combatnumbers', + 'Contacts' : 'contact', + 'Contact Finder' : 'contactfinder', + 'Costumes' : 'costume', + 'Email' : 'email', + 'Enhancements' : 'enhancements', + 'Friends' : 'friend', + 'Group' : 'group', + 'Help' : 'helpwindow', + 'Incarnate' : 'incarnate', + 'Inspirations' : 'insp', + 'League' : 'league', + 'LFG' : 'lfg', + 'Map' : 'map', + 'Mission' : 'mission', + 'Nav / Compass' : 'nav', + 'Options' : 'options', + 'Pets' : 'pet', + 'Petition' : 'petition', + 'Power Tray' : 'powers', + 'Power List' : 'powerlist', + 'Quit' : 'quit', + 'Recipes' : 'recipe', + 'Salvage' : 'salvage', + 'Search' : 'search', + 'Supergroup' : 'sg', + 'Target' : 'target', + 'Team' : 'team', + 'Tray' : 'tray', + 'Tray1' : 'tray1', + 'Tray2' : 'tray2', + 'Tray3' : 'tray3', + 'Tray4' : 'tray4', + 'Tray5' : 'tray5', + 'Tray6' : 'tray6', + 'Tray7' : 'tray7', + 'Tray8' : 'tray8', + 'Vault' : 'vault', + } + + self.ShortToggleCommands = { + 'Auction House' : 'ah', + 'Chat' : 'chat', + 'Help' : 'helpwindow', + 'Map' : 'map', + 'Nav / Compass' : 'nav', + 'Power Tray' : 'powers', + 'Target' : 'target', + 'Tray' : 'tray', + } + + windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) + windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) + self.windowToggleTray.SetSelection(0) + windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.windowShowRB = wx.RadioButton(dialog, -1, "Show") + self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") + + windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) + + return windowToggleSizer + + def MakeBindString(self): + choice = self.windowToggleTray + index = choice.GetSelection() + windowdesc = choice.GetString(index) + windowname = self.WindowNames[windowdesc] + + if self.windowShowRB.GetValue(): + return 'show ' + windowname + elif self.windowHideRB.GetValue(): + return 'windowhide ' + windowname + else: + if shortcmd := self.ShortToggleCommands.get(windowdesc, None): + return shortcmd + else: + return 'toggle ' + windowname + + + def Serialize(self): + choice = self.windowToggleTray + if self.windowShowRB.GetValue(): + action = "Show" + elif self.windowHideRB.GetValue(): + action = "Hide" + else: + action = "Toggle" + return { + 'window': choice.GetString(choice.GetSelection()), + 'action': action, + } + + def Deserialize(self, init): + choice = self.windowToggleTray + if window := init.get('window', ''): + if isinstance(window, int): + choice.SetSelection(window) + else: + choice.SetSelection(choice.FindString(window)) + + if choice.GetSelection() == wx.NOT_FOUND: + choice.SetSelection(0) + + action = init.get('action', '') + if action == "Show": + self.windowShowRB.SetValue(True) + elif action == "Hide": + self.windowHideRB.SetValue(True) + else: + self.windowToggleRB.SetValue(True) + + +# Must always add to this list when adding a new command class above +menuStructure = { + 'Graphics / UI' : [ + 'Attribute Monitor', + 'Buff Display Settings', + 'Graphics Settings', + 'Window Color', + 'Window Save / Load', + 'Window Toggle', + ], + 'Inspirations' : [ + 'Use Inspiration By Name', + 'Use Inspiration From Row/Column', + ], + 'Powers' : [ + 'Auto Power', + 'Power Abort', + 'Power Unqueue', + 'Use Power', + 'Use Power From Tray', + ], + 'Social' : [ + 'Away From Keyboard', + 'Chat Command', + 'Chat Command (Global)', + 'Costume Change', + 'Emote', + 'Supergroup Mode', + ], + 'Targeting' : [ + 'Target Custom', + 'Target Enemy', + 'Target Frield', + 'Team/Pet Select', + 'Unselect', + ], + 'Misc' : [ + 'Load Binds Directory', + 'Movement Commands', + ], + # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, + # but I'm leaving it here to remind myself that we do that. + } + +# Must always add to this list when adding a new command class above +commandClasses = { + 'Auto Power' : AutoPowerCmd, + 'Away From Keyboard' : AFKCmd, + 'Attribute Monitor' : AttributeMonitorCmd, + 'Buff Display Settings' : BuffDisplayCmd, + 'Chat Command' : ChatCmd, + 'Chat Command (Global)' : ChatGlobalCmd, + 'Costume Change' : CostumeChangeCmd, + 'Custom Bind' : CustomBindCmd, + 'Emote' : EmoteCmd, + 'Graphics Settings' : GraphicsCmd, + 'Load Binds Directory' : LoadBindsDir, + 'Movement Commands' : MovementCmd, + 'Power Abort' : PowerAbortCmd, + 'Power Unqueue' : PowerUnqueueCmd, + 'Supergroup Mode' : SGModeCmd, + 'Target Custom' : TargetCustomCmd, + 'Target Enemy' : TargetEnemyCmd, + 'Target Friend' : TargetFriendCmd, + 'Team/Pet Select' : TeamPetSelectCmd, + 'Unselect' : UnselectCmd, + 'Use Inspiration By Name' : UseInspByNameCmd, + 'Use Inspiration From Row/Column' : UseInspRowColCmd, + 'Use Power' : UsePowerCmd, + 'Use Power From Tray' : UsePowerFromTrayCmd, + 'Window Color' : WindowColorCmd, + 'Window Save / Load' : WindowSaveLoadCmd, + 'Window Toggle' : WindowToggleCmd, +} +# use these when we rename a commandClass so that old Profiles will still load correctly. +# If we've also updated the class, we need to try to make sure the new class will still +# Deserialize the legacy data, or at least not crash. +deprecatedCommandClasses = { + 'SG Mode Toggle' : SGModeCmd, + 'Use Insp By Name' : UseInspByNameCmd, + 'Use Insp From Row/Column' : UseInspRowColCmd, +} +commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/BuffDisplayCmd.py b/UI/PowerBinderCommand/BuffDisplayCmd.py new file mode 100644 index 0000000..4c02ab7 --- /dev/null +++ b/UI/PowerBinderCommand/BuffDisplayCmd.py @@ -0,0 +1,1800 @@ +import wx +import re +import UI +import UI.EmotePicker +from UI.ControlGroup import ControlGroup +from UI.PowerPicker import PowerPicker +from Help import HelpButton +import wx.adv +from wx.adv import BitmapComboBox, EditableListBox +from pathlib import PureWindowsPath +import GameData +import Profile +from Icon import GetIcon + +class PowerBinderDialog(wx.Dialog): + def __init__(self, parent, button, init = {}): + wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) + + self.Page = parent.Page + self.EditDialog = PowerBinderEditDialog(self) + self.Button = button + self.AddStepMenu = self.makeAddStepMenu() + + sizer = wx.BoxSizer(wx.VERTICAL); + self.mainSizer = sizer + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) + # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) + # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) + #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) + AddStepButton = wx.Button(self, -1, 'Add Step') + AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) + AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) + choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) + choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) + sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) + + rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) + + self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) + self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) + self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) + rearrangeCtrl.Add(self.RearrangeList, 1) + + rearrangeButtons = wx.BoxSizer(wx.VERTICAL) + self.DelButton = wx.Button(self, -1, "Delete") + self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) + self.EditButton = wx.Button(self, -1, "Edit") + self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) + self.EditButton.Disable() + upButton = wx.Button(self, -1, "\u25B2") + upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) + downButton = wx.Button(self, -1, "\u25BC") + downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) + rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) + rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) + + sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.BindStringDisplay = wx.TextCtrl(self, -1) + self.BindStringDisplay.Disable() + choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, + wx.ALIGN_CENTER_VERTICAL) + choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) + + sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) + + sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) + + # need to dig around and get the OK button since we show this dialog modelessly now. + okButton = self.FindWindow(self.GetAffirmativeId()) + okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) + + # Wrap everything in a vbox to add some padding + vbox = wx.BoxSizer(wx.VERTICAL); + vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); + + self.SetSizerAndFit(vbox); + self.Layout() + self.Fit() + self.SetFocus() + + # if we are loading from profile, ie, have "init", build the list from it + if init: self.LoadFromData(init) + + def LoadFromData(self, init): + for item in init: + for type, data in item.items(): + commandClass = commandClasses.get(type, None) + if not commandClass: + commandClass = deprecatedCommandClasses.get(type, None) + if not commandClass: + wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") + continue + newCommand = commandClass(self.EditDialog, data) + index = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.SetClientData(index, newCommand) + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) + self.EditDialog.mainSizer.Hide(newCommand.UI) + self.UpdateBindStringDisplay() + + def SaveToData(self): + data = [] + index = 0 + for _ in self.RearrangeList.GetItems(): + # check whether we have an object already attached to this choice + cmdObject = self.RearrangeList.GetClientData(index) + commandClassName = commandRevClasses[type(cmdObject)] + data.append({commandClassName: cmdObject.Serialize()}) + index = index + 1 + return data + + def OnAddStepButton(self, evt): + button = evt.EventObject + if not self.AddStepMenu: + self.AddStepMenu = self.makeAddStepMenu() + button.PopupMenu(self.AddStepMenu) + + + def OnOKButton(self, _): + if self.Button.tgtTxtCtrl: + bindString = self.MakeBindString() + if bindString != self.Button.tgtTxtCtrl.GetValue(): + self.Button.tgtTxtCtrl.SetValue(bindString) + wx.App.Get().Main.Profile.SetModified() + self.Close() + + def OnRearrangeDelete(self, _): + current = self.RearrangeList.GetSelection() + if current == wx.NOT_FOUND: return + + self.RearrangeList.Delete(current) + self.UpdateBindStringDisplay() + + def OnRearrangeUp(self, _): + self.RearrangeList.MoveCurrentUp() + self.UpdateBindStringDisplay() + + def OnRearrangeDown(self, _): + self.RearrangeList.MoveCurrentDown() + self.UpdateBindStringDisplay() + + def OnRearrangeEdit(self, _): + index = self.RearrangeList.GetSelection() + + # check whether we have an object already attached to this choice + cmdObject = None + try: + cmdObject = self.RearrangeList.GetClientData(index) + except Exception: + pass + + if cmdObject: + self.ShowEditDialogFor(cmdObject) + self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) + else: + print("cmdObject was None") + self.UpdateBindStringDisplay() + + # OnAddStepMenu creates a new step and adds it to the rearrangelist + def OnAddStepMenu(self, evt): + menuitem = self.AddStepMenu.FindItemById(evt.GetId()) + chosenName = menuitem.GetItemLabel() + + # make a new command object, attached to the parent dialog + newCommandClass = commandClasses[chosenName] + newCommand = newCommandClass(self.EditDialog) + + # show the edit dialog if this command needs it + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) + if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): + self.EditDialog.mainSizer.Remove(newCommand.UI) + return + + newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.Select(newBindIndex) + self.RearrangeList.SetClientData(newBindIndex, newCommand) + + self.OnListSelect() + self.UpdateBindStringDisplay() + + def OnListSelect(self, _ = None): + selected = self.RearrangeList.GetSelection() + + if selected != wx.NOT_FOUND: + selCommand = self.RearrangeList.GetClientData(selected) + if selCommand.UI: + self.EditButton.Enable() + else: + self.EditButton.Disable() + + def UpdateBindStringDisplay(self): + self.BindStringDisplay.SetValue(self.MakeBindString()) + self.BindStringDisplay.SetToolTip(self.MakeBindString()) + + def MakeBindString(self): + cmdBindStrings = [] + for index in range(self.RearrangeList.GetCount()): + c = self.RearrangeList.GetClientData(index) + if c: cmdBindStrings.append(c.MakeBindString()) + + bindstring = ('$$'.join(cmdBindStrings)) + return bindstring + + def ShowEditDialogFor(self, command): + if not command.UI: return + + self.EditDialog.mainSizer.Show(command.UI) + + self.EditDialog.Layout() + self.EditDialog.Fit() + + self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') + returnval = self.EditDialog.ShowModal() + + self.EditDialog.mainSizer.Hide(command.UI) + + return returnval + + def makeAddStepMenu(self): + + stepMenu = wx.Menu() + + for subname in menuStructure: + submenu = wx.Menu() + stepMenu.AppendSubMenu(submenu, subname) + for classname in menuStructure[subname]: + submenu.Append(wx.ID_ANY, classname) + + stepMenu.Append(wx.ID_ANY, 'Custom Bind') + + return stepMenu + +class PowerBinderButton(wx.BitmapButton): + + def __init__(self, parent, tgtTxtCtrl, init = {}): + wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) + self.Init = init + self.Dialog = None + self.DialogParent = parent + + self.tgtTxtCtrl = tgtTxtCtrl + self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) + self.SetToolTip("Launch PowerBinder") + + def PowerBinderEventHandler(self, _): + self.PowerBinderDialog().Show() + + def LoadFromData(self, data): + self.PowerBinderDialog().LoadFromData(data) + + def SaveToData(self): + return self.PowerBinderDialog().SaveToData() + + def PowerBinderDialog(self): + if not self.Dialog: + self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) + return self.Dialog + + +class PowerBinderEditDialog(wx.Dialog): + def __init__(self, parent): + wx.Dialog.__init__(self, parent, -1, "Edit Step", + style = wx.DEFAULT_DIALOG_STYLE) + + outerSizer = wx.BoxSizer(wx.VERTICAL) + + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + self.mainSizer.SetMinSize([500, 150]) + + self.Page = parent.Page + + self.mainSizer.Add( + self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), + 0, wx.EXPAND|wx.ALL, 10) + + outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) + + self.SetSizerAndFit(outerSizer) + self.Layout() + self.Fit() + +########### Power Binder Command Objects +class PowerBindCmd(): + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + commandClassName = commandRevClasses[type(self)] + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{commandClassName} - {short_bindstr}" + + +####### Away From Keyboard +class AFKCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) + +####### Attribute Monitor +class AttributeMonitorCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.Groups = {} + self.AttributeTable = { + 'Base' : { + 'Current Hit Points' : 'NT H', + 'Max Hit Points' : 'X H', + 'Current Endurance' : 'T E', + 'Max Endurance' : 'X EN', + 'Regeneration Rate' : 'N RAT', + 'Recovery Rate' : 'Y RA', + 'Endurance Consumption' : 'SU', + 'ToHit Bonus' : 'T B', + 'Accuracy Bonus' : 'CC', + 'Last Hit Chance' : 'T C', + 'Damage Bonus' : 'DA', + 'Healing Bonus' : 'NG B', + 'Recharge Time Bonus' : 'ME B', + 'Endurance Discount' : 'CE DIS', + 'Stealth Radius (PvP)' : 'PVP', + 'Stealth Radius (PvE)' : 'PVE', + 'Perception Radius' : 'RC', + 'Range Bonus' : 'GE B', + 'Threat Level' : 'AT L', + 'Experience to Next Level' : 'XT', + 'Experience Debt' : 'XP', + 'Influence / Infamy' : 'INF', + 'Inherent' : 'NH', + }, + 'Movement Speed' : { + 'Flying Speed' : 'FL', + 'Jumping Speed' : 'PI', + 'Max Jump Height' : 'X J', + 'Run Speed' : 'RU', + }, + 'Damage Resistance' : { + 'Smashing Resistance' : 'G R', + 'Lethal Resistance' : 'L R', + 'Fire Resistance' : 'RE R', + 'Cold Resistance' : 'COLD R', + 'Energy Resistance' : 'DamageType[4]', + 'Negative Energy Resistance' : 'GY R', + 'Psyonic Resistance' : 'NIC R', + 'Toxic Resistance' : 'XIC R', + }, + 'Defense' : { + 'Base Defense' : 'BAS', + 'Ranged Defense' : 'ED', + 'Melee Defense' : 'MEL', + 'AoE Defense' : '2', + 'Smashing Defense' : '3', + 'Lethal Defense' : '4', + 'Fire Defense' : '5', + 'Cold Defense' : '6', + 'Energy Defense' : '7', + 'Negative Energy Defense' : '8', + 'Psionic Defense' : '9', + 'Toxic Defense' : '1', + }, + 'Debuff Resistance' : { + 'Regeneration Resistance' : 'ON R', + 'Recovery Resistance' : 'RY R', + 'To Hit Resistance' : 'IT R', + 'Defense Resistance' : 'NSE RES', + }, + 'Status Effect Protection' : { + 'Hold Protection' : 'D P', + 'Immobilize Protection' : 'LIZE P', + 'Stun Protection' : 'N P', + 'Sleep Protection' : 'P P', + 'Knockback Protection' : 'K P', + 'Confuse Protection' : 'SE P', + 'Terrorize Protection' : 'ZE P', + 'Repel Protection' : 'EL P', + 'Teleport Protection' : 'T P', + }, + 'Status Effect Resistance' : { + 'Hold Resistance' : 'D R', + 'Immobilize Resistance' : 'LIZE R', + 'Stun Resistance' : 'N R', + 'Sleep Resistance' : 'P R', + 'Knockback Resistance' : 'K R', + 'Confuse Resistance' : 'SE R', + 'Terrorize Resistance' : 'ZE R', + 'Placate Resistance' : 'TE R', + 'Taunt Resistance' : 'NT R', + }, + 'Miscellaneous' : { + 'Level Shift' : 'L S', + }, + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.AttributeMenu = wx.Menu() + for group, controls in self.AttributeTable.items(): + submenu = wx.Menu() + self.AttributeMenu.AppendSubMenu(submenu, group) + for cb in controls: + submenu.Append(wx.ID_ANY, cb) + + self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) + + self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) + groupSizer.Add(self.editbox) + + newButton = self.editbox.GetNewButton() + newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) + + return groupSizer + + def MakeBindString(self): + map = {} + bindstrings = [] + for _, controls in self.AttributeTable.items(): + for cb, data in controls.items(): + map[cb] = data + + for string in self.editbox.GetStrings(): + if string: + bindstrings.append(f'monitorattribute {map[string]}') + + return '$$'.join(bindstrings) + + def Serialize(self): + return { + 'attributes' : self.editbox.GetStrings() + } + + def Deserialize(self, init): + self.editbox.SetStrings(init.get('attributes', [])) + + def OnNewButton(self, evt): + evt.GetEventObject().PopupMenu(self.AttributeMenu) + + def OnMenuItem(self, evt): + menuitem = evt.EventObject.FindItemById(evt.GetId()) + existingstrings = self.editbox.GetStrings() + existingstrings.append(menuitem.GetItemLabel()) + self.editbox.SetStrings(existingstrings) + +####### Auto Power +class AutoPowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) + autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.autoPowerName = PowerPicker(dialog) + autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) + + return autoPowerSizer + + def MakeBindString(self): + return f"powexecauto {self.autoPowerName.GetLabel()}" + + def Serialize(self): + return { + 'pname' : self.autoPowerName.GetLabel(), + 'picon' : self.autoPowerName.IconFilename + } + + def Deserialize(self, init): + if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) + +####### Buff Display Command +class BuffDisplayCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.buffDisplayMap = { + 'Status Window' : { + 'Hide Auto' : 1, + 'Hide Toggles' : 2, + 'No Blinking' : 4, + 'No Stacking' : 8, + 'Numeric Stacking' : 16, + 'Hide Buff Numbers' : 32, + 'Stop Sending Buffs' : 64, + }, + 'Group Window' : { + 'Hide Auto' : 256, + 'Hide Toggles' : 512, + 'No Blinking' : 1024, + 'No Stacking' : 2048, + 'Numeric Stacking' : 4096, + 'Hide Buff Numbers' : 8192, + 'Stop Sending Buffs' : 16384, + }, + 'Pet Window' : { + 'Hide Auto' : 65536, + 'Hide Toggles' : 131072, + 'No Blinking' : 262144, + 'No Stacking' : 524288, + 'Numeric Stacking' : 1048576, + 'Hide Buff Numbers' : 2097152, + 'Stop Sending Buffs' : 4194304, + }, + } + self.Groups = {} + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + for group, controls in self.buffDisplayMap.items(): + self.Groups[group] = ControlGroup(dialog, self.Page, label = group) + groupid = self.Groups[group].GetStaticBox().GetId() + for cb, data in controls.items(): + self.Groups[group].AddControl( + ctlType = 'checkbox', + ctlName = f"{groupid}_{group}_{cb}", + label = cb, + data = data, + ) + + groupSizer.Add(self.Groups[group]) + + return groupSizer + + def CalculateValue(self): + page = wx.App.Get().Main.Profile.CustomBinds + + total = 0 + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] + if checkbox.IsChecked(): + total = total + checkbox.Data + return total + + def MakeBindString(self): + return f"optionset buffsettings {self.CalculateValue()}" + + def Serialize(self): + return { 'value' : self.CalculateValue() } + + def Deserialize(self, init): + value = init.get('value', 0) + + value = value or 0 # in case we had for some reason 'None' stashed in the init values + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] + checkbox.SetValue( checkbox.Data & value ) + +####### Chat Command +class ChatCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.chatChannelMap = { # before __init__ + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + chatCommandSizer = wx.GridBagSizer(5, 5) + self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") + chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) + # row 1 + self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) + self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) + self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) + # row 2 + self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) + self.chatCommandDuration.SetRange(1, 20) + self.chatCommandDuration.SetValue(7) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandDuration, (2,1)) + self.chatCommandChatSize = wx.Choice(dialog, -1, + choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) + self.chatCommandChatSize.SetSelection(5) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) + self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) + self.chatCommandChannel.SetSelection(0) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChannel, (2,5)) + # row 3 + self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") + chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) + self.chatCommandMessage = wx.TextCtrl(dialog, -1) + self.chatCommandMessage.SetHint('Chat Command Text') + chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) + + return chatCommandSizer + + def MakeBindString(self): + duration = self.chatCommandDuration.GetValue() + + choice = self.chatCommandChatSize + index = choice.GetSelection() + size = choice.GetString(index) + + duration = f"" if duration != 7 else "" + size = f"" if size != "1" else "" + + bdcolor = fgcolor = bgcolor = '' + if self.chatCommandUseColorsCB.IsChecked(): + bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + + bdcolor = f"" + fgcolor = f"" + bgcolor = f"" + + beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' + text = self.chatCommandMessage.GetValue() + + choice = self.chatCommandChannel + index = choice.GetSelection() + channel = choice.GetString(index) + + return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" + + def Serialize(self): + return { + 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), + 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), + 'channel' : self.chatCommandChannel .GetSelection(), + 'size' : self.chatCommandChatSize.GetSelection(), + 'duration' : self.chatCommandDuration.GetValue(), + 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'text' : self.chatCommandMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) + if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) + if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) + if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) + if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) + if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) + if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) + if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) + if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) + + +####### Chat Command Global +class ChatGlobalCmd(PowerBindCmd): + def BuildUI(self, dialog): + chatCommandGlobalSizer = wx.GridBagSizer(5,5) + + self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") + chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) + + self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalChannel.SetHint("Channel") + chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) + + self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') + chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) + + chatCommandGlobalSizer.AddGrowableCol(1) + + return chatCommandGlobalSizer + + def MakeBindString(self): + useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() + channel = self.chatCommandGlobalChannel.GetValue() + message = self.chatCommandGlobalMessage.GetValue() + + preface = "beginchat /" if useBeginchat else "" + + return f'{preface}send "{channel}" {message}' + + def Serialize(self): + return { + 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), + 'channel' : self.chatCommandGlobalChannel.GetValue(), + 'message' : self.chatCommandGlobalMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) + if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) + if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) + +#######Costume Change +class CostumeChangeCmd(PowerBindCmd): + def BuildUI(self, dialog): + costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeCostume = wx.Choice(dialog, -1, + choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) + self.costumeChangeCostume.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeEmote = wx.Choice(dialog, -1, + choices = GameData.Emotes['costumechange']) + self.costumeChangeEmote.Insert("- None -", 0) + self.costumeChangeEmote.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return costumeChangeSizer + + def MakeBindString(self): + costumeNumber = self.costumeChangeCostume.GetSelection() + costumeEmote = self.costumeChangeEmote.GetSelection() + + if costumeEmote: # None, or 0 == "- None -" + ccCmd = 'cce' + emoteName = self.costumeChangeEmote.GetString(costumeEmote) + emoteName = " CC" + emoteName.replace(" ","") + else: + ccCmd = 'cc' + emoteName = '' + + return f"{ccCmd} {costumeNumber}{emoteName}" + + def Serialize(self): + return{ + 'costumeNumber': self.costumeChangeCostume.GetSelection(), + 'costumeEmote' : self.costumeChangeEmote.GetSelection(), + } + + def Deserialize(self, init): + if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) + if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) + +####### Movement Command +class MovementCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + self.plusbutton.SetValue(True) + + self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.commandchoice = wx.Choice(dialog, choices = [ + "forward", "left", "right", "backward", "up", "down", + "turnleft", "turnright", "first", "autorun", "clicktomove", + ],) + sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) + self.commandchoice.SetSelection(0) + + self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + pre = post = '' + if self.plusbutton.GetValue() : pre = "+" + elif self.plusplusbutton.GetValue() : pre = "++" + elif self.minusbutton.GetValue() : pre = "-" + elif self.zerobutton.GetValue() : post = " 0" + elif self.onebutton.GetValue() : post = " 1" + + command = self.commandchoice.GetString(self.commandchoice.GetSelection()) + + return f"{pre}{command}{post}" + + def Serialize(self): + mod = '' + if self.plusbutton.GetValue() : mod = "plus" + elif self.plusplusbutton.GetValue() : mod = "plusplus" + elif self.minusbutton.GetValue() : mod = "minus" + elif self.zerobutton.GetValue() : mod = "zero" + elif self.onebutton.GetValue() : mod = "one" + + return { + 'mod' : mod, + 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), + } + + def Deserialize(self, init): + mod = init.get('mod', 'plus') + + if mod == 'plus' : self.plusbutton.SetValue(True) + elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) + elif mod == 'minus' : self.minusbutton.SetValue(True) + elif mod == 'zero' : self.zerobutton.SetValue(True) + elif mod == 'one' : self.onebutton.SetValue(True) + + self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) + +####### Graphics Command +class GraphicsCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.FlexGridSizer(2) + + self.visscalecb = wx.CheckBox(dialog, label = "visscale") + sizer.Add(self.visscalecb) + self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) + sizer.Add(self.visscalesc) + + self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") + sizer.Add(self.dofweightcb) + self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) + sizer.Add(self.dofweightsc) + + self.fsaacb = wx.CheckBox(dialog, label = "fsaa") + sizer.Add(self.fsaacb) + self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) + self.fsaach.SetSelection(0) + sizer.Add(self.fsaach) + + self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") + sizer.Add(self.bloomscalecb) + self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) + self.bloomscalech.SetSelection(0) + sizer.Add(self.bloomscalech) + + self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") + sizer.Add(self.bloomweightcb) + self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) + sizer.Add(self.bloomweightsc) + + self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") + sizer.Add(self.lodbiascb) + self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) + sizer.Add(self.lodbiassc) + + self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") + sizer.Add(self.renderscalecb) + self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) + sizer.Add(self.renderscalesc) + + return sizer + + def MakeBindString(self): + # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. + bindstrings = [] + if self.visscalecb.IsChecked(): + bindstrings.append("visscale " + str(self.visscalesc.GetValue())) + if self.dofweightcb.IsChecked(): + bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) + if self.fsaacb.IsChecked(): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bindstrings.append("fsaa " + fsaavalue) + if self.bloomscalecb.IsChecked(): + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + bindstrings.append("bloomscale " + bloomscalevalue) + if self.bloomweightcb.IsChecked(): + bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) + if self.lodbiascb.IsChecked(): + bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) + if self.renderscalecb.IsChecked(): + bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) + + return '$$'.join(bindstrings) + + def Serialize(self): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + return { + 'visscalecb' : self.visscalecb.IsChecked(), + 'visscalesc' : self.visscalesc.GetValue(), + 'dofweightcb' : self.dofweightcb.IsChecked(), + 'dofweightsc' : self.dofweightsc.GetValue(), + 'fsaacb' : self.fsaacb.IsChecked(), + 'fsaach' : fsaavalue, + 'bloomscalecb' : self.bloomscalecb.IsChecked(), + 'bloomscalech' : bloomscalevalue, + 'bloomweightcb' : self.bloomweightcb.IsChecked(), + 'bloomweightsc' : self.bloomweightsc.GetValue(), + 'lodbiascb' : self.lodbiascb.IsChecked(), + 'lodbiassc' : self.lodbiassc.GetValue(), + 'renderscalecb' : self.renderscalecb.IsChecked(), + 'renderscalesc' : self.renderscalesc.GetValue(), + } + + def Deserialize(self, init): + self.visscalecb.SetValue(init.get('visscalecb', False)) + self.visscalesc.SetValue(init.get('visscalesc', 1.0)) + self.dofweightcb.SetValue(init.get('dofweightcb', False)) + self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) + self.fsaacb.SetValue(init.get('fsaacb', False)) + self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) + self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) + self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) + self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) + self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) + self.lodbiascb.SetValue(init.get('lodbiascb', False)) + self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) + self.renderscalecb.SetValue(init.get('renderscalecb', False)) + self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) + +####### Custom Bind +class CustomBindCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.customBindName = wx.TextCtrl(dialog, -1) + self.customBindName.SetHint('Custom Bind Text') + sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + return self.customBindName.GetValue() + + def Serialize(self): + return { 'customBindName': self.customBindName.GetValue() } + + def Deserialize(self,init): + if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) + +####### Emote +class EmoteCmd(PowerBindCmd): + def BuildUI(self, dialog): + emoteSizer = wx.BoxSizer(wx.HORIZONTAL) + self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") + emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + self.emoteName = wx.Button(dialog, -1, "...") + self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) + emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) + + return emoteSizer + + def MakeBindString(self): + displayedEmoteName = self.emoteName.GetLabel() + actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] + + return actualEmotePayload + + def Serialize(self): + return {'emoteName': self.emoteName.GetLabel()} + + def Deserialize(self, init): + if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) + +####### Load Binds Directory +class LoadBindsDir(PowerBindCmd): + def BuildUI(self, dialog): + mainSizer = wx.BoxSizer(wx.VERTICAL) + + lbSizer = wx.BoxSizer(wx.HORIZONTAL) + lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") + lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + profiles = Profile.GetAllProfileBindsDirs() + + self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) + lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") + self.lbResetCB.SetValue(True) + + mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + return mainSizer + + def MakeBindString(self): + + # If the specified binds directory disappeared between runs, we'd crash, so handle that. + if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' + + config = wx.ConfigBase.Get() + if config.Exists('GameBindPath'): + bindpath = config.Read('GameBindPath') + else: + bindpath = config.Read('BindPath') + + reset = "" + if self.lbResetCB.GetValue(): + reset = "keybind_reset$$" + + resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' + return reset + 'bindloadfile ' + str(resetfilepath) + + def Serialize(self): + return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), + 'ResetKeybinds' : self.lbResetCB.GetValue(), + } + + def Deserialize(self, init): + if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) + self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) + +####### Power Abort +class PowerAbortCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecabort' + +####### Power Unqueue +class PowerUnqueueCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecunqueue' + +####### SG Mode +class SGModeCmd(PowerBindCmd): + def BuildUI(self, dialog): + sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) + sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") + self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") + + sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) + + return sgmodeSizer + + def MakeBindString(self): + if self.sgmodeOnRB.GetValue(): + return 'sgmodeset 1' + elif self.sgmodeOffRB.GetValue(): + return 'sgmodeset 0' + else: + return 'sgmode' + + def Serialize(self): + if self.sgmodeOnRB.GetValue(): + val = "On" + elif self.sgmodeOffRB.GetValue(): + val = "Off" + else: + val = "Toggle" + + return {"value" : val} + + def Deserialize(self, init): + val = init.get('value', '') + if val == "On": + self.sgmodeOnRB.SetValue(True) + elif val == "Off": + self.sgmodeOffRB.SetValue(True) + else: + self.sgmodeToggleRB.SetValue(True) + +####### Target Custom +class TargetCustomCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetCustomSizer = wx.GridBagSizer(5,5) + targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), + flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) + self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetCustomModeChoice.SetSelection(0) + targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) + self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) + self.targetCustomOptionalName.SetHint("Optional name to match") + targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) + self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") + targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) + self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") + targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) + self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") + targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) + self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") + targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) + self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") + targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) + self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") + targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) + self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") + targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) + self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") + targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) + + targetCustomSizer.AddGrowableCol(2) + + return targetCustomSizer + + def MakeBindString(self): + choice = self.targetCustomModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + targetCommand = "targetcustom" + mode.lower() + + enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" + friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" + defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" + alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" + mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" + notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" + base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" + notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" + + name = self.targetCustomOptionalName.GetValue() + + return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" + + def Serialize(self): + return { + 'mode' : self.targetCustomModeChoice.GetSelection(), + 'enemy' : self.targetCustomCBEnemies. IsChecked(), + 'friend' : self.targetCustomCBFriends. IsChecked(), + 'defeated' : self.targetCustomCBDefeated. IsChecked(), + 'alive' : self.targetCustomCBAlive. IsChecked(), + 'mypet' : self.targetCustomCBMyPets. IsChecked(), + 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), + 'base' : self.targetCustomCBBaseItems. IsChecked(), + 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), + 'name' : self.targetCustomOptionalName.GetValue(), + } + + def Deserialize(self, init): + if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) + if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) + if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) + if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) + if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) + if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) + if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) + if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) + if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) + if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) + + +####### Target Enemy +class TargetEnemyCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) + targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetEnemyModeChoice.SetSelection(0) + targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetEnemySizer + + def MakeBindString(self): + choice = self.targetEnemyModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetenemy" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetEnemyModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) + +####### Target Friend +class TargetFriendCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) + targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetFriendModeChoice.SetSelection(0) + targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetFriendSizer + + def MakeBindString(self): + choice = self.targetFriendModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetfriend" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetFriendModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) + +####### Team/Pet Select +class TeamPetSelectCmd(PowerBindCmd): + def BuildUI(self, dialog): + teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], + style=wx.ALIGN_CENTER_VERTICAL) + self.teamPetSelectNumber.SetSelection(0) + teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) + + return teamPetSelectSizer + + def MakeBindString(self): + teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' + targetNumber = self.teamPetSelectNumber.GetSelection()+1 + + return f"{teamOrPet}select {targetNumber}" + + def Serialize(self): + return { + 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', + 'targetNum': self.teamPetSelectNumber.GetSelection(), + } + + def Deserialize(self, init): + ToP = init.get('teamOrPet', '') + if ToP == 'pet': + self.teamPetSelectPetRB.SetValue(True) + else: + self.teamPetSelectTeamRB.SetValue(True) + if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) + +####### Unselect +class UnselectCmd(PowerBindCmd): + def MakeBindString(self): + return 'unselect' + +####### Use Insp By Name +class UseInspByNameCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) + for _, types in GameData.Inspirations.items(): + for _, info in types.items(): + for insp in info['tiers']: + name = re.sub(' ', '', str(insp)) + icon = GetIcon(f'Inspirations/{name}') + self.useInspByNameModeChoice.Append(insp, icon) + self.useInspByNameModeChoice.SetSelection(0) + useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) + + return useInspByNameSizer + + def MakeBindString(self): + choice = self.useInspByNameModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "inspexecname " + mode.lower() + + def GetAllInsps(self): + Insplist = [] + for _, info in GameData.Inspirations.items(): + for insp in info['tiers']: + Insplist.append(insp) + Insplist.append("---") + Insplist.pop(-1) # snip the terminal "---" + + return Insplist + + def Serialize(self): + return { 'insp' : self.useInspByNameModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) + +####### Use Insp From Row / Column +class UseInspRowColCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnRow.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) + self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnCol.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) + + return useInspRowColumnSizer + + def MakeBindString(self): + row = self.useInspRowColumnRow.GetSelection()+1 + col = self.useInspRowColumnCol.GetSelection()+1 + + return f"inspexectray {col} {row}" + + def Serialize(self): + return { + 'col' : self.useInspRowColumnCol.GetSelection(), + 'row' : self.useInspRowColumnRow.GetSelection(), + } + + def Deserialize(self, init): + if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) + if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) + +####### Use Power +class UsePowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + outerSizer = wx.BoxSizer(wx.HORIZONTAL) + + usePowerSizer = wx.GridBagSizer(5,5) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBToggle, (0,1)) + self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOn, (0,2)) + self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOff, (0,3)) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerName = PowerPicker(dialog) + usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) + usePowerSizer.AddGrowableCol(3) + + outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) + + return outerSizer + + def MakeBindString(self): + if self.usePowerRBToggle.GetValue(): + method = "powexecname" + elif self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') + return '' + + return f"{method} {self.usePowerName.GetLabel()}" + + def Serialize(self): + if self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + method = "powexecname" + return { + 'method': method, + 'pname' : self.usePowerName.GetLabel(), + 'picon' : self.usePowerName.IconFilename + } + + def Deserialize(self, init): + method = init.get('method', '') + if method == 'powexectoggleon': + self.usePowerRBOn.SetValue(True) + elif method == 'powexectoggleoff': + self.usePowerRBOff.SetValue(True) + else: + self.usePowerRBToggle.SetValue(True) + if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) + +####### Use Power From Tray +class UsePowerFromTrayCmd(PowerBindCmd): + def BuildUI(self, dialog): + usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTrayTray = wx.Choice(dialog, -1, + choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', + 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) + self.usePowerFromTrayTray.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) + self.usePowerFromTraySlot.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return usePowerFromTraySizer + + def MakeBindString(self): + choice = self.usePowerFromTrayTray + tray = choice.GetSelection() + + choice = self.usePowerFromTraySlot + slot = choice.GetSelection()+1 + + mode = "slot" + mode2 = '' + if tray > 3: + mode = "tray" + mode2 = f" {tray - 3}" + elif tray == 3: + mode = "alt2slot" + elif tray == 2: + mode = "altslot" + + return f"powexec{mode} {slot}{mode2}" + + def Serialize(self): + return { + 'tray' : self.usePowerFromTrayTray.GetSelection(), + 'slot' : self.usePowerFromTraySlot.GetSelection(), + } + + def Deserialize(self, init): + if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) + if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) + +####### Window Color +class WindowColorCmd(PowerBindCmd): + def BuildUI(self, dialog): + windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) + borderSizer = wx.BoxSizer(wx.VERTICAL) + self.ColorBorder.SetSizer(borderSizer) + self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) + borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) + + windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) + + RGBASizer = wx.FlexGridSizer(3, 4, 5) + + RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) + self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) + self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + windowColorSizer.Add(RGBASizer) + + self.UpdateFromSlider() + + return windowColorSizer + + def MakeBindString(self): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + return f"windowcolor {Rval} {Gval} {Bval} {Aval}" + + def Serialize(self): + return { + 'Rval' : self.RSlider.GetValue(), + 'Gval' : self.GSlider.GetValue(), + 'Bval' : self.BSlider.GetValue(), + 'Aval' : self.ASlider.GetValue(), + } + + def Deserialize(self, init): + self.RSlider.SetValue(init['Rval']) + self.GSlider.SetValue(init['Gval']) + self.BSlider.SetValue(init['Bval']) + self.ASlider.SetValue(init['Aval']) + self.UpdateFromSlider() + + def UpdateFromSlider(self, _ = None): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RReadout.SetValue(Rval) + self.GReadout.SetValue(Gval) + self.BReadout.SetValue(Bval) + self.AReadout.SetValue(Aval) + self.ColorBorder.Refresh() + + def UpdateFromText(self, _ = None): + Rval = self.RReadout.GetValue() + Gval = self.GReadout.GetValue() + Bval = self.BReadout.GetValue() + Aval = self.AReadout.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RSlider.SetValue(Rval) + self.GSlider.SetValue(Gval) + self.BSlider.SetValue(Bval) + self.ASlider.SetValue(Aval) + self.ColorBorder.Refresh() + +####### Window Save / Load +class WindowSaveLoadCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) + self.CommandChoice.SetSelection(0) + sizer.Add(self.CommandChoice, 0, wx.ALL, 5) + + self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), + value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) + sizer.Add(self.FilePath, 0, wx.ALL, 5) + + return sizer + + def MakeBindString(self): + command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] + return f'{command} "{self.FilePath.GetValue()}"' + + def Serialize(self): + return { + 'command' : self.CommandChoice.GetSelection(), + 'filename' : self.FilePath.GetValue(), + } + + def Deserialize(self, init): + self.CommandChoice.SetSelection(init.get('command', 0)) + self.FilePath.SetValue(init.get('filename', '')) + +####### Window Toggle +class WindowToggleCmd(PowerBindCmd): + def BuildUI(self, dialog): + self.WindowNames = { + 'Actions' : 'actions', + 'Auction House' : 'ah', + 'Badge' : 'badge', + 'Channel Search' : 'chansearch', + 'Chat' : 'chat', + 'Custom Chat 1' : 'chat1', + 'Custom Chat 2' : 'chat2', + 'Custom Chat 3' : 'chat3', + 'Custom Chat 4' : 'chat4', + 'Clues' : 'clue', + 'Combat Numbers' : 'combatnumbers', + 'Contacts' : 'contact', + 'Contact Finder' : 'contactfinder', + 'Costumes' : 'costume', + 'Email' : 'email', + 'Enhancements' : 'enhancements', + 'Friends' : 'friend', + 'Group' : 'group', + 'Help' : 'helpwindow', + 'Incarnate' : 'incarnate', + 'Inspirations' : 'insp', + 'League' : 'league', + 'LFG' : 'lfg', + 'Map' : 'map', + 'Mission' : 'mission', + 'Nav / Compass' : 'nav', + 'Options' : 'options', + 'Pets' : 'pet', + 'Petition' : 'petition', + 'Power Tray' : 'powers', + 'Power List' : 'powerlist', + 'Quit' : 'quit', + 'Recipes' : 'recipe', + 'Salvage' : 'salvage', + 'Search' : 'search', + 'Supergroup' : 'sg', + 'Target' : 'target', + 'Team' : 'team', + 'Tray' : 'tray', + 'Tray1' : 'tray1', + 'Tray2' : 'tray2', + 'Tray3' : 'tray3', + 'Tray4' : 'tray4', + 'Tray5' : 'tray5', + 'Tray6' : 'tray6', + 'Tray7' : 'tray7', + 'Tray8' : 'tray8', + 'Vault' : 'vault', + } + + self.ShortToggleCommands = { + 'Auction House' : 'ah', + 'Chat' : 'chat', + 'Help' : 'helpwindow', + 'Map' : 'map', + 'Nav / Compass' : 'nav', + 'Power Tray' : 'powers', + 'Target' : 'target', + 'Tray' : 'tray', + } + + windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) + windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) + self.windowToggleTray.SetSelection(0) + windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.windowShowRB = wx.RadioButton(dialog, -1, "Show") + self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") + + windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) + + return windowToggleSizer + + def MakeBindString(self): + choice = self.windowToggleTray + index = choice.GetSelection() + windowdesc = choice.GetString(index) + windowname = self.WindowNames[windowdesc] + + if self.windowShowRB.GetValue(): + return 'show ' + windowname + elif self.windowHideRB.GetValue(): + return 'windowhide ' + windowname + else: + if shortcmd := self.ShortToggleCommands.get(windowdesc, None): + return shortcmd + else: + return 'toggle ' + windowname + + + def Serialize(self): + choice = self.windowToggleTray + if self.windowShowRB.GetValue(): + action = "Show" + elif self.windowHideRB.GetValue(): + action = "Hide" + else: + action = "Toggle" + return { + 'window': choice.GetString(choice.GetSelection()), + 'action': action, + } + + def Deserialize(self, init): + choice = self.windowToggleTray + if window := init.get('window', ''): + if isinstance(window, int): + choice.SetSelection(window) + else: + choice.SetSelection(choice.FindString(window)) + + if choice.GetSelection() == wx.NOT_FOUND: + choice.SetSelection(0) + + action = init.get('action', '') + if action == "Show": + self.windowShowRB.SetValue(True) + elif action == "Hide": + self.windowHideRB.SetValue(True) + else: + self.windowToggleRB.SetValue(True) + + +# Must always add to this list when adding a new command class above +menuStructure = { + 'Graphics / UI' : [ + 'Attribute Monitor', + 'Buff Display Settings', + 'Graphics Settings', + 'Window Color', + 'Window Save / Load', + 'Window Toggle', + ], + 'Inspirations' : [ + 'Use Inspiration By Name', + 'Use Inspiration From Row/Column', + ], + 'Powers' : [ + 'Auto Power', + 'Power Abort', + 'Power Unqueue', + 'Use Power', + 'Use Power From Tray', + ], + 'Social' : [ + 'Away From Keyboard', + 'Chat Command', + 'Chat Command (Global)', + 'Costume Change', + 'Emote', + 'Supergroup Mode', + ], + 'Targeting' : [ + 'Target Custom', + 'Target Enemy', + 'Target Frield', + 'Team/Pet Select', + 'Unselect', + ], + 'Misc' : [ + 'Load Binds Directory', + 'Movement Commands', + ], + # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, + # but I'm leaving it here to remind myself that we do that. + } + +# Must always add to this list when adding a new command class above +commandClasses = { + 'Auto Power' : AutoPowerCmd, + 'Away From Keyboard' : AFKCmd, + 'Attribute Monitor' : AttributeMonitorCmd, + 'Buff Display Settings' : BuffDisplayCmd, + 'Chat Command' : ChatCmd, + 'Chat Command (Global)' : ChatGlobalCmd, + 'Costume Change' : CostumeChangeCmd, + 'Custom Bind' : CustomBindCmd, + 'Emote' : EmoteCmd, + 'Graphics Settings' : GraphicsCmd, + 'Load Binds Directory' : LoadBindsDir, + 'Movement Commands' : MovementCmd, + 'Power Abort' : PowerAbortCmd, + 'Power Unqueue' : PowerUnqueueCmd, + 'Supergroup Mode' : SGModeCmd, + 'Target Custom' : TargetCustomCmd, + 'Target Enemy' : TargetEnemyCmd, + 'Target Friend' : TargetFriendCmd, + 'Team/Pet Select' : TeamPetSelectCmd, + 'Unselect' : UnselectCmd, + 'Use Inspiration By Name' : UseInspByNameCmd, + 'Use Inspiration From Row/Column' : UseInspRowColCmd, + 'Use Power' : UsePowerCmd, + 'Use Power From Tray' : UsePowerFromTrayCmd, + 'Window Color' : WindowColorCmd, + 'Window Save / Load' : WindowSaveLoadCmd, + 'Window Toggle' : WindowToggleCmd, +} +# use these when we rename a commandClass so that old Profiles will still load correctly. +# If we've also updated the class, we need to try to make sure the new class will still +# Deserialize the legacy data, or at least not crash. +deprecatedCommandClasses = { + 'SG Mode Toggle' : SGModeCmd, + 'Use Insp By Name' : UseInspByNameCmd, + 'Use Insp From Row/Column' : UseInspRowColCmd, +} +commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/ChatCmd.py b/UI/PowerBinderCommand/ChatCmd.py new file mode 100644 index 0000000..4c02ab7 --- /dev/null +++ b/UI/PowerBinderCommand/ChatCmd.py @@ -0,0 +1,1800 @@ +import wx +import re +import UI +import UI.EmotePicker +from UI.ControlGroup import ControlGroup +from UI.PowerPicker import PowerPicker +from Help import HelpButton +import wx.adv +from wx.adv import BitmapComboBox, EditableListBox +from pathlib import PureWindowsPath +import GameData +import Profile +from Icon import GetIcon + +class PowerBinderDialog(wx.Dialog): + def __init__(self, parent, button, init = {}): + wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) + + self.Page = parent.Page + self.EditDialog = PowerBinderEditDialog(self) + self.Button = button + self.AddStepMenu = self.makeAddStepMenu() + + sizer = wx.BoxSizer(wx.VERTICAL); + self.mainSizer = sizer + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) + # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) + # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) + #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) + AddStepButton = wx.Button(self, -1, 'Add Step') + AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) + AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) + choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) + choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) + sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) + + rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) + + self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) + self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) + self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) + rearrangeCtrl.Add(self.RearrangeList, 1) + + rearrangeButtons = wx.BoxSizer(wx.VERTICAL) + self.DelButton = wx.Button(self, -1, "Delete") + self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) + self.EditButton = wx.Button(self, -1, "Edit") + self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) + self.EditButton.Disable() + upButton = wx.Button(self, -1, "\u25B2") + upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) + downButton = wx.Button(self, -1, "\u25BC") + downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) + rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) + rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) + + sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.BindStringDisplay = wx.TextCtrl(self, -1) + self.BindStringDisplay.Disable() + choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, + wx.ALIGN_CENTER_VERTICAL) + choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) + + sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) + + sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) + + # need to dig around and get the OK button since we show this dialog modelessly now. + okButton = self.FindWindow(self.GetAffirmativeId()) + okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) + + # Wrap everything in a vbox to add some padding + vbox = wx.BoxSizer(wx.VERTICAL); + vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); + + self.SetSizerAndFit(vbox); + self.Layout() + self.Fit() + self.SetFocus() + + # if we are loading from profile, ie, have "init", build the list from it + if init: self.LoadFromData(init) + + def LoadFromData(self, init): + for item in init: + for type, data in item.items(): + commandClass = commandClasses.get(type, None) + if not commandClass: + commandClass = deprecatedCommandClasses.get(type, None) + if not commandClass: + wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") + continue + newCommand = commandClass(self.EditDialog, data) + index = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.SetClientData(index, newCommand) + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) + self.EditDialog.mainSizer.Hide(newCommand.UI) + self.UpdateBindStringDisplay() + + def SaveToData(self): + data = [] + index = 0 + for _ in self.RearrangeList.GetItems(): + # check whether we have an object already attached to this choice + cmdObject = self.RearrangeList.GetClientData(index) + commandClassName = commandRevClasses[type(cmdObject)] + data.append({commandClassName: cmdObject.Serialize()}) + index = index + 1 + return data + + def OnAddStepButton(self, evt): + button = evt.EventObject + if not self.AddStepMenu: + self.AddStepMenu = self.makeAddStepMenu() + button.PopupMenu(self.AddStepMenu) + + + def OnOKButton(self, _): + if self.Button.tgtTxtCtrl: + bindString = self.MakeBindString() + if bindString != self.Button.tgtTxtCtrl.GetValue(): + self.Button.tgtTxtCtrl.SetValue(bindString) + wx.App.Get().Main.Profile.SetModified() + self.Close() + + def OnRearrangeDelete(self, _): + current = self.RearrangeList.GetSelection() + if current == wx.NOT_FOUND: return + + self.RearrangeList.Delete(current) + self.UpdateBindStringDisplay() + + def OnRearrangeUp(self, _): + self.RearrangeList.MoveCurrentUp() + self.UpdateBindStringDisplay() + + def OnRearrangeDown(self, _): + self.RearrangeList.MoveCurrentDown() + self.UpdateBindStringDisplay() + + def OnRearrangeEdit(self, _): + index = self.RearrangeList.GetSelection() + + # check whether we have an object already attached to this choice + cmdObject = None + try: + cmdObject = self.RearrangeList.GetClientData(index) + except Exception: + pass + + if cmdObject: + self.ShowEditDialogFor(cmdObject) + self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) + else: + print("cmdObject was None") + self.UpdateBindStringDisplay() + + # OnAddStepMenu creates a new step and adds it to the rearrangelist + def OnAddStepMenu(self, evt): + menuitem = self.AddStepMenu.FindItemById(evt.GetId()) + chosenName = menuitem.GetItemLabel() + + # make a new command object, attached to the parent dialog + newCommandClass = commandClasses[chosenName] + newCommand = newCommandClass(self.EditDialog) + + # show the edit dialog if this command needs it + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) + if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): + self.EditDialog.mainSizer.Remove(newCommand.UI) + return + + newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.Select(newBindIndex) + self.RearrangeList.SetClientData(newBindIndex, newCommand) + + self.OnListSelect() + self.UpdateBindStringDisplay() + + def OnListSelect(self, _ = None): + selected = self.RearrangeList.GetSelection() + + if selected != wx.NOT_FOUND: + selCommand = self.RearrangeList.GetClientData(selected) + if selCommand.UI: + self.EditButton.Enable() + else: + self.EditButton.Disable() + + def UpdateBindStringDisplay(self): + self.BindStringDisplay.SetValue(self.MakeBindString()) + self.BindStringDisplay.SetToolTip(self.MakeBindString()) + + def MakeBindString(self): + cmdBindStrings = [] + for index in range(self.RearrangeList.GetCount()): + c = self.RearrangeList.GetClientData(index) + if c: cmdBindStrings.append(c.MakeBindString()) + + bindstring = ('$$'.join(cmdBindStrings)) + return bindstring + + def ShowEditDialogFor(self, command): + if not command.UI: return + + self.EditDialog.mainSizer.Show(command.UI) + + self.EditDialog.Layout() + self.EditDialog.Fit() + + self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') + returnval = self.EditDialog.ShowModal() + + self.EditDialog.mainSizer.Hide(command.UI) + + return returnval + + def makeAddStepMenu(self): + + stepMenu = wx.Menu() + + for subname in menuStructure: + submenu = wx.Menu() + stepMenu.AppendSubMenu(submenu, subname) + for classname in menuStructure[subname]: + submenu.Append(wx.ID_ANY, classname) + + stepMenu.Append(wx.ID_ANY, 'Custom Bind') + + return stepMenu + +class PowerBinderButton(wx.BitmapButton): + + def __init__(self, parent, tgtTxtCtrl, init = {}): + wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) + self.Init = init + self.Dialog = None + self.DialogParent = parent + + self.tgtTxtCtrl = tgtTxtCtrl + self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) + self.SetToolTip("Launch PowerBinder") + + def PowerBinderEventHandler(self, _): + self.PowerBinderDialog().Show() + + def LoadFromData(self, data): + self.PowerBinderDialog().LoadFromData(data) + + def SaveToData(self): + return self.PowerBinderDialog().SaveToData() + + def PowerBinderDialog(self): + if not self.Dialog: + self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) + return self.Dialog + + +class PowerBinderEditDialog(wx.Dialog): + def __init__(self, parent): + wx.Dialog.__init__(self, parent, -1, "Edit Step", + style = wx.DEFAULT_DIALOG_STYLE) + + outerSizer = wx.BoxSizer(wx.VERTICAL) + + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + self.mainSizer.SetMinSize([500, 150]) + + self.Page = parent.Page + + self.mainSizer.Add( + self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), + 0, wx.EXPAND|wx.ALL, 10) + + outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) + + self.SetSizerAndFit(outerSizer) + self.Layout() + self.Fit() + +########### Power Binder Command Objects +class PowerBindCmd(): + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + commandClassName = commandRevClasses[type(self)] + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{commandClassName} - {short_bindstr}" + + +####### Away From Keyboard +class AFKCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) + +####### Attribute Monitor +class AttributeMonitorCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.Groups = {} + self.AttributeTable = { + 'Base' : { + 'Current Hit Points' : 'NT H', + 'Max Hit Points' : 'X H', + 'Current Endurance' : 'T E', + 'Max Endurance' : 'X EN', + 'Regeneration Rate' : 'N RAT', + 'Recovery Rate' : 'Y RA', + 'Endurance Consumption' : 'SU', + 'ToHit Bonus' : 'T B', + 'Accuracy Bonus' : 'CC', + 'Last Hit Chance' : 'T C', + 'Damage Bonus' : 'DA', + 'Healing Bonus' : 'NG B', + 'Recharge Time Bonus' : 'ME B', + 'Endurance Discount' : 'CE DIS', + 'Stealth Radius (PvP)' : 'PVP', + 'Stealth Radius (PvE)' : 'PVE', + 'Perception Radius' : 'RC', + 'Range Bonus' : 'GE B', + 'Threat Level' : 'AT L', + 'Experience to Next Level' : 'XT', + 'Experience Debt' : 'XP', + 'Influence / Infamy' : 'INF', + 'Inherent' : 'NH', + }, + 'Movement Speed' : { + 'Flying Speed' : 'FL', + 'Jumping Speed' : 'PI', + 'Max Jump Height' : 'X J', + 'Run Speed' : 'RU', + }, + 'Damage Resistance' : { + 'Smashing Resistance' : 'G R', + 'Lethal Resistance' : 'L R', + 'Fire Resistance' : 'RE R', + 'Cold Resistance' : 'COLD R', + 'Energy Resistance' : 'DamageType[4]', + 'Negative Energy Resistance' : 'GY R', + 'Psyonic Resistance' : 'NIC R', + 'Toxic Resistance' : 'XIC R', + }, + 'Defense' : { + 'Base Defense' : 'BAS', + 'Ranged Defense' : 'ED', + 'Melee Defense' : 'MEL', + 'AoE Defense' : '2', + 'Smashing Defense' : '3', + 'Lethal Defense' : '4', + 'Fire Defense' : '5', + 'Cold Defense' : '6', + 'Energy Defense' : '7', + 'Negative Energy Defense' : '8', + 'Psionic Defense' : '9', + 'Toxic Defense' : '1', + }, + 'Debuff Resistance' : { + 'Regeneration Resistance' : 'ON R', + 'Recovery Resistance' : 'RY R', + 'To Hit Resistance' : 'IT R', + 'Defense Resistance' : 'NSE RES', + }, + 'Status Effect Protection' : { + 'Hold Protection' : 'D P', + 'Immobilize Protection' : 'LIZE P', + 'Stun Protection' : 'N P', + 'Sleep Protection' : 'P P', + 'Knockback Protection' : 'K P', + 'Confuse Protection' : 'SE P', + 'Terrorize Protection' : 'ZE P', + 'Repel Protection' : 'EL P', + 'Teleport Protection' : 'T P', + }, + 'Status Effect Resistance' : { + 'Hold Resistance' : 'D R', + 'Immobilize Resistance' : 'LIZE R', + 'Stun Resistance' : 'N R', + 'Sleep Resistance' : 'P R', + 'Knockback Resistance' : 'K R', + 'Confuse Resistance' : 'SE R', + 'Terrorize Resistance' : 'ZE R', + 'Placate Resistance' : 'TE R', + 'Taunt Resistance' : 'NT R', + }, + 'Miscellaneous' : { + 'Level Shift' : 'L S', + }, + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.AttributeMenu = wx.Menu() + for group, controls in self.AttributeTable.items(): + submenu = wx.Menu() + self.AttributeMenu.AppendSubMenu(submenu, group) + for cb in controls: + submenu.Append(wx.ID_ANY, cb) + + self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) + + self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) + groupSizer.Add(self.editbox) + + newButton = self.editbox.GetNewButton() + newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) + + return groupSizer + + def MakeBindString(self): + map = {} + bindstrings = [] + for _, controls in self.AttributeTable.items(): + for cb, data in controls.items(): + map[cb] = data + + for string in self.editbox.GetStrings(): + if string: + bindstrings.append(f'monitorattribute {map[string]}') + + return '$$'.join(bindstrings) + + def Serialize(self): + return { + 'attributes' : self.editbox.GetStrings() + } + + def Deserialize(self, init): + self.editbox.SetStrings(init.get('attributes', [])) + + def OnNewButton(self, evt): + evt.GetEventObject().PopupMenu(self.AttributeMenu) + + def OnMenuItem(self, evt): + menuitem = evt.EventObject.FindItemById(evt.GetId()) + existingstrings = self.editbox.GetStrings() + existingstrings.append(menuitem.GetItemLabel()) + self.editbox.SetStrings(existingstrings) + +####### Auto Power +class AutoPowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) + autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.autoPowerName = PowerPicker(dialog) + autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) + + return autoPowerSizer + + def MakeBindString(self): + return f"powexecauto {self.autoPowerName.GetLabel()}" + + def Serialize(self): + return { + 'pname' : self.autoPowerName.GetLabel(), + 'picon' : self.autoPowerName.IconFilename + } + + def Deserialize(self, init): + if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) + +####### Buff Display Command +class BuffDisplayCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.buffDisplayMap = { + 'Status Window' : { + 'Hide Auto' : 1, + 'Hide Toggles' : 2, + 'No Blinking' : 4, + 'No Stacking' : 8, + 'Numeric Stacking' : 16, + 'Hide Buff Numbers' : 32, + 'Stop Sending Buffs' : 64, + }, + 'Group Window' : { + 'Hide Auto' : 256, + 'Hide Toggles' : 512, + 'No Blinking' : 1024, + 'No Stacking' : 2048, + 'Numeric Stacking' : 4096, + 'Hide Buff Numbers' : 8192, + 'Stop Sending Buffs' : 16384, + }, + 'Pet Window' : { + 'Hide Auto' : 65536, + 'Hide Toggles' : 131072, + 'No Blinking' : 262144, + 'No Stacking' : 524288, + 'Numeric Stacking' : 1048576, + 'Hide Buff Numbers' : 2097152, + 'Stop Sending Buffs' : 4194304, + }, + } + self.Groups = {} + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + for group, controls in self.buffDisplayMap.items(): + self.Groups[group] = ControlGroup(dialog, self.Page, label = group) + groupid = self.Groups[group].GetStaticBox().GetId() + for cb, data in controls.items(): + self.Groups[group].AddControl( + ctlType = 'checkbox', + ctlName = f"{groupid}_{group}_{cb}", + label = cb, + data = data, + ) + + groupSizer.Add(self.Groups[group]) + + return groupSizer + + def CalculateValue(self): + page = wx.App.Get().Main.Profile.CustomBinds + + total = 0 + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] + if checkbox.IsChecked(): + total = total + checkbox.Data + return total + + def MakeBindString(self): + return f"optionset buffsettings {self.CalculateValue()}" + + def Serialize(self): + return { 'value' : self.CalculateValue() } + + def Deserialize(self, init): + value = init.get('value', 0) + + value = value or 0 # in case we had for some reason 'None' stashed in the init values + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] + checkbox.SetValue( checkbox.Data & value ) + +####### Chat Command +class ChatCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.chatChannelMap = { # before __init__ + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + chatCommandSizer = wx.GridBagSizer(5, 5) + self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") + chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) + # row 1 + self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) + self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) + self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) + # row 2 + self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) + self.chatCommandDuration.SetRange(1, 20) + self.chatCommandDuration.SetValue(7) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandDuration, (2,1)) + self.chatCommandChatSize = wx.Choice(dialog, -1, + choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) + self.chatCommandChatSize.SetSelection(5) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) + self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) + self.chatCommandChannel.SetSelection(0) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChannel, (2,5)) + # row 3 + self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") + chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) + self.chatCommandMessage = wx.TextCtrl(dialog, -1) + self.chatCommandMessage.SetHint('Chat Command Text') + chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) + + return chatCommandSizer + + def MakeBindString(self): + duration = self.chatCommandDuration.GetValue() + + choice = self.chatCommandChatSize + index = choice.GetSelection() + size = choice.GetString(index) + + duration = f"" if duration != 7 else "" + size = f"" if size != "1" else "" + + bdcolor = fgcolor = bgcolor = '' + if self.chatCommandUseColorsCB.IsChecked(): + bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + + bdcolor = f"" + fgcolor = f"" + bgcolor = f"" + + beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' + text = self.chatCommandMessage.GetValue() + + choice = self.chatCommandChannel + index = choice.GetSelection() + channel = choice.GetString(index) + + return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" + + def Serialize(self): + return { + 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), + 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), + 'channel' : self.chatCommandChannel .GetSelection(), + 'size' : self.chatCommandChatSize.GetSelection(), + 'duration' : self.chatCommandDuration.GetValue(), + 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'text' : self.chatCommandMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) + if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) + if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) + if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) + if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) + if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) + if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) + if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) + if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) + + +####### Chat Command Global +class ChatGlobalCmd(PowerBindCmd): + def BuildUI(self, dialog): + chatCommandGlobalSizer = wx.GridBagSizer(5,5) + + self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") + chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) + + self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalChannel.SetHint("Channel") + chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) + + self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') + chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) + + chatCommandGlobalSizer.AddGrowableCol(1) + + return chatCommandGlobalSizer + + def MakeBindString(self): + useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() + channel = self.chatCommandGlobalChannel.GetValue() + message = self.chatCommandGlobalMessage.GetValue() + + preface = "beginchat /" if useBeginchat else "" + + return f'{preface}send "{channel}" {message}' + + def Serialize(self): + return { + 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), + 'channel' : self.chatCommandGlobalChannel.GetValue(), + 'message' : self.chatCommandGlobalMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) + if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) + if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) + +#######Costume Change +class CostumeChangeCmd(PowerBindCmd): + def BuildUI(self, dialog): + costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeCostume = wx.Choice(dialog, -1, + choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) + self.costumeChangeCostume.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeEmote = wx.Choice(dialog, -1, + choices = GameData.Emotes['costumechange']) + self.costumeChangeEmote.Insert("- None -", 0) + self.costumeChangeEmote.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return costumeChangeSizer + + def MakeBindString(self): + costumeNumber = self.costumeChangeCostume.GetSelection() + costumeEmote = self.costumeChangeEmote.GetSelection() + + if costumeEmote: # None, or 0 == "- None -" + ccCmd = 'cce' + emoteName = self.costumeChangeEmote.GetString(costumeEmote) + emoteName = " CC" + emoteName.replace(" ","") + else: + ccCmd = 'cc' + emoteName = '' + + return f"{ccCmd} {costumeNumber}{emoteName}" + + def Serialize(self): + return{ + 'costumeNumber': self.costumeChangeCostume.GetSelection(), + 'costumeEmote' : self.costumeChangeEmote.GetSelection(), + } + + def Deserialize(self, init): + if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) + if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) + +####### Movement Command +class MovementCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + self.plusbutton.SetValue(True) + + self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.commandchoice = wx.Choice(dialog, choices = [ + "forward", "left", "right", "backward", "up", "down", + "turnleft", "turnright", "first", "autorun", "clicktomove", + ],) + sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) + self.commandchoice.SetSelection(0) + + self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + pre = post = '' + if self.plusbutton.GetValue() : pre = "+" + elif self.plusplusbutton.GetValue() : pre = "++" + elif self.minusbutton.GetValue() : pre = "-" + elif self.zerobutton.GetValue() : post = " 0" + elif self.onebutton.GetValue() : post = " 1" + + command = self.commandchoice.GetString(self.commandchoice.GetSelection()) + + return f"{pre}{command}{post}" + + def Serialize(self): + mod = '' + if self.plusbutton.GetValue() : mod = "plus" + elif self.plusplusbutton.GetValue() : mod = "plusplus" + elif self.minusbutton.GetValue() : mod = "minus" + elif self.zerobutton.GetValue() : mod = "zero" + elif self.onebutton.GetValue() : mod = "one" + + return { + 'mod' : mod, + 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), + } + + def Deserialize(self, init): + mod = init.get('mod', 'plus') + + if mod == 'plus' : self.plusbutton.SetValue(True) + elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) + elif mod == 'minus' : self.minusbutton.SetValue(True) + elif mod == 'zero' : self.zerobutton.SetValue(True) + elif mod == 'one' : self.onebutton.SetValue(True) + + self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) + +####### Graphics Command +class GraphicsCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.FlexGridSizer(2) + + self.visscalecb = wx.CheckBox(dialog, label = "visscale") + sizer.Add(self.visscalecb) + self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) + sizer.Add(self.visscalesc) + + self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") + sizer.Add(self.dofweightcb) + self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) + sizer.Add(self.dofweightsc) + + self.fsaacb = wx.CheckBox(dialog, label = "fsaa") + sizer.Add(self.fsaacb) + self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) + self.fsaach.SetSelection(0) + sizer.Add(self.fsaach) + + self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") + sizer.Add(self.bloomscalecb) + self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) + self.bloomscalech.SetSelection(0) + sizer.Add(self.bloomscalech) + + self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") + sizer.Add(self.bloomweightcb) + self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) + sizer.Add(self.bloomweightsc) + + self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") + sizer.Add(self.lodbiascb) + self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) + sizer.Add(self.lodbiassc) + + self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") + sizer.Add(self.renderscalecb) + self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) + sizer.Add(self.renderscalesc) + + return sizer + + def MakeBindString(self): + # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. + bindstrings = [] + if self.visscalecb.IsChecked(): + bindstrings.append("visscale " + str(self.visscalesc.GetValue())) + if self.dofweightcb.IsChecked(): + bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) + if self.fsaacb.IsChecked(): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bindstrings.append("fsaa " + fsaavalue) + if self.bloomscalecb.IsChecked(): + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + bindstrings.append("bloomscale " + bloomscalevalue) + if self.bloomweightcb.IsChecked(): + bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) + if self.lodbiascb.IsChecked(): + bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) + if self.renderscalecb.IsChecked(): + bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) + + return '$$'.join(bindstrings) + + def Serialize(self): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + return { + 'visscalecb' : self.visscalecb.IsChecked(), + 'visscalesc' : self.visscalesc.GetValue(), + 'dofweightcb' : self.dofweightcb.IsChecked(), + 'dofweightsc' : self.dofweightsc.GetValue(), + 'fsaacb' : self.fsaacb.IsChecked(), + 'fsaach' : fsaavalue, + 'bloomscalecb' : self.bloomscalecb.IsChecked(), + 'bloomscalech' : bloomscalevalue, + 'bloomweightcb' : self.bloomweightcb.IsChecked(), + 'bloomweightsc' : self.bloomweightsc.GetValue(), + 'lodbiascb' : self.lodbiascb.IsChecked(), + 'lodbiassc' : self.lodbiassc.GetValue(), + 'renderscalecb' : self.renderscalecb.IsChecked(), + 'renderscalesc' : self.renderscalesc.GetValue(), + } + + def Deserialize(self, init): + self.visscalecb.SetValue(init.get('visscalecb', False)) + self.visscalesc.SetValue(init.get('visscalesc', 1.0)) + self.dofweightcb.SetValue(init.get('dofweightcb', False)) + self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) + self.fsaacb.SetValue(init.get('fsaacb', False)) + self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) + self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) + self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) + self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) + self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) + self.lodbiascb.SetValue(init.get('lodbiascb', False)) + self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) + self.renderscalecb.SetValue(init.get('renderscalecb', False)) + self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) + +####### Custom Bind +class CustomBindCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.customBindName = wx.TextCtrl(dialog, -1) + self.customBindName.SetHint('Custom Bind Text') + sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + return self.customBindName.GetValue() + + def Serialize(self): + return { 'customBindName': self.customBindName.GetValue() } + + def Deserialize(self,init): + if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) + +####### Emote +class EmoteCmd(PowerBindCmd): + def BuildUI(self, dialog): + emoteSizer = wx.BoxSizer(wx.HORIZONTAL) + self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") + emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + self.emoteName = wx.Button(dialog, -1, "...") + self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) + emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) + + return emoteSizer + + def MakeBindString(self): + displayedEmoteName = self.emoteName.GetLabel() + actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] + + return actualEmotePayload + + def Serialize(self): + return {'emoteName': self.emoteName.GetLabel()} + + def Deserialize(self, init): + if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) + +####### Load Binds Directory +class LoadBindsDir(PowerBindCmd): + def BuildUI(self, dialog): + mainSizer = wx.BoxSizer(wx.VERTICAL) + + lbSizer = wx.BoxSizer(wx.HORIZONTAL) + lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") + lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + profiles = Profile.GetAllProfileBindsDirs() + + self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) + lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") + self.lbResetCB.SetValue(True) + + mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + return mainSizer + + def MakeBindString(self): + + # If the specified binds directory disappeared between runs, we'd crash, so handle that. + if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' + + config = wx.ConfigBase.Get() + if config.Exists('GameBindPath'): + bindpath = config.Read('GameBindPath') + else: + bindpath = config.Read('BindPath') + + reset = "" + if self.lbResetCB.GetValue(): + reset = "keybind_reset$$" + + resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' + return reset + 'bindloadfile ' + str(resetfilepath) + + def Serialize(self): + return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), + 'ResetKeybinds' : self.lbResetCB.GetValue(), + } + + def Deserialize(self, init): + if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) + self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) + +####### Power Abort +class PowerAbortCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecabort' + +####### Power Unqueue +class PowerUnqueueCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecunqueue' + +####### SG Mode +class SGModeCmd(PowerBindCmd): + def BuildUI(self, dialog): + sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) + sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") + self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") + + sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) + + return sgmodeSizer + + def MakeBindString(self): + if self.sgmodeOnRB.GetValue(): + return 'sgmodeset 1' + elif self.sgmodeOffRB.GetValue(): + return 'sgmodeset 0' + else: + return 'sgmode' + + def Serialize(self): + if self.sgmodeOnRB.GetValue(): + val = "On" + elif self.sgmodeOffRB.GetValue(): + val = "Off" + else: + val = "Toggle" + + return {"value" : val} + + def Deserialize(self, init): + val = init.get('value', '') + if val == "On": + self.sgmodeOnRB.SetValue(True) + elif val == "Off": + self.sgmodeOffRB.SetValue(True) + else: + self.sgmodeToggleRB.SetValue(True) + +####### Target Custom +class TargetCustomCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetCustomSizer = wx.GridBagSizer(5,5) + targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), + flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) + self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetCustomModeChoice.SetSelection(0) + targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) + self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) + self.targetCustomOptionalName.SetHint("Optional name to match") + targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) + self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") + targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) + self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") + targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) + self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") + targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) + self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") + targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) + self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") + targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) + self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") + targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) + self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") + targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) + self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") + targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) + + targetCustomSizer.AddGrowableCol(2) + + return targetCustomSizer + + def MakeBindString(self): + choice = self.targetCustomModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + targetCommand = "targetcustom" + mode.lower() + + enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" + friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" + defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" + alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" + mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" + notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" + base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" + notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" + + name = self.targetCustomOptionalName.GetValue() + + return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" + + def Serialize(self): + return { + 'mode' : self.targetCustomModeChoice.GetSelection(), + 'enemy' : self.targetCustomCBEnemies. IsChecked(), + 'friend' : self.targetCustomCBFriends. IsChecked(), + 'defeated' : self.targetCustomCBDefeated. IsChecked(), + 'alive' : self.targetCustomCBAlive. IsChecked(), + 'mypet' : self.targetCustomCBMyPets. IsChecked(), + 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), + 'base' : self.targetCustomCBBaseItems. IsChecked(), + 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), + 'name' : self.targetCustomOptionalName.GetValue(), + } + + def Deserialize(self, init): + if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) + if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) + if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) + if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) + if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) + if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) + if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) + if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) + if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) + if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) + + +####### Target Enemy +class TargetEnemyCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) + targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetEnemyModeChoice.SetSelection(0) + targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetEnemySizer + + def MakeBindString(self): + choice = self.targetEnemyModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetenemy" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetEnemyModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) + +####### Target Friend +class TargetFriendCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) + targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetFriendModeChoice.SetSelection(0) + targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetFriendSizer + + def MakeBindString(self): + choice = self.targetFriendModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetfriend" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetFriendModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) + +####### Team/Pet Select +class TeamPetSelectCmd(PowerBindCmd): + def BuildUI(self, dialog): + teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], + style=wx.ALIGN_CENTER_VERTICAL) + self.teamPetSelectNumber.SetSelection(0) + teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) + + return teamPetSelectSizer + + def MakeBindString(self): + teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' + targetNumber = self.teamPetSelectNumber.GetSelection()+1 + + return f"{teamOrPet}select {targetNumber}" + + def Serialize(self): + return { + 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', + 'targetNum': self.teamPetSelectNumber.GetSelection(), + } + + def Deserialize(self, init): + ToP = init.get('teamOrPet', '') + if ToP == 'pet': + self.teamPetSelectPetRB.SetValue(True) + else: + self.teamPetSelectTeamRB.SetValue(True) + if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) + +####### Unselect +class UnselectCmd(PowerBindCmd): + def MakeBindString(self): + return 'unselect' + +####### Use Insp By Name +class UseInspByNameCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) + for _, types in GameData.Inspirations.items(): + for _, info in types.items(): + for insp in info['tiers']: + name = re.sub(' ', '', str(insp)) + icon = GetIcon(f'Inspirations/{name}') + self.useInspByNameModeChoice.Append(insp, icon) + self.useInspByNameModeChoice.SetSelection(0) + useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) + + return useInspByNameSizer + + def MakeBindString(self): + choice = self.useInspByNameModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "inspexecname " + mode.lower() + + def GetAllInsps(self): + Insplist = [] + for _, info in GameData.Inspirations.items(): + for insp in info['tiers']: + Insplist.append(insp) + Insplist.append("---") + Insplist.pop(-1) # snip the terminal "---" + + return Insplist + + def Serialize(self): + return { 'insp' : self.useInspByNameModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) + +####### Use Insp From Row / Column +class UseInspRowColCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnRow.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) + self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnCol.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) + + return useInspRowColumnSizer + + def MakeBindString(self): + row = self.useInspRowColumnRow.GetSelection()+1 + col = self.useInspRowColumnCol.GetSelection()+1 + + return f"inspexectray {col} {row}" + + def Serialize(self): + return { + 'col' : self.useInspRowColumnCol.GetSelection(), + 'row' : self.useInspRowColumnRow.GetSelection(), + } + + def Deserialize(self, init): + if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) + if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) + +####### Use Power +class UsePowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + outerSizer = wx.BoxSizer(wx.HORIZONTAL) + + usePowerSizer = wx.GridBagSizer(5,5) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBToggle, (0,1)) + self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOn, (0,2)) + self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOff, (0,3)) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerName = PowerPicker(dialog) + usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) + usePowerSizer.AddGrowableCol(3) + + outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) + + return outerSizer + + def MakeBindString(self): + if self.usePowerRBToggle.GetValue(): + method = "powexecname" + elif self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') + return '' + + return f"{method} {self.usePowerName.GetLabel()}" + + def Serialize(self): + if self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + method = "powexecname" + return { + 'method': method, + 'pname' : self.usePowerName.GetLabel(), + 'picon' : self.usePowerName.IconFilename + } + + def Deserialize(self, init): + method = init.get('method', '') + if method == 'powexectoggleon': + self.usePowerRBOn.SetValue(True) + elif method == 'powexectoggleoff': + self.usePowerRBOff.SetValue(True) + else: + self.usePowerRBToggle.SetValue(True) + if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) + +####### Use Power From Tray +class UsePowerFromTrayCmd(PowerBindCmd): + def BuildUI(self, dialog): + usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTrayTray = wx.Choice(dialog, -1, + choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', + 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) + self.usePowerFromTrayTray.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) + self.usePowerFromTraySlot.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return usePowerFromTraySizer + + def MakeBindString(self): + choice = self.usePowerFromTrayTray + tray = choice.GetSelection() + + choice = self.usePowerFromTraySlot + slot = choice.GetSelection()+1 + + mode = "slot" + mode2 = '' + if tray > 3: + mode = "tray" + mode2 = f" {tray - 3}" + elif tray == 3: + mode = "alt2slot" + elif tray == 2: + mode = "altslot" + + return f"powexec{mode} {slot}{mode2}" + + def Serialize(self): + return { + 'tray' : self.usePowerFromTrayTray.GetSelection(), + 'slot' : self.usePowerFromTraySlot.GetSelection(), + } + + def Deserialize(self, init): + if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) + if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) + +####### Window Color +class WindowColorCmd(PowerBindCmd): + def BuildUI(self, dialog): + windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) + borderSizer = wx.BoxSizer(wx.VERTICAL) + self.ColorBorder.SetSizer(borderSizer) + self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) + borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) + + windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) + + RGBASizer = wx.FlexGridSizer(3, 4, 5) + + RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) + self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) + self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + windowColorSizer.Add(RGBASizer) + + self.UpdateFromSlider() + + return windowColorSizer + + def MakeBindString(self): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + return f"windowcolor {Rval} {Gval} {Bval} {Aval}" + + def Serialize(self): + return { + 'Rval' : self.RSlider.GetValue(), + 'Gval' : self.GSlider.GetValue(), + 'Bval' : self.BSlider.GetValue(), + 'Aval' : self.ASlider.GetValue(), + } + + def Deserialize(self, init): + self.RSlider.SetValue(init['Rval']) + self.GSlider.SetValue(init['Gval']) + self.BSlider.SetValue(init['Bval']) + self.ASlider.SetValue(init['Aval']) + self.UpdateFromSlider() + + def UpdateFromSlider(self, _ = None): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RReadout.SetValue(Rval) + self.GReadout.SetValue(Gval) + self.BReadout.SetValue(Bval) + self.AReadout.SetValue(Aval) + self.ColorBorder.Refresh() + + def UpdateFromText(self, _ = None): + Rval = self.RReadout.GetValue() + Gval = self.GReadout.GetValue() + Bval = self.BReadout.GetValue() + Aval = self.AReadout.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RSlider.SetValue(Rval) + self.GSlider.SetValue(Gval) + self.BSlider.SetValue(Bval) + self.ASlider.SetValue(Aval) + self.ColorBorder.Refresh() + +####### Window Save / Load +class WindowSaveLoadCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) + self.CommandChoice.SetSelection(0) + sizer.Add(self.CommandChoice, 0, wx.ALL, 5) + + self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), + value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) + sizer.Add(self.FilePath, 0, wx.ALL, 5) + + return sizer + + def MakeBindString(self): + command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] + return f'{command} "{self.FilePath.GetValue()}"' + + def Serialize(self): + return { + 'command' : self.CommandChoice.GetSelection(), + 'filename' : self.FilePath.GetValue(), + } + + def Deserialize(self, init): + self.CommandChoice.SetSelection(init.get('command', 0)) + self.FilePath.SetValue(init.get('filename', '')) + +####### Window Toggle +class WindowToggleCmd(PowerBindCmd): + def BuildUI(self, dialog): + self.WindowNames = { + 'Actions' : 'actions', + 'Auction House' : 'ah', + 'Badge' : 'badge', + 'Channel Search' : 'chansearch', + 'Chat' : 'chat', + 'Custom Chat 1' : 'chat1', + 'Custom Chat 2' : 'chat2', + 'Custom Chat 3' : 'chat3', + 'Custom Chat 4' : 'chat4', + 'Clues' : 'clue', + 'Combat Numbers' : 'combatnumbers', + 'Contacts' : 'contact', + 'Contact Finder' : 'contactfinder', + 'Costumes' : 'costume', + 'Email' : 'email', + 'Enhancements' : 'enhancements', + 'Friends' : 'friend', + 'Group' : 'group', + 'Help' : 'helpwindow', + 'Incarnate' : 'incarnate', + 'Inspirations' : 'insp', + 'League' : 'league', + 'LFG' : 'lfg', + 'Map' : 'map', + 'Mission' : 'mission', + 'Nav / Compass' : 'nav', + 'Options' : 'options', + 'Pets' : 'pet', + 'Petition' : 'petition', + 'Power Tray' : 'powers', + 'Power List' : 'powerlist', + 'Quit' : 'quit', + 'Recipes' : 'recipe', + 'Salvage' : 'salvage', + 'Search' : 'search', + 'Supergroup' : 'sg', + 'Target' : 'target', + 'Team' : 'team', + 'Tray' : 'tray', + 'Tray1' : 'tray1', + 'Tray2' : 'tray2', + 'Tray3' : 'tray3', + 'Tray4' : 'tray4', + 'Tray5' : 'tray5', + 'Tray6' : 'tray6', + 'Tray7' : 'tray7', + 'Tray8' : 'tray8', + 'Vault' : 'vault', + } + + self.ShortToggleCommands = { + 'Auction House' : 'ah', + 'Chat' : 'chat', + 'Help' : 'helpwindow', + 'Map' : 'map', + 'Nav / Compass' : 'nav', + 'Power Tray' : 'powers', + 'Target' : 'target', + 'Tray' : 'tray', + } + + windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) + windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) + self.windowToggleTray.SetSelection(0) + windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.windowShowRB = wx.RadioButton(dialog, -1, "Show") + self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") + + windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) + + return windowToggleSizer + + def MakeBindString(self): + choice = self.windowToggleTray + index = choice.GetSelection() + windowdesc = choice.GetString(index) + windowname = self.WindowNames[windowdesc] + + if self.windowShowRB.GetValue(): + return 'show ' + windowname + elif self.windowHideRB.GetValue(): + return 'windowhide ' + windowname + else: + if shortcmd := self.ShortToggleCommands.get(windowdesc, None): + return shortcmd + else: + return 'toggle ' + windowname + + + def Serialize(self): + choice = self.windowToggleTray + if self.windowShowRB.GetValue(): + action = "Show" + elif self.windowHideRB.GetValue(): + action = "Hide" + else: + action = "Toggle" + return { + 'window': choice.GetString(choice.GetSelection()), + 'action': action, + } + + def Deserialize(self, init): + choice = self.windowToggleTray + if window := init.get('window', ''): + if isinstance(window, int): + choice.SetSelection(window) + else: + choice.SetSelection(choice.FindString(window)) + + if choice.GetSelection() == wx.NOT_FOUND: + choice.SetSelection(0) + + action = init.get('action', '') + if action == "Show": + self.windowShowRB.SetValue(True) + elif action == "Hide": + self.windowHideRB.SetValue(True) + else: + self.windowToggleRB.SetValue(True) + + +# Must always add to this list when adding a new command class above +menuStructure = { + 'Graphics / UI' : [ + 'Attribute Monitor', + 'Buff Display Settings', + 'Graphics Settings', + 'Window Color', + 'Window Save / Load', + 'Window Toggle', + ], + 'Inspirations' : [ + 'Use Inspiration By Name', + 'Use Inspiration From Row/Column', + ], + 'Powers' : [ + 'Auto Power', + 'Power Abort', + 'Power Unqueue', + 'Use Power', + 'Use Power From Tray', + ], + 'Social' : [ + 'Away From Keyboard', + 'Chat Command', + 'Chat Command (Global)', + 'Costume Change', + 'Emote', + 'Supergroup Mode', + ], + 'Targeting' : [ + 'Target Custom', + 'Target Enemy', + 'Target Frield', + 'Team/Pet Select', + 'Unselect', + ], + 'Misc' : [ + 'Load Binds Directory', + 'Movement Commands', + ], + # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, + # but I'm leaving it here to remind myself that we do that. + } + +# Must always add to this list when adding a new command class above +commandClasses = { + 'Auto Power' : AutoPowerCmd, + 'Away From Keyboard' : AFKCmd, + 'Attribute Monitor' : AttributeMonitorCmd, + 'Buff Display Settings' : BuffDisplayCmd, + 'Chat Command' : ChatCmd, + 'Chat Command (Global)' : ChatGlobalCmd, + 'Costume Change' : CostumeChangeCmd, + 'Custom Bind' : CustomBindCmd, + 'Emote' : EmoteCmd, + 'Graphics Settings' : GraphicsCmd, + 'Load Binds Directory' : LoadBindsDir, + 'Movement Commands' : MovementCmd, + 'Power Abort' : PowerAbortCmd, + 'Power Unqueue' : PowerUnqueueCmd, + 'Supergroup Mode' : SGModeCmd, + 'Target Custom' : TargetCustomCmd, + 'Target Enemy' : TargetEnemyCmd, + 'Target Friend' : TargetFriendCmd, + 'Team/Pet Select' : TeamPetSelectCmd, + 'Unselect' : UnselectCmd, + 'Use Inspiration By Name' : UseInspByNameCmd, + 'Use Inspiration From Row/Column' : UseInspRowColCmd, + 'Use Power' : UsePowerCmd, + 'Use Power From Tray' : UsePowerFromTrayCmd, + 'Window Color' : WindowColorCmd, + 'Window Save / Load' : WindowSaveLoadCmd, + 'Window Toggle' : WindowToggleCmd, +} +# use these when we rename a commandClass so that old Profiles will still load correctly. +# If we've also updated the class, we need to try to make sure the new class will still +# Deserialize the legacy data, or at least not crash. +deprecatedCommandClasses = { + 'SG Mode Toggle' : SGModeCmd, + 'Use Insp By Name' : UseInspByNameCmd, + 'Use Insp From Row/Column' : UseInspRowColCmd, +} +commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/ChatGlobalCmd.py b/UI/PowerBinderCommand/ChatGlobalCmd.py new file mode 100644 index 0000000..4c02ab7 --- /dev/null +++ b/UI/PowerBinderCommand/ChatGlobalCmd.py @@ -0,0 +1,1800 @@ +import wx +import re +import UI +import UI.EmotePicker +from UI.ControlGroup import ControlGroup +from UI.PowerPicker import PowerPicker +from Help import HelpButton +import wx.adv +from wx.adv import BitmapComboBox, EditableListBox +from pathlib import PureWindowsPath +import GameData +import Profile +from Icon import GetIcon + +class PowerBinderDialog(wx.Dialog): + def __init__(self, parent, button, init = {}): + wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) + + self.Page = parent.Page + self.EditDialog = PowerBinderEditDialog(self) + self.Button = button + self.AddStepMenu = self.makeAddStepMenu() + + sizer = wx.BoxSizer(wx.VERTICAL); + self.mainSizer = sizer + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) + # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) + # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) + #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) + AddStepButton = wx.Button(self, -1, 'Add Step') + AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) + AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) + choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) + choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) + sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) + + rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) + + self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) + self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) + self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) + rearrangeCtrl.Add(self.RearrangeList, 1) + + rearrangeButtons = wx.BoxSizer(wx.VERTICAL) + self.DelButton = wx.Button(self, -1, "Delete") + self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) + self.EditButton = wx.Button(self, -1, "Edit") + self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) + self.EditButton.Disable() + upButton = wx.Button(self, -1, "\u25B2") + upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) + downButton = wx.Button(self, -1, "\u25BC") + downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) + rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) + rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) + + sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.BindStringDisplay = wx.TextCtrl(self, -1) + self.BindStringDisplay.Disable() + choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, + wx.ALIGN_CENTER_VERTICAL) + choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) + + sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) + + sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) + + # need to dig around and get the OK button since we show this dialog modelessly now. + okButton = self.FindWindow(self.GetAffirmativeId()) + okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) + + # Wrap everything in a vbox to add some padding + vbox = wx.BoxSizer(wx.VERTICAL); + vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); + + self.SetSizerAndFit(vbox); + self.Layout() + self.Fit() + self.SetFocus() + + # if we are loading from profile, ie, have "init", build the list from it + if init: self.LoadFromData(init) + + def LoadFromData(self, init): + for item in init: + for type, data in item.items(): + commandClass = commandClasses.get(type, None) + if not commandClass: + commandClass = deprecatedCommandClasses.get(type, None) + if not commandClass: + wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") + continue + newCommand = commandClass(self.EditDialog, data) + index = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.SetClientData(index, newCommand) + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) + self.EditDialog.mainSizer.Hide(newCommand.UI) + self.UpdateBindStringDisplay() + + def SaveToData(self): + data = [] + index = 0 + for _ in self.RearrangeList.GetItems(): + # check whether we have an object already attached to this choice + cmdObject = self.RearrangeList.GetClientData(index) + commandClassName = commandRevClasses[type(cmdObject)] + data.append({commandClassName: cmdObject.Serialize()}) + index = index + 1 + return data + + def OnAddStepButton(self, evt): + button = evt.EventObject + if not self.AddStepMenu: + self.AddStepMenu = self.makeAddStepMenu() + button.PopupMenu(self.AddStepMenu) + + + def OnOKButton(self, _): + if self.Button.tgtTxtCtrl: + bindString = self.MakeBindString() + if bindString != self.Button.tgtTxtCtrl.GetValue(): + self.Button.tgtTxtCtrl.SetValue(bindString) + wx.App.Get().Main.Profile.SetModified() + self.Close() + + def OnRearrangeDelete(self, _): + current = self.RearrangeList.GetSelection() + if current == wx.NOT_FOUND: return + + self.RearrangeList.Delete(current) + self.UpdateBindStringDisplay() + + def OnRearrangeUp(self, _): + self.RearrangeList.MoveCurrentUp() + self.UpdateBindStringDisplay() + + def OnRearrangeDown(self, _): + self.RearrangeList.MoveCurrentDown() + self.UpdateBindStringDisplay() + + def OnRearrangeEdit(self, _): + index = self.RearrangeList.GetSelection() + + # check whether we have an object already attached to this choice + cmdObject = None + try: + cmdObject = self.RearrangeList.GetClientData(index) + except Exception: + pass + + if cmdObject: + self.ShowEditDialogFor(cmdObject) + self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) + else: + print("cmdObject was None") + self.UpdateBindStringDisplay() + + # OnAddStepMenu creates a new step and adds it to the rearrangelist + def OnAddStepMenu(self, evt): + menuitem = self.AddStepMenu.FindItemById(evt.GetId()) + chosenName = menuitem.GetItemLabel() + + # make a new command object, attached to the parent dialog + newCommandClass = commandClasses[chosenName] + newCommand = newCommandClass(self.EditDialog) + + # show the edit dialog if this command needs it + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) + if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): + self.EditDialog.mainSizer.Remove(newCommand.UI) + return + + newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.Select(newBindIndex) + self.RearrangeList.SetClientData(newBindIndex, newCommand) + + self.OnListSelect() + self.UpdateBindStringDisplay() + + def OnListSelect(self, _ = None): + selected = self.RearrangeList.GetSelection() + + if selected != wx.NOT_FOUND: + selCommand = self.RearrangeList.GetClientData(selected) + if selCommand.UI: + self.EditButton.Enable() + else: + self.EditButton.Disable() + + def UpdateBindStringDisplay(self): + self.BindStringDisplay.SetValue(self.MakeBindString()) + self.BindStringDisplay.SetToolTip(self.MakeBindString()) + + def MakeBindString(self): + cmdBindStrings = [] + for index in range(self.RearrangeList.GetCount()): + c = self.RearrangeList.GetClientData(index) + if c: cmdBindStrings.append(c.MakeBindString()) + + bindstring = ('$$'.join(cmdBindStrings)) + return bindstring + + def ShowEditDialogFor(self, command): + if not command.UI: return + + self.EditDialog.mainSizer.Show(command.UI) + + self.EditDialog.Layout() + self.EditDialog.Fit() + + self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') + returnval = self.EditDialog.ShowModal() + + self.EditDialog.mainSizer.Hide(command.UI) + + return returnval + + def makeAddStepMenu(self): + + stepMenu = wx.Menu() + + for subname in menuStructure: + submenu = wx.Menu() + stepMenu.AppendSubMenu(submenu, subname) + for classname in menuStructure[subname]: + submenu.Append(wx.ID_ANY, classname) + + stepMenu.Append(wx.ID_ANY, 'Custom Bind') + + return stepMenu + +class PowerBinderButton(wx.BitmapButton): + + def __init__(self, parent, tgtTxtCtrl, init = {}): + wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) + self.Init = init + self.Dialog = None + self.DialogParent = parent + + self.tgtTxtCtrl = tgtTxtCtrl + self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) + self.SetToolTip("Launch PowerBinder") + + def PowerBinderEventHandler(self, _): + self.PowerBinderDialog().Show() + + def LoadFromData(self, data): + self.PowerBinderDialog().LoadFromData(data) + + def SaveToData(self): + return self.PowerBinderDialog().SaveToData() + + def PowerBinderDialog(self): + if not self.Dialog: + self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) + return self.Dialog + + +class PowerBinderEditDialog(wx.Dialog): + def __init__(self, parent): + wx.Dialog.__init__(self, parent, -1, "Edit Step", + style = wx.DEFAULT_DIALOG_STYLE) + + outerSizer = wx.BoxSizer(wx.VERTICAL) + + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + self.mainSizer.SetMinSize([500, 150]) + + self.Page = parent.Page + + self.mainSizer.Add( + self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), + 0, wx.EXPAND|wx.ALL, 10) + + outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) + + self.SetSizerAndFit(outerSizer) + self.Layout() + self.Fit() + +########### Power Binder Command Objects +class PowerBindCmd(): + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + commandClassName = commandRevClasses[type(self)] + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{commandClassName} - {short_bindstr}" + + +####### Away From Keyboard +class AFKCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) + +####### Attribute Monitor +class AttributeMonitorCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.Groups = {} + self.AttributeTable = { + 'Base' : { + 'Current Hit Points' : 'NT H', + 'Max Hit Points' : 'X H', + 'Current Endurance' : 'T E', + 'Max Endurance' : 'X EN', + 'Regeneration Rate' : 'N RAT', + 'Recovery Rate' : 'Y RA', + 'Endurance Consumption' : 'SU', + 'ToHit Bonus' : 'T B', + 'Accuracy Bonus' : 'CC', + 'Last Hit Chance' : 'T C', + 'Damage Bonus' : 'DA', + 'Healing Bonus' : 'NG B', + 'Recharge Time Bonus' : 'ME B', + 'Endurance Discount' : 'CE DIS', + 'Stealth Radius (PvP)' : 'PVP', + 'Stealth Radius (PvE)' : 'PVE', + 'Perception Radius' : 'RC', + 'Range Bonus' : 'GE B', + 'Threat Level' : 'AT L', + 'Experience to Next Level' : 'XT', + 'Experience Debt' : 'XP', + 'Influence / Infamy' : 'INF', + 'Inherent' : 'NH', + }, + 'Movement Speed' : { + 'Flying Speed' : 'FL', + 'Jumping Speed' : 'PI', + 'Max Jump Height' : 'X J', + 'Run Speed' : 'RU', + }, + 'Damage Resistance' : { + 'Smashing Resistance' : 'G R', + 'Lethal Resistance' : 'L R', + 'Fire Resistance' : 'RE R', + 'Cold Resistance' : 'COLD R', + 'Energy Resistance' : 'DamageType[4]', + 'Negative Energy Resistance' : 'GY R', + 'Psyonic Resistance' : 'NIC R', + 'Toxic Resistance' : 'XIC R', + }, + 'Defense' : { + 'Base Defense' : 'BAS', + 'Ranged Defense' : 'ED', + 'Melee Defense' : 'MEL', + 'AoE Defense' : '2', + 'Smashing Defense' : '3', + 'Lethal Defense' : '4', + 'Fire Defense' : '5', + 'Cold Defense' : '6', + 'Energy Defense' : '7', + 'Negative Energy Defense' : '8', + 'Psionic Defense' : '9', + 'Toxic Defense' : '1', + }, + 'Debuff Resistance' : { + 'Regeneration Resistance' : 'ON R', + 'Recovery Resistance' : 'RY R', + 'To Hit Resistance' : 'IT R', + 'Defense Resistance' : 'NSE RES', + }, + 'Status Effect Protection' : { + 'Hold Protection' : 'D P', + 'Immobilize Protection' : 'LIZE P', + 'Stun Protection' : 'N P', + 'Sleep Protection' : 'P P', + 'Knockback Protection' : 'K P', + 'Confuse Protection' : 'SE P', + 'Terrorize Protection' : 'ZE P', + 'Repel Protection' : 'EL P', + 'Teleport Protection' : 'T P', + }, + 'Status Effect Resistance' : { + 'Hold Resistance' : 'D R', + 'Immobilize Resistance' : 'LIZE R', + 'Stun Resistance' : 'N R', + 'Sleep Resistance' : 'P R', + 'Knockback Resistance' : 'K R', + 'Confuse Resistance' : 'SE R', + 'Terrorize Resistance' : 'ZE R', + 'Placate Resistance' : 'TE R', + 'Taunt Resistance' : 'NT R', + }, + 'Miscellaneous' : { + 'Level Shift' : 'L S', + }, + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.AttributeMenu = wx.Menu() + for group, controls in self.AttributeTable.items(): + submenu = wx.Menu() + self.AttributeMenu.AppendSubMenu(submenu, group) + for cb in controls: + submenu.Append(wx.ID_ANY, cb) + + self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) + + self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) + groupSizer.Add(self.editbox) + + newButton = self.editbox.GetNewButton() + newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) + + return groupSizer + + def MakeBindString(self): + map = {} + bindstrings = [] + for _, controls in self.AttributeTable.items(): + for cb, data in controls.items(): + map[cb] = data + + for string in self.editbox.GetStrings(): + if string: + bindstrings.append(f'monitorattribute {map[string]}') + + return '$$'.join(bindstrings) + + def Serialize(self): + return { + 'attributes' : self.editbox.GetStrings() + } + + def Deserialize(self, init): + self.editbox.SetStrings(init.get('attributes', [])) + + def OnNewButton(self, evt): + evt.GetEventObject().PopupMenu(self.AttributeMenu) + + def OnMenuItem(self, evt): + menuitem = evt.EventObject.FindItemById(evt.GetId()) + existingstrings = self.editbox.GetStrings() + existingstrings.append(menuitem.GetItemLabel()) + self.editbox.SetStrings(existingstrings) + +####### Auto Power +class AutoPowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) + autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.autoPowerName = PowerPicker(dialog) + autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) + + return autoPowerSizer + + def MakeBindString(self): + return f"powexecauto {self.autoPowerName.GetLabel()}" + + def Serialize(self): + return { + 'pname' : self.autoPowerName.GetLabel(), + 'picon' : self.autoPowerName.IconFilename + } + + def Deserialize(self, init): + if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) + +####### Buff Display Command +class BuffDisplayCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.buffDisplayMap = { + 'Status Window' : { + 'Hide Auto' : 1, + 'Hide Toggles' : 2, + 'No Blinking' : 4, + 'No Stacking' : 8, + 'Numeric Stacking' : 16, + 'Hide Buff Numbers' : 32, + 'Stop Sending Buffs' : 64, + }, + 'Group Window' : { + 'Hide Auto' : 256, + 'Hide Toggles' : 512, + 'No Blinking' : 1024, + 'No Stacking' : 2048, + 'Numeric Stacking' : 4096, + 'Hide Buff Numbers' : 8192, + 'Stop Sending Buffs' : 16384, + }, + 'Pet Window' : { + 'Hide Auto' : 65536, + 'Hide Toggles' : 131072, + 'No Blinking' : 262144, + 'No Stacking' : 524288, + 'Numeric Stacking' : 1048576, + 'Hide Buff Numbers' : 2097152, + 'Stop Sending Buffs' : 4194304, + }, + } + self.Groups = {} + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + for group, controls in self.buffDisplayMap.items(): + self.Groups[group] = ControlGroup(dialog, self.Page, label = group) + groupid = self.Groups[group].GetStaticBox().GetId() + for cb, data in controls.items(): + self.Groups[group].AddControl( + ctlType = 'checkbox', + ctlName = f"{groupid}_{group}_{cb}", + label = cb, + data = data, + ) + + groupSizer.Add(self.Groups[group]) + + return groupSizer + + def CalculateValue(self): + page = wx.App.Get().Main.Profile.CustomBinds + + total = 0 + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] + if checkbox.IsChecked(): + total = total + checkbox.Data + return total + + def MakeBindString(self): + return f"optionset buffsettings {self.CalculateValue()}" + + def Serialize(self): + return { 'value' : self.CalculateValue() } + + def Deserialize(self, init): + value = init.get('value', 0) + + value = value or 0 # in case we had for some reason 'None' stashed in the init values + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] + checkbox.SetValue( checkbox.Data & value ) + +####### Chat Command +class ChatCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.chatChannelMap = { # before __init__ + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + chatCommandSizer = wx.GridBagSizer(5, 5) + self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") + chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) + # row 1 + self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) + self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) + self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) + # row 2 + self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) + self.chatCommandDuration.SetRange(1, 20) + self.chatCommandDuration.SetValue(7) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandDuration, (2,1)) + self.chatCommandChatSize = wx.Choice(dialog, -1, + choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) + self.chatCommandChatSize.SetSelection(5) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) + self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) + self.chatCommandChannel.SetSelection(0) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChannel, (2,5)) + # row 3 + self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") + chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) + self.chatCommandMessage = wx.TextCtrl(dialog, -1) + self.chatCommandMessage.SetHint('Chat Command Text') + chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) + + return chatCommandSizer + + def MakeBindString(self): + duration = self.chatCommandDuration.GetValue() + + choice = self.chatCommandChatSize + index = choice.GetSelection() + size = choice.GetString(index) + + duration = f"" if duration != 7 else "" + size = f"" if size != "1" else "" + + bdcolor = fgcolor = bgcolor = '' + if self.chatCommandUseColorsCB.IsChecked(): + bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + + bdcolor = f"" + fgcolor = f"" + bgcolor = f"" + + beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' + text = self.chatCommandMessage.GetValue() + + choice = self.chatCommandChannel + index = choice.GetSelection() + channel = choice.GetString(index) + + return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" + + def Serialize(self): + return { + 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), + 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), + 'channel' : self.chatCommandChannel .GetSelection(), + 'size' : self.chatCommandChatSize.GetSelection(), + 'duration' : self.chatCommandDuration.GetValue(), + 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'text' : self.chatCommandMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) + if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) + if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) + if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) + if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) + if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) + if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) + if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) + if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) + + +####### Chat Command Global +class ChatGlobalCmd(PowerBindCmd): + def BuildUI(self, dialog): + chatCommandGlobalSizer = wx.GridBagSizer(5,5) + + self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") + chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) + + self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalChannel.SetHint("Channel") + chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) + + self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') + chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) + + chatCommandGlobalSizer.AddGrowableCol(1) + + return chatCommandGlobalSizer + + def MakeBindString(self): + useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() + channel = self.chatCommandGlobalChannel.GetValue() + message = self.chatCommandGlobalMessage.GetValue() + + preface = "beginchat /" if useBeginchat else "" + + return f'{preface}send "{channel}" {message}' + + def Serialize(self): + return { + 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), + 'channel' : self.chatCommandGlobalChannel.GetValue(), + 'message' : self.chatCommandGlobalMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) + if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) + if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) + +#######Costume Change +class CostumeChangeCmd(PowerBindCmd): + def BuildUI(self, dialog): + costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeCostume = wx.Choice(dialog, -1, + choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) + self.costumeChangeCostume.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeEmote = wx.Choice(dialog, -1, + choices = GameData.Emotes['costumechange']) + self.costumeChangeEmote.Insert("- None -", 0) + self.costumeChangeEmote.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return costumeChangeSizer + + def MakeBindString(self): + costumeNumber = self.costumeChangeCostume.GetSelection() + costumeEmote = self.costumeChangeEmote.GetSelection() + + if costumeEmote: # None, or 0 == "- None -" + ccCmd = 'cce' + emoteName = self.costumeChangeEmote.GetString(costumeEmote) + emoteName = " CC" + emoteName.replace(" ","") + else: + ccCmd = 'cc' + emoteName = '' + + return f"{ccCmd} {costumeNumber}{emoteName}" + + def Serialize(self): + return{ + 'costumeNumber': self.costumeChangeCostume.GetSelection(), + 'costumeEmote' : self.costumeChangeEmote.GetSelection(), + } + + def Deserialize(self, init): + if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) + if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) + +####### Movement Command +class MovementCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + self.plusbutton.SetValue(True) + + self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.commandchoice = wx.Choice(dialog, choices = [ + "forward", "left", "right", "backward", "up", "down", + "turnleft", "turnright", "first", "autorun", "clicktomove", + ],) + sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) + self.commandchoice.SetSelection(0) + + self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + pre = post = '' + if self.plusbutton.GetValue() : pre = "+" + elif self.plusplusbutton.GetValue() : pre = "++" + elif self.minusbutton.GetValue() : pre = "-" + elif self.zerobutton.GetValue() : post = " 0" + elif self.onebutton.GetValue() : post = " 1" + + command = self.commandchoice.GetString(self.commandchoice.GetSelection()) + + return f"{pre}{command}{post}" + + def Serialize(self): + mod = '' + if self.plusbutton.GetValue() : mod = "plus" + elif self.plusplusbutton.GetValue() : mod = "plusplus" + elif self.minusbutton.GetValue() : mod = "minus" + elif self.zerobutton.GetValue() : mod = "zero" + elif self.onebutton.GetValue() : mod = "one" + + return { + 'mod' : mod, + 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), + } + + def Deserialize(self, init): + mod = init.get('mod', 'plus') + + if mod == 'plus' : self.plusbutton.SetValue(True) + elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) + elif mod == 'minus' : self.minusbutton.SetValue(True) + elif mod == 'zero' : self.zerobutton.SetValue(True) + elif mod == 'one' : self.onebutton.SetValue(True) + + self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) + +####### Graphics Command +class GraphicsCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.FlexGridSizer(2) + + self.visscalecb = wx.CheckBox(dialog, label = "visscale") + sizer.Add(self.visscalecb) + self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) + sizer.Add(self.visscalesc) + + self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") + sizer.Add(self.dofweightcb) + self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) + sizer.Add(self.dofweightsc) + + self.fsaacb = wx.CheckBox(dialog, label = "fsaa") + sizer.Add(self.fsaacb) + self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) + self.fsaach.SetSelection(0) + sizer.Add(self.fsaach) + + self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") + sizer.Add(self.bloomscalecb) + self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) + self.bloomscalech.SetSelection(0) + sizer.Add(self.bloomscalech) + + self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") + sizer.Add(self.bloomweightcb) + self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) + sizer.Add(self.bloomweightsc) + + self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") + sizer.Add(self.lodbiascb) + self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) + sizer.Add(self.lodbiassc) + + self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") + sizer.Add(self.renderscalecb) + self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) + sizer.Add(self.renderscalesc) + + return sizer + + def MakeBindString(self): + # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. + bindstrings = [] + if self.visscalecb.IsChecked(): + bindstrings.append("visscale " + str(self.visscalesc.GetValue())) + if self.dofweightcb.IsChecked(): + bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) + if self.fsaacb.IsChecked(): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bindstrings.append("fsaa " + fsaavalue) + if self.bloomscalecb.IsChecked(): + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + bindstrings.append("bloomscale " + bloomscalevalue) + if self.bloomweightcb.IsChecked(): + bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) + if self.lodbiascb.IsChecked(): + bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) + if self.renderscalecb.IsChecked(): + bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) + + return '$$'.join(bindstrings) + + def Serialize(self): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + return { + 'visscalecb' : self.visscalecb.IsChecked(), + 'visscalesc' : self.visscalesc.GetValue(), + 'dofweightcb' : self.dofweightcb.IsChecked(), + 'dofweightsc' : self.dofweightsc.GetValue(), + 'fsaacb' : self.fsaacb.IsChecked(), + 'fsaach' : fsaavalue, + 'bloomscalecb' : self.bloomscalecb.IsChecked(), + 'bloomscalech' : bloomscalevalue, + 'bloomweightcb' : self.bloomweightcb.IsChecked(), + 'bloomweightsc' : self.bloomweightsc.GetValue(), + 'lodbiascb' : self.lodbiascb.IsChecked(), + 'lodbiassc' : self.lodbiassc.GetValue(), + 'renderscalecb' : self.renderscalecb.IsChecked(), + 'renderscalesc' : self.renderscalesc.GetValue(), + } + + def Deserialize(self, init): + self.visscalecb.SetValue(init.get('visscalecb', False)) + self.visscalesc.SetValue(init.get('visscalesc', 1.0)) + self.dofweightcb.SetValue(init.get('dofweightcb', False)) + self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) + self.fsaacb.SetValue(init.get('fsaacb', False)) + self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) + self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) + self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) + self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) + self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) + self.lodbiascb.SetValue(init.get('lodbiascb', False)) + self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) + self.renderscalecb.SetValue(init.get('renderscalecb', False)) + self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) + +####### Custom Bind +class CustomBindCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.customBindName = wx.TextCtrl(dialog, -1) + self.customBindName.SetHint('Custom Bind Text') + sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + return self.customBindName.GetValue() + + def Serialize(self): + return { 'customBindName': self.customBindName.GetValue() } + + def Deserialize(self,init): + if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) + +####### Emote +class EmoteCmd(PowerBindCmd): + def BuildUI(self, dialog): + emoteSizer = wx.BoxSizer(wx.HORIZONTAL) + self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") + emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + self.emoteName = wx.Button(dialog, -1, "...") + self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) + emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) + + return emoteSizer + + def MakeBindString(self): + displayedEmoteName = self.emoteName.GetLabel() + actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] + + return actualEmotePayload + + def Serialize(self): + return {'emoteName': self.emoteName.GetLabel()} + + def Deserialize(self, init): + if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) + +####### Load Binds Directory +class LoadBindsDir(PowerBindCmd): + def BuildUI(self, dialog): + mainSizer = wx.BoxSizer(wx.VERTICAL) + + lbSizer = wx.BoxSizer(wx.HORIZONTAL) + lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") + lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + profiles = Profile.GetAllProfileBindsDirs() + + self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) + lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") + self.lbResetCB.SetValue(True) + + mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + return mainSizer + + def MakeBindString(self): + + # If the specified binds directory disappeared between runs, we'd crash, so handle that. + if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' + + config = wx.ConfigBase.Get() + if config.Exists('GameBindPath'): + bindpath = config.Read('GameBindPath') + else: + bindpath = config.Read('BindPath') + + reset = "" + if self.lbResetCB.GetValue(): + reset = "keybind_reset$$" + + resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' + return reset + 'bindloadfile ' + str(resetfilepath) + + def Serialize(self): + return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), + 'ResetKeybinds' : self.lbResetCB.GetValue(), + } + + def Deserialize(self, init): + if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) + self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) + +####### Power Abort +class PowerAbortCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecabort' + +####### Power Unqueue +class PowerUnqueueCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecunqueue' + +####### SG Mode +class SGModeCmd(PowerBindCmd): + def BuildUI(self, dialog): + sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) + sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") + self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") + + sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) + + return sgmodeSizer + + def MakeBindString(self): + if self.sgmodeOnRB.GetValue(): + return 'sgmodeset 1' + elif self.sgmodeOffRB.GetValue(): + return 'sgmodeset 0' + else: + return 'sgmode' + + def Serialize(self): + if self.sgmodeOnRB.GetValue(): + val = "On" + elif self.sgmodeOffRB.GetValue(): + val = "Off" + else: + val = "Toggle" + + return {"value" : val} + + def Deserialize(self, init): + val = init.get('value', '') + if val == "On": + self.sgmodeOnRB.SetValue(True) + elif val == "Off": + self.sgmodeOffRB.SetValue(True) + else: + self.sgmodeToggleRB.SetValue(True) + +####### Target Custom +class TargetCustomCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetCustomSizer = wx.GridBagSizer(5,5) + targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), + flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) + self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetCustomModeChoice.SetSelection(0) + targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) + self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) + self.targetCustomOptionalName.SetHint("Optional name to match") + targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) + self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") + targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) + self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") + targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) + self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") + targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) + self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") + targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) + self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") + targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) + self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") + targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) + self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") + targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) + self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") + targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) + + targetCustomSizer.AddGrowableCol(2) + + return targetCustomSizer + + def MakeBindString(self): + choice = self.targetCustomModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + targetCommand = "targetcustom" + mode.lower() + + enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" + friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" + defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" + alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" + mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" + notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" + base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" + notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" + + name = self.targetCustomOptionalName.GetValue() + + return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" + + def Serialize(self): + return { + 'mode' : self.targetCustomModeChoice.GetSelection(), + 'enemy' : self.targetCustomCBEnemies. IsChecked(), + 'friend' : self.targetCustomCBFriends. IsChecked(), + 'defeated' : self.targetCustomCBDefeated. IsChecked(), + 'alive' : self.targetCustomCBAlive. IsChecked(), + 'mypet' : self.targetCustomCBMyPets. IsChecked(), + 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), + 'base' : self.targetCustomCBBaseItems. IsChecked(), + 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), + 'name' : self.targetCustomOptionalName.GetValue(), + } + + def Deserialize(self, init): + if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) + if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) + if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) + if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) + if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) + if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) + if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) + if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) + if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) + if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) + + +####### Target Enemy +class TargetEnemyCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) + targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetEnemyModeChoice.SetSelection(0) + targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetEnemySizer + + def MakeBindString(self): + choice = self.targetEnemyModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetenemy" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetEnemyModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) + +####### Target Friend +class TargetFriendCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) + targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetFriendModeChoice.SetSelection(0) + targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetFriendSizer + + def MakeBindString(self): + choice = self.targetFriendModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetfriend" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetFriendModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) + +####### Team/Pet Select +class TeamPetSelectCmd(PowerBindCmd): + def BuildUI(self, dialog): + teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], + style=wx.ALIGN_CENTER_VERTICAL) + self.teamPetSelectNumber.SetSelection(0) + teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) + + return teamPetSelectSizer + + def MakeBindString(self): + teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' + targetNumber = self.teamPetSelectNumber.GetSelection()+1 + + return f"{teamOrPet}select {targetNumber}" + + def Serialize(self): + return { + 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', + 'targetNum': self.teamPetSelectNumber.GetSelection(), + } + + def Deserialize(self, init): + ToP = init.get('teamOrPet', '') + if ToP == 'pet': + self.teamPetSelectPetRB.SetValue(True) + else: + self.teamPetSelectTeamRB.SetValue(True) + if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) + +####### Unselect +class UnselectCmd(PowerBindCmd): + def MakeBindString(self): + return 'unselect' + +####### Use Insp By Name +class UseInspByNameCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) + for _, types in GameData.Inspirations.items(): + for _, info in types.items(): + for insp in info['tiers']: + name = re.sub(' ', '', str(insp)) + icon = GetIcon(f'Inspirations/{name}') + self.useInspByNameModeChoice.Append(insp, icon) + self.useInspByNameModeChoice.SetSelection(0) + useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) + + return useInspByNameSizer + + def MakeBindString(self): + choice = self.useInspByNameModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "inspexecname " + mode.lower() + + def GetAllInsps(self): + Insplist = [] + for _, info in GameData.Inspirations.items(): + for insp in info['tiers']: + Insplist.append(insp) + Insplist.append("---") + Insplist.pop(-1) # snip the terminal "---" + + return Insplist + + def Serialize(self): + return { 'insp' : self.useInspByNameModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) + +####### Use Insp From Row / Column +class UseInspRowColCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnRow.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) + self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnCol.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) + + return useInspRowColumnSizer + + def MakeBindString(self): + row = self.useInspRowColumnRow.GetSelection()+1 + col = self.useInspRowColumnCol.GetSelection()+1 + + return f"inspexectray {col} {row}" + + def Serialize(self): + return { + 'col' : self.useInspRowColumnCol.GetSelection(), + 'row' : self.useInspRowColumnRow.GetSelection(), + } + + def Deserialize(self, init): + if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) + if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) + +####### Use Power +class UsePowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + outerSizer = wx.BoxSizer(wx.HORIZONTAL) + + usePowerSizer = wx.GridBagSizer(5,5) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBToggle, (0,1)) + self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOn, (0,2)) + self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOff, (0,3)) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerName = PowerPicker(dialog) + usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) + usePowerSizer.AddGrowableCol(3) + + outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) + + return outerSizer + + def MakeBindString(self): + if self.usePowerRBToggle.GetValue(): + method = "powexecname" + elif self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') + return '' + + return f"{method} {self.usePowerName.GetLabel()}" + + def Serialize(self): + if self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + method = "powexecname" + return { + 'method': method, + 'pname' : self.usePowerName.GetLabel(), + 'picon' : self.usePowerName.IconFilename + } + + def Deserialize(self, init): + method = init.get('method', '') + if method == 'powexectoggleon': + self.usePowerRBOn.SetValue(True) + elif method == 'powexectoggleoff': + self.usePowerRBOff.SetValue(True) + else: + self.usePowerRBToggle.SetValue(True) + if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) + +####### Use Power From Tray +class UsePowerFromTrayCmd(PowerBindCmd): + def BuildUI(self, dialog): + usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTrayTray = wx.Choice(dialog, -1, + choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', + 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) + self.usePowerFromTrayTray.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) + self.usePowerFromTraySlot.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return usePowerFromTraySizer + + def MakeBindString(self): + choice = self.usePowerFromTrayTray + tray = choice.GetSelection() + + choice = self.usePowerFromTraySlot + slot = choice.GetSelection()+1 + + mode = "slot" + mode2 = '' + if tray > 3: + mode = "tray" + mode2 = f" {tray - 3}" + elif tray == 3: + mode = "alt2slot" + elif tray == 2: + mode = "altslot" + + return f"powexec{mode} {slot}{mode2}" + + def Serialize(self): + return { + 'tray' : self.usePowerFromTrayTray.GetSelection(), + 'slot' : self.usePowerFromTraySlot.GetSelection(), + } + + def Deserialize(self, init): + if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) + if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) + +####### Window Color +class WindowColorCmd(PowerBindCmd): + def BuildUI(self, dialog): + windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) + borderSizer = wx.BoxSizer(wx.VERTICAL) + self.ColorBorder.SetSizer(borderSizer) + self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) + borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) + + windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) + + RGBASizer = wx.FlexGridSizer(3, 4, 5) + + RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) + self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) + self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + windowColorSizer.Add(RGBASizer) + + self.UpdateFromSlider() + + return windowColorSizer + + def MakeBindString(self): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + return f"windowcolor {Rval} {Gval} {Bval} {Aval}" + + def Serialize(self): + return { + 'Rval' : self.RSlider.GetValue(), + 'Gval' : self.GSlider.GetValue(), + 'Bval' : self.BSlider.GetValue(), + 'Aval' : self.ASlider.GetValue(), + } + + def Deserialize(self, init): + self.RSlider.SetValue(init['Rval']) + self.GSlider.SetValue(init['Gval']) + self.BSlider.SetValue(init['Bval']) + self.ASlider.SetValue(init['Aval']) + self.UpdateFromSlider() + + def UpdateFromSlider(self, _ = None): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RReadout.SetValue(Rval) + self.GReadout.SetValue(Gval) + self.BReadout.SetValue(Bval) + self.AReadout.SetValue(Aval) + self.ColorBorder.Refresh() + + def UpdateFromText(self, _ = None): + Rval = self.RReadout.GetValue() + Gval = self.GReadout.GetValue() + Bval = self.BReadout.GetValue() + Aval = self.AReadout.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RSlider.SetValue(Rval) + self.GSlider.SetValue(Gval) + self.BSlider.SetValue(Bval) + self.ASlider.SetValue(Aval) + self.ColorBorder.Refresh() + +####### Window Save / Load +class WindowSaveLoadCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) + self.CommandChoice.SetSelection(0) + sizer.Add(self.CommandChoice, 0, wx.ALL, 5) + + self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), + value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) + sizer.Add(self.FilePath, 0, wx.ALL, 5) + + return sizer + + def MakeBindString(self): + command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] + return f'{command} "{self.FilePath.GetValue()}"' + + def Serialize(self): + return { + 'command' : self.CommandChoice.GetSelection(), + 'filename' : self.FilePath.GetValue(), + } + + def Deserialize(self, init): + self.CommandChoice.SetSelection(init.get('command', 0)) + self.FilePath.SetValue(init.get('filename', '')) + +####### Window Toggle +class WindowToggleCmd(PowerBindCmd): + def BuildUI(self, dialog): + self.WindowNames = { + 'Actions' : 'actions', + 'Auction House' : 'ah', + 'Badge' : 'badge', + 'Channel Search' : 'chansearch', + 'Chat' : 'chat', + 'Custom Chat 1' : 'chat1', + 'Custom Chat 2' : 'chat2', + 'Custom Chat 3' : 'chat3', + 'Custom Chat 4' : 'chat4', + 'Clues' : 'clue', + 'Combat Numbers' : 'combatnumbers', + 'Contacts' : 'contact', + 'Contact Finder' : 'contactfinder', + 'Costumes' : 'costume', + 'Email' : 'email', + 'Enhancements' : 'enhancements', + 'Friends' : 'friend', + 'Group' : 'group', + 'Help' : 'helpwindow', + 'Incarnate' : 'incarnate', + 'Inspirations' : 'insp', + 'League' : 'league', + 'LFG' : 'lfg', + 'Map' : 'map', + 'Mission' : 'mission', + 'Nav / Compass' : 'nav', + 'Options' : 'options', + 'Pets' : 'pet', + 'Petition' : 'petition', + 'Power Tray' : 'powers', + 'Power List' : 'powerlist', + 'Quit' : 'quit', + 'Recipes' : 'recipe', + 'Salvage' : 'salvage', + 'Search' : 'search', + 'Supergroup' : 'sg', + 'Target' : 'target', + 'Team' : 'team', + 'Tray' : 'tray', + 'Tray1' : 'tray1', + 'Tray2' : 'tray2', + 'Tray3' : 'tray3', + 'Tray4' : 'tray4', + 'Tray5' : 'tray5', + 'Tray6' : 'tray6', + 'Tray7' : 'tray7', + 'Tray8' : 'tray8', + 'Vault' : 'vault', + } + + self.ShortToggleCommands = { + 'Auction House' : 'ah', + 'Chat' : 'chat', + 'Help' : 'helpwindow', + 'Map' : 'map', + 'Nav / Compass' : 'nav', + 'Power Tray' : 'powers', + 'Target' : 'target', + 'Tray' : 'tray', + } + + windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) + windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) + self.windowToggleTray.SetSelection(0) + windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.windowShowRB = wx.RadioButton(dialog, -1, "Show") + self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") + + windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) + + return windowToggleSizer + + def MakeBindString(self): + choice = self.windowToggleTray + index = choice.GetSelection() + windowdesc = choice.GetString(index) + windowname = self.WindowNames[windowdesc] + + if self.windowShowRB.GetValue(): + return 'show ' + windowname + elif self.windowHideRB.GetValue(): + return 'windowhide ' + windowname + else: + if shortcmd := self.ShortToggleCommands.get(windowdesc, None): + return shortcmd + else: + return 'toggle ' + windowname + + + def Serialize(self): + choice = self.windowToggleTray + if self.windowShowRB.GetValue(): + action = "Show" + elif self.windowHideRB.GetValue(): + action = "Hide" + else: + action = "Toggle" + return { + 'window': choice.GetString(choice.GetSelection()), + 'action': action, + } + + def Deserialize(self, init): + choice = self.windowToggleTray + if window := init.get('window', ''): + if isinstance(window, int): + choice.SetSelection(window) + else: + choice.SetSelection(choice.FindString(window)) + + if choice.GetSelection() == wx.NOT_FOUND: + choice.SetSelection(0) + + action = init.get('action', '') + if action == "Show": + self.windowShowRB.SetValue(True) + elif action == "Hide": + self.windowHideRB.SetValue(True) + else: + self.windowToggleRB.SetValue(True) + + +# Must always add to this list when adding a new command class above +menuStructure = { + 'Graphics / UI' : [ + 'Attribute Monitor', + 'Buff Display Settings', + 'Graphics Settings', + 'Window Color', + 'Window Save / Load', + 'Window Toggle', + ], + 'Inspirations' : [ + 'Use Inspiration By Name', + 'Use Inspiration From Row/Column', + ], + 'Powers' : [ + 'Auto Power', + 'Power Abort', + 'Power Unqueue', + 'Use Power', + 'Use Power From Tray', + ], + 'Social' : [ + 'Away From Keyboard', + 'Chat Command', + 'Chat Command (Global)', + 'Costume Change', + 'Emote', + 'Supergroup Mode', + ], + 'Targeting' : [ + 'Target Custom', + 'Target Enemy', + 'Target Frield', + 'Team/Pet Select', + 'Unselect', + ], + 'Misc' : [ + 'Load Binds Directory', + 'Movement Commands', + ], + # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, + # but I'm leaving it here to remind myself that we do that. + } + +# Must always add to this list when adding a new command class above +commandClasses = { + 'Auto Power' : AutoPowerCmd, + 'Away From Keyboard' : AFKCmd, + 'Attribute Monitor' : AttributeMonitorCmd, + 'Buff Display Settings' : BuffDisplayCmd, + 'Chat Command' : ChatCmd, + 'Chat Command (Global)' : ChatGlobalCmd, + 'Costume Change' : CostumeChangeCmd, + 'Custom Bind' : CustomBindCmd, + 'Emote' : EmoteCmd, + 'Graphics Settings' : GraphicsCmd, + 'Load Binds Directory' : LoadBindsDir, + 'Movement Commands' : MovementCmd, + 'Power Abort' : PowerAbortCmd, + 'Power Unqueue' : PowerUnqueueCmd, + 'Supergroup Mode' : SGModeCmd, + 'Target Custom' : TargetCustomCmd, + 'Target Enemy' : TargetEnemyCmd, + 'Target Friend' : TargetFriendCmd, + 'Team/Pet Select' : TeamPetSelectCmd, + 'Unselect' : UnselectCmd, + 'Use Inspiration By Name' : UseInspByNameCmd, + 'Use Inspiration From Row/Column' : UseInspRowColCmd, + 'Use Power' : UsePowerCmd, + 'Use Power From Tray' : UsePowerFromTrayCmd, + 'Window Color' : WindowColorCmd, + 'Window Save / Load' : WindowSaveLoadCmd, + 'Window Toggle' : WindowToggleCmd, +} +# use these when we rename a commandClass so that old Profiles will still load correctly. +# If we've also updated the class, we need to try to make sure the new class will still +# Deserialize the legacy data, or at least not crash. +deprecatedCommandClasses = { + 'SG Mode Toggle' : SGModeCmd, + 'Use Insp By Name' : UseInspByNameCmd, + 'Use Insp From Row/Column' : UseInspRowColCmd, +} +commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/CostumeChangeCmd.py b/UI/PowerBinderCommand/CostumeChangeCmd.py new file mode 100644 index 0000000..4c02ab7 --- /dev/null +++ b/UI/PowerBinderCommand/CostumeChangeCmd.py @@ -0,0 +1,1800 @@ +import wx +import re +import UI +import UI.EmotePicker +from UI.ControlGroup import ControlGroup +from UI.PowerPicker import PowerPicker +from Help import HelpButton +import wx.adv +from wx.adv import BitmapComboBox, EditableListBox +from pathlib import PureWindowsPath +import GameData +import Profile +from Icon import GetIcon + +class PowerBinderDialog(wx.Dialog): + def __init__(self, parent, button, init = {}): + wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) + + self.Page = parent.Page + self.EditDialog = PowerBinderEditDialog(self) + self.Button = button + self.AddStepMenu = self.makeAddStepMenu() + + sizer = wx.BoxSizer(wx.VERTICAL); + self.mainSizer = sizer + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) + # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) + # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) + #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) + AddStepButton = wx.Button(self, -1, 'Add Step') + AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) + AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) + choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) + choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) + sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) + + rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) + + self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) + self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) + self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) + rearrangeCtrl.Add(self.RearrangeList, 1) + + rearrangeButtons = wx.BoxSizer(wx.VERTICAL) + self.DelButton = wx.Button(self, -1, "Delete") + self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) + self.EditButton = wx.Button(self, -1, "Edit") + self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) + self.EditButton.Disable() + upButton = wx.Button(self, -1, "\u25B2") + upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) + downButton = wx.Button(self, -1, "\u25BC") + downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) + rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) + rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) + + sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.BindStringDisplay = wx.TextCtrl(self, -1) + self.BindStringDisplay.Disable() + choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, + wx.ALIGN_CENTER_VERTICAL) + choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) + + sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) + + sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) + + # need to dig around and get the OK button since we show this dialog modelessly now. + okButton = self.FindWindow(self.GetAffirmativeId()) + okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) + + # Wrap everything in a vbox to add some padding + vbox = wx.BoxSizer(wx.VERTICAL); + vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); + + self.SetSizerAndFit(vbox); + self.Layout() + self.Fit() + self.SetFocus() + + # if we are loading from profile, ie, have "init", build the list from it + if init: self.LoadFromData(init) + + def LoadFromData(self, init): + for item in init: + for type, data in item.items(): + commandClass = commandClasses.get(type, None) + if not commandClass: + commandClass = deprecatedCommandClasses.get(type, None) + if not commandClass: + wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") + continue + newCommand = commandClass(self.EditDialog, data) + index = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.SetClientData(index, newCommand) + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) + self.EditDialog.mainSizer.Hide(newCommand.UI) + self.UpdateBindStringDisplay() + + def SaveToData(self): + data = [] + index = 0 + for _ in self.RearrangeList.GetItems(): + # check whether we have an object already attached to this choice + cmdObject = self.RearrangeList.GetClientData(index) + commandClassName = commandRevClasses[type(cmdObject)] + data.append({commandClassName: cmdObject.Serialize()}) + index = index + 1 + return data + + def OnAddStepButton(self, evt): + button = evt.EventObject + if not self.AddStepMenu: + self.AddStepMenu = self.makeAddStepMenu() + button.PopupMenu(self.AddStepMenu) + + + def OnOKButton(self, _): + if self.Button.tgtTxtCtrl: + bindString = self.MakeBindString() + if bindString != self.Button.tgtTxtCtrl.GetValue(): + self.Button.tgtTxtCtrl.SetValue(bindString) + wx.App.Get().Main.Profile.SetModified() + self.Close() + + def OnRearrangeDelete(self, _): + current = self.RearrangeList.GetSelection() + if current == wx.NOT_FOUND: return + + self.RearrangeList.Delete(current) + self.UpdateBindStringDisplay() + + def OnRearrangeUp(self, _): + self.RearrangeList.MoveCurrentUp() + self.UpdateBindStringDisplay() + + def OnRearrangeDown(self, _): + self.RearrangeList.MoveCurrentDown() + self.UpdateBindStringDisplay() + + def OnRearrangeEdit(self, _): + index = self.RearrangeList.GetSelection() + + # check whether we have an object already attached to this choice + cmdObject = None + try: + cmdObject = self.RearrangeList.GetClientData(index) + except Exception: + pass + + if cmdObject: + self.ShowEditDialogFor(cmdObject) + self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) + else: + print("cmdObject was None") + self.UpdateBindStringDisplay() + + # OnAddStepMenu creates a new step and adds it to the rearrangelist + def OnAddStepMenu(self, evt): + menuitem = self.AddStepMenu.FindItemById(evt.GetId()) + chosenName = menuitem.GetItemLabel() + + # make a new command object, attached to the parent dialog + newCommandClass = commandClasses[chosenName] + newCommand = newCommandClass(self.EditDialog) + + # show the edit dialog if this command needs it + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) + if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): + self.EditDialog.mainSizer.Remove(newCommand.UI) + return + + newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.Select(newBindIndex) + self.RearrangeList.SetClientData(newBindIndex, newCommand) + + self.OnListSelect() + self.UpdateBindStringDisplay() + + def OnListSelect(self, _ = None): + selected = self.RearrangeList.GetSelection() + + if selected != wx.NOT_FOUND: + selCommand = self.RearrangeList.GetClientData(selected) + if selCommand.UI: + self.EditButton.Enable() + else: + self.EditButton.Disable() + + def UpdateBindStringDisplay(self): + self.BindStringDisplay.SetValue(self.MakeBindString()) + self.BindStringDisplay.SetToolTip(self.MakeBindString()) + + def MakeBindString(self): + cmdBindStrings = [] + for index in range(self.RearrangeList.GetCount()): + c = self.RearrangeList.GetClientData(index) + if c: cmdBindStrings.append(c.MakeBindString()) + + bindstring = ('$$'.join(cmdBindStrings)) + return bindstring + + def ShowEditDialogFor(self, command): + if not command.UI: return + + self.EditDialog.mainSizer.Show(command.UI) + + self.EditDialog.Layout() + self.EditDialog.Fit() + + self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') + returnval = self.EditDialog.ShowModal() + + self.EditDialog.mainSizer.Hide(command.UI) + + return returnval + + def makeAddStepMenu(self): + + stepMenu = wx.Menu() + + for subname in menuStructure: + submenu = wx.Menu() + stepMenu.AppendSubMenu(submenu, subname) + for classname in menuStructure[subname]: + submenu.Append(wx.ID_ANY, classname) + + stepMenu.Append(wx.ID_ANY, 'Custom Bind') + + return stepMenu + +class PowerBinderButton(wx.BitmapButton): + + def __init__(self, parent, tgtTxtCtrl, init = {}): + wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) + self.Init = init + self.Dialog = None + self.DialogParent = parent + + self.tgtTxtCtrl = tgtTxtCtrl + self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) + self.SetToolTip("Launch PowerBinder") + + def PowerBinderEventHandler(self, _): + self.PowerBinderDialog().Show() + + def LoadFromData(self, data): + self.PowerBinderDialog().LoadFromData(data) + + def SaveToData(self): + return self.PowerBinderDialog().SaveToData() + + def PowerBinderDialog(self): + if not self.Dialog: + self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) + return self.Dialog + + +class PowerBinderEditDialog(wx.Dialog): + def __init__(self, parent): + wx.Dialog.__init__(self, parent, -1, "Edit Step", + style = wx.DEFAULT_DIALOG_STYLE) + + outerSizer = wx.BoxSizer(wx.VERTICAL) + + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + self.mainSizer.SetMinSize([500, 150]) + + self.Page = parent.Page + + self.mainSizer.Add( + self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), + 0, wx.EXPAND|wx.ALL, 10) + + outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) + + self.SetSizerAndFit(outerSizer) + self.Layout() + self.Fit() + +########### Power Binder Command Objects +class PowerBindCmd(): + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + commandClassName = commandRevClasses[type(self)] + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{commandClassName} - {short_bindstr}" + + +####### Away From Keyboard +class AFKCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) + +####### Attribute Monitor +class AttributeMonitorCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.Groups = {} + self.AttributeTable = { + 'Base' : { + 'Current Hit Points' : 'NT H', + 'Max Hit Points' : 'X H', + 'Current Endurance' : 'T E', + 'Max Endurance' : 'X EN', + 'Regeneration Rate' : 'N RAT', + 'Recovery Rate' : 'Y RA', + 'Endurance Consumption' : 'SU', + 'ToHit Bonus' : 'T B', + 'Accuracy Bonus' : 'CC', + 'Last Hit Chance' : 'T C', + 'Damage Bonus' : 'DA', + 'Healing Bonus' : 'NG B', + 'Recharge Time Bonus' : 'ME B', + 'Endurance Discount' : 'CE DIS', + 'Stealth Radius (PvP)' : 'PVP', + 'Stealth Radius (PvE)' : 'PVE', + 'Perception Radius' : 'RC', + 'Range Bonus' : 'GE B', + 'Threat Level' : 'AT L', + 'Experience to Next Level' : 'XT', + 'Experience Debt' : 'XP', + 'Influence / Infamy' : 'INF', + 'Inherent' : 'NH', + }, + 'Movement Speed' : { + 'Flying Speed' : 'FL', + 'Jumping Speed' : 'PI', + 'Max Jump Height' : 'X J', + 'Run Speed' : 'RU', + }, + 'Damage Resistance' : { + 'Smashing Resistance' : 'G R', + 'Lethal Resistance' : 'L R', + 'Fire Resistance' : 'RE R', + 'Cold Resistance' : 'COLD R', + 'Energy Resistance' : 'DamageType[4]', + 'Negative Energy Resistance' : 'GY R', + 'Psyonic Resistance' : 'NIC R', + 'Toxic Resistance' : 'XIC R', + }, + 'Defense' : { + 'Base Defense' : 'BAS', + 'Ranged Defense' : 'ED', + 'Melee Defense' : 'MEL', + 'AoE Defense' : '2', + 'Smashing Defense' : '3', + 'Lethal Defense' : '4', + 'Fire Defense' : '5', + 'Cold Defense' : '6', + 'Energy Defense' : '7', + 'Negative Energy Defense' : '8', + 'Psionic Defense' : '9', + 'Toxic Defense' : '1', + }, + 'Debuff Resistance' : { + 'Regeneration Resistance' : 'ON R', + 'Recovery Resistance' : 'RY R', + 'To Hit Resistance' : 'IT R', + 'Defense Resistance' : 'NSE RES', + }, + 'Status Effect Protection' : { + 'Hold Protection' : 'D P', + 'Immobilize Protection' : 'LIZE P', + 'Stun Protection' : 'N P', + 'Sleep Protection' : 'P P', + 'Knockback Protection' : 'K P', + 'Confuse Protection' : 'SE P', + 'Terrorize Protection' : 'ZE P', + 'Repel Protection' : 'EL P', + 'Teleport Protection' : 'T P', + }, + 'Status Effect Resistance' : { + 'Hold Resistance' : 'D R', + 'Immobilize Resistance' : 'LIZE R', + 'Stun Resistance' : 'N R', + 'Sleep Resistance' : 'P R', + 'Knockback Resistance' : 'K R', + 'Confuse Resistance' : 'SE R', + 'Terrorize Resistance' : 'ZE R', + 'Placate Resistance' : 'TE R', + 'Taunt Resistance' : 'NT R', + }, + 'Miscellaneous' : { + 'Level Shift' : 'L S', + }, + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.AttributeMenu = wx.Menu() + for group, controls in self.AttributeTable.items(): + submenu = wx.Menu() + self.AttributeMenu.AppendSubMenu(submenu, group) + for cb in controls: + submenu.Append(wx.ID_ANY, cb) + + self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) + + self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) + groupSizer.Add(self.editbox) + + newButton = self.editbox.GetNewButton() + newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) + + return groupSizer + + def MakeBindString(self): + map = {} + bindstrings = [] + for _, controls in self.AttributeTable.items(): + for cb, data in controls.items(): + map[cb] = data + + for string in self.editbox.GetStrings(): + if string: + bindstrings.append(f'monitorattribute {map[string]}') + + return '$$'.join(bindstrings) + + def Serialize(self): + return { + 'attributes' : self.editbox.GetStrings() + } + + def Deserialize(self, init): + self.editbox.SetStrings(init.get('attributes', [])) + + def OnNewButton(self, evt): + evt.GetEventObject().PopupMenu(self.AttributeMenu) + + def OnMenuItem(self, evt): + menuitem = evt.EventObject.FindItemById(evt.GetId()) + existingstrings = self.editbox.GetStrings() + existingstrings.append(menuitem.GetItemLabel()) + self.editbox.SetStrings(existingstrings) + +####### Auto Power +class AutoPowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) + autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.autoPowerName = PowerPicker(dialog) + autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) + + return autoPowerSizer + + def MakeBindString(self): + return f"powexecauto {self.autoPowerName.GetLabel()}" + + def Serialize(self): + return { + 'pname' : self.autoPowerName.GetLabel(), + 'picon' : self.autoPowerName.IconFilename + } + + def Deserialize(self, init): + if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) + +####### Buff Display Command +class BuffDisplayCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.buffDisplayMap = { + 'Status Window' : { + 'Hide Auto' : 1, + 'Hide Toggles' : 2, + 'No Blinking' : 4, + 'No Stacking' : 8, + 'Numeric Stacking' : 16, + 'Hide Buff Numbers' : 32, + 'Stop Sending Buffs' : 64, + }, + 'Group Window' : { + 'Hide Auto' : 256, + 'Hide Toggles' : 512, + 'No Blinking' : 1024, + 'No Stacking' : 2048, + 'Numeric Stacking' : 4096, + 'Hide Buff Numbers' : 8192, + 'Stop Sending Buffs' : 16384, + }, + 'Pet Window' : { + 'Hide Auto' : 65536, + 'Hide Toggles' : 131072, + 'No Blinking' : 262144, + 'No Stacking' : 524288, + 'Numeric Stacking' : 1048576, + 'Hide Buff Numbers' : 2097152, + 'Stop Sending Buffs' : 4194304, + }, + } + self.Groups = {} + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + for group, controls in self.buffDisplayMap.items(): + self.Groups[group] = ControlGroup(dialog, self.Page, label = group) + groupid = self.Groups[group].GetStaticBox().GetId() + for cb, data in controls.items(): + self.Groups[group].AddControl( + ctlType = 'checkbox', + ctlName = f"{groupid}_{group}_{cb}", + label = cb, + data = data, + ) + + groupSizer.Add(self.Groups[group]) + + return groupSizer + + def CalculateValue(self): + page = wx.App.Get().Main.Profile.CustomBinds + + total = 0 + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] + if checkbox.IsChecked(): + total = total + checkbox.Data + return total + + def MakeBindString(self): + return f"optionset buffsettings {self.CalculateValue()}" + + def Serialize(self): + return { 'value' : self.CalculateValue() } + + def Deserialize(self, init): + value = init.get('value', 0) + + value = value or 0 # in case we had for some reason 'None' stashed in the init values + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] + checkbox.SetValue( checkbox.Data & value ) + +####### Chat Command +class ChatCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.chatChannelMap = { # before __init__ + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + chatCommandSizer = wx.GridBagSizer(5, 5) + self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") + chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) + # row 1 + self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) + self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) + self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) + # row 2 + self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) + self.chatCommandDuration.SetRange(1, 20) + self.chatCommandDuration.SetValue(7) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandDuration, (2,1)) + self.chatCommandChatSize = wx.Choice(dialog, -1, + choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) + self.chatCommandChatSize.SetSelection(5) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) + self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) + self.chatCommandChannel.SetSelection(0) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChannel, (2,5)) + # row 3 + self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") + chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) + self.chatCommandMessage = wx.TextCtrl(dialog, -1) + self.chatCommandMessage.SetHint('Chat Command Text') + chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) + + return chatCommandSizer + + def MakeBindString(self): + duration = self.chatCommandDuration.GetValue() + + choice = self.chatCommandChatSize + index = choice.GetSelection() + size = choice.GetString(index) + + duration = f"" if duration != 7 else "" + size = f"" if size != "1" else "" + + bdcolor = fgcolor = bgcolor = '' + if self.chatCommandUseColorsCB.IsChecked(): + bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + + bdcolor = f"" + fgcolor = f"" + bgcolor = f"" + + beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' + text = self.chatCommandMessage.GetValue() + + choice = self.chatCommandChannel + index = choice.GetSelection() + channel = choice.GetString(index) + + return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" + + def Serialize(self): + return { + 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), + 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), + 'channel' : self.chatCommandChannel .GetSelection(), + 'size' : self.chatCommandChatSize.GetSelection(), + 'duration' : self.chatCommandDuration.GetValue(), + 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'text' : self.chatCommandMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) + if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) + if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) + if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) + if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) + if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) + if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) + if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) + if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) + + +####### Chat Command Global +class ChatGlobalCmd(PowerBindCmd): + def BuildUI(self, dialog): + chatCommandGlobalSizer = wx.GridBagSizer(5,5) + + self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") + chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) + + self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalChannel.SetHint("Channel") + chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) + + self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') + chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) + + chatCommandGlobalSizer.AddGrowableCol(1) + + return chatCommandGlobalSizer + + def MakeBindString(self): + useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() + channel = self.chatCommandGlobalChannel.GetValue() + message = self.chatCommandGlobalMessage.GetValue() + + preface = "beginchat /" if useBeginchat else "" + + return f'{preface}send "{channel}" {message}' + + def Serialize(self): + return { + 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), + 'channel' : self.chatCommandGlobalChannel.GetValue(), + 'message' : self.chatCommandGlobalMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) + if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) + if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) + +#######Costume Change +class CostumeChangeCmd(PowerBindCmd): + def BuildUI(self, dialog): + costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeCostume = wx.Choice(dialog, -1, + choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) + self.costumeChangeCostume.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeEmote = wx.Choice(dialog, -1, + choices = GameData.Emotes['costumechange']) + self.costumeChangeEmote.Insert("- None -", 0) + self.costumeChangeEmote.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return costumeChangeSizer + + def MakeBindString(self): + costumeNumber = self.costumeChangeCostume.GetSelection() + costumeEmote = self.costumeChangeEmote.GetSelection() + + if costumeEmote: # None, or 0 == "- None -" + ccCmd = 'cce' + emoteName = self.costumeChangeEmote.GetString(costumeEmote) + emoteName = " CC" + emoteName.replace(" ","") + else: + ccCmd = 'cc' + emoteName = '' + + return f"{ccCmd} {costumeNumber}{emoteName}" + + def Serialize(self): + return{ + 'costumeNumber': self.costumeChangeCostume.GetSelection(), + 'costumeEmote' : self.costumeChangeEmote.GetSelection(), + } + + def Deserialize(self, init): + if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) + if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) + +####### Movement Command +class MovementCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + self.plusbutton.SetValue(True) + + self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.commandchoice = wx.Choice(dialog, choices = [ + "forward", "left", "right", "backward", "up", "down", + "turnleft", "turnright", "first", "autorun", "clicktomove", + ],) + sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) + self.commandchoice.SetSelection(0) + + self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + pre = post = '' + if self.plusbutton.GetValue() : pre = "+" + elif self.plusplusbutton.GetValue() : pre = "++" + elif self.minusbutton.GetValue() : pre = "-" + elif self.zerobutton.GetValue() : post = " 0" + elif self.onebutton.GetValue() : post = " 1" + + command = self.commandchoice.GetString(self.commandchoice.GetSelection()) + + return f"{pre}{command}{post}" + + def Serialize(self): + mod = '' + if self.plusbutton.GetValue() : mod = "plus" + elif self.plusplusbutton.GetValue() : mod = "plusplus" + elif self.minusbutton.GetValue() : mod = "minus" + elif self.zerobutton.GetValue() : mod = "zero" + elif self.onebutton.GetValue() : mod = "one" + + return { + 'mod' : mod, + 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), + } + + def Deserialize(self, init): + mod = init.get('mod', 'plus') + + if mod == 'plus' : self.plusbutton.SetValue(True) + elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) + elif mod == 'minus' : self.minusbutton.SetValue(True) + elif mod == 'zero' : self.zerobutton.SetValue(True) + elif mod == 'one' : self.onebutton.SetValue(True) + + self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) + +####### Graphics Command +class GraphicsCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.FlexGridSizer(2) + + self.visscalecb = wx.CheckBox(dialog, label = "visscale") + sizer.Add(self.visscalecb) + self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) + sizer.Add(self.visscalesc) + + self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") + sizer.Add(self.dofweightcb) + self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) + sizer.Add(self.dofweightsc) + + self.fsaacb = wx.CheckBox(dialog, label = "fsaa") + sizer.Add(self.fsaacb) + self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) + self.fsaach.SetSelection(0) + sizer.Add(self.fsaach) + + self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") + sizer.Add(self.bloomscalecb) + self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) + self.bloomscalech.SetSelection(0) + sizer.Add(self.bloomscalech) + + self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") + sizer.Add(self.bloomweightcb) + self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) + sizer.Add(self.bloomweightsc) + + self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") + sizer.Add(self.lodbiascb) + self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) + sizer.Add(self.lodbiassc) + + self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") + sizer.Add(self.renderscalecb) + self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) + sizer.Add(self.renderscalesc) + + return sizer + + def MakeBindString(self): + # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. + bindstrings = [] + if self.visscalecb.IsChecked(): + bindstrings.append("visscale " + str(self.visscalesc.GetValue())) + if self.dofweightcb.IsChecked(): + bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) + if self.fsaacb.IsChecked(): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bindstrings.append("fsaa " + fsaavalue) + if self.bloomscalecb.IsChecked(): + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + bindstrings.append("bloomscale " + bloomscalevalue) + if self.bloomweightcb.IsChecked(): + bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) + if self.lodbiascb.IsChecked(): + bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) + if self.renderscalecb.IsChecked(): + bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) + + return '$$'.join(bindstrings) + + def Serialize(self): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + return { + 'visscalecb' : self.visscalecb.IsChecked(), + 'visscalesc' : self.visscalesc.GetValue(), + 'dofweightcb' : self.dofweightcb.IsChecked(), + 'dofweightsc' : self.dofweightsc.GetValue(), + 'fsaacb' : self.fsaacb.IsChecked(), + 'fsaach' : fsaavalue, + 'bloomscalecb' : self.bloomscalecb.IsChecked(), + 'bloomscalech' : bloomscalevalue, + 'bloomweightcb' : self.bloomweightcb.IsChecked(), + 'bloomweightsc' : self.bloomweightsc.GetValue(), + 'lodbiascb' : self.lodbiascb.IsChecked(), + 'lodbiassc' : self.lodbiassc.GetValue(), + 'renderscalecb' : self.renderscalecb.IsChecked(), + 'renderscalesc' : self.renderscalesc.GetValue(), + } + + def Deserialize(self, init): + self.visscalecb.SetValue(init.get('visscalecb', False)) + self.visscalesc.SetValue(init.get('visscalesc', 1.0)) + self.dofweightcb.SetValue(init.get('dofweightcb', False)) + self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) + self.fsaacb.SetValue(init.get('fsaacb', False)) + self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) + self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) + self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) + self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) + self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) + self.lodbiascb.SetValue(init.get('lodbiascb', False)) + self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) + self.renderscalecb.SetValue(init.get('renderscalecb', False)) + self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) + +####### Custom Bind +class CustomBindCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.customBindName = wx.TextCtrl(dialog, -1) + self.customBindName.SetHint('Custom Bind Text') + sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + return self.customBindName.GetValue() + + def Serialize(self): + return { 'customBindName': self.customBindName.GetValue() } + + def Deserialize(self,init): + if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) + +####### Emote +class EmoteCmd(PowerBindCmd): + def BuildUI(self, dialog): + emoteSizer = wx.BoxSizer(wx.HORIZONTAL) + self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") + emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + self.emoteName = wx.Button(dialog, -1, "...") + self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) + emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) + + return emoteSizer + + def MakeBindString(self): + displayedEmoteName = self.emoteName.GetLabel() + actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] + + return actualEmotePayload + + def Serialize(self): + return {'emoteName': self.emoteName.GetLabel()} + + def Deserialize(self, init): + if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) + +####### Load Binds Directory +class LoadBindsDir(PowerBindCmd): + def BuildUI(self, dialog): + mainSizer = wx.BoxSizer(wx.VERTICAL) + + lbSizer = wx.BoxSizer(wx.HORIZONTAL) + lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") + lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + profiles = Profile.GetAllProfileBindsDirs() + + self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) + lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") + self.lbResetCB.SetValue(True) + + mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + return mainSizer + + def MakeBindString(self): + + # If the specified binds directory disappeared between runs, we'd crash, so handle that. + if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' + + config = wx.ConfigBase.Get() + if config.Exists('GameBindPath'): + bindpath = config.Read('GameBindPath') + else: + bindpath = config.Read('BindPath') + + reset = "" + if self.lbResetCB.GetValue(): + reset = "keybind_reset$$" + + resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' + return reset + 'bindloadfile ' + str(resetfilepath) + + def Serialize(self): + return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), + 'ResetKeybinds' : self.lbResetCB.GetValue(), + } + + def Deserialize(self, init): + if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) + self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) + +####### Power Abort +class PowerAbortCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecabort' + +####### Power Unqueue +class PowerUnqueueCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecunqueue' + +####### SG Mode +class SGModeCmd(PowerBindCmd): + def BuildUI(self, dialog): + sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) + sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") + self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") + + sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) + + return sgmodeSizer + + def MakeBindString(self): + if self.sgmodeOnRB.GetValue(): + return 'sgmodeset 1' + elif self.sgmodeOffRB.GetValue(): + return 'sgmodeset 0' + else: + return 'sgmode' + + def Serialize(self): + if self.sgmodeOnRB.GetValue(): + val = "On" + elif self.sgmodeOffRB.GetValue(): + val = "Off" + else: + val = "Toggle" + + return {"value" : val} + + def Deserialize(self, init): + val = init.get('value', '') + if val == "On": + self.sgmodeOnRB.SetValue(True) + elif val == "Off": + self.sgmodeOffRB.SetValue(True) + else: + self.sgmodeToggleRB.SetValue(True) + +####### Target Custom +class TargetCustomCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetCustomSizer = wx.GridBagSizer(5,5) + targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), + flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) + self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetCustomModeChoice.SetSelection(0) + targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) + self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) + self.targetCustomOptionalName.SetHint("Optional name to match") + targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) + self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") + targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) + self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") + targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) + self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") + targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) + self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") + targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) + self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") + targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) + self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") + targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) + self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") + targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) + self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") + targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) + + targetCustomSizer.AddGrowableCol(2) + + return targetCustomSizer + + def MakeBindString(self): + choice = self.targetCustomModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + targetCommand = "targetcustom" + mode.lower() + + enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" + friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" + defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" + alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" + mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" + notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" + base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" + notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" + + name = self.targetCustomOptionalName.GetValue() + + return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" + + def Serialize(self): + return { + 'mode' : self.targetCustomModeChoice.GetSelection(), + 'enemy' : self.targetCustomCBEnemies. IsChecked(), + 'friend' : self.targetCustomCBFriends. IsChecked(), + 'defeated' : self.targetCustomCBDefeated. IsChecked(), + 'alive' : self.targetCustomCBAlive. IsChecked(), + 'mypet' : self.targetCustomCBMyPets. IsChecked(), + 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), + 'base' : self.targetCustomCBBaseItems. IsChecked(), + 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), + 'name' : self.targetCustomOptionalName.GetValue(), + } + + def Deserialize(self, init): + if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) + if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) + if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) + if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) + if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) + if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) + if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) + if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) + if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) + if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) + + +####### Target Enemy +class TargetEnemyCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) + targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetEnemyModeChoice.SetSelection(0) + targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetEnemySizer + + def MakeBindString(self): + choice = self.targetEnemyModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetenemy" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetEnemyModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) + +####### Target Friend +class TargetFriendCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) + targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetFriendModeChoice.SetSelection(0) + targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetFriendSizer + + def MakeBindString(self): + choice = self.targetFriendModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetfriend" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetFriendModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) + +####### Team/Pet Select +class TeamPetSelectCmd(PowerBindCmd): + def BuildUI(self, dialog): + teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], + style=wx.ALIGN_CENTER_VERTICAL) + self.teamPetSelectNumber.SetSelection(0) + teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) + + return teamPetSelectSizer + + def MakeBindString(self): + teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' + targetNumber = self.teamPetSelectNumber.GetSelection()+1 + + return f"{teamOrPet}select {targetNumber}" + + def Serialize(self): + return { + 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', + 'targetNum': self.teamPetSelectNumber.GetSelection(), + } + + def Deserialize(self, init): + ToP = init.get('teamOrPet', '') + if ToP == 'pet': + self.teamPetSelectPetRB.SetValue(True) + else: + self.teamPetSelectTeamRB.SetValue(True) + if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) + +####### Unselect +class UnselectCmd(PowerBindCmd): + def MakeBindString(self): + return 'unselect' + +####### Use Insp By Name +class UseInspByNameCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) + for _, types in GameData.Inspirations.items(): + for _, info in types.items(): + for insp in info['tiers']: + name = re.sub(' ', '', str(insp)) + icon = GetIcon(f'Inspirations/{name}') + self.useInspByNameModeChoice.Append(insp, icon) + self.useInspByNameModeChoice.SetSelection(0) + useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) + + return useInspByNameSizer + + def MakeBindString(self): + choice = self.useInspByNameModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "inspexecname " + mode.lower() + + def GetAllInsps(self): + Insplist = [] + for _, info in GameData.Inspirations.items(): + for insp in info['tiers']: + Insplist.append(insp) + Insplist.append("---") + Insplist.pop(-1) # snip the terminal "---" + + return Insplist + + def Serialize(self): + return { 'insp' : self.useInspByNameModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) + +####### Use Insp From Row / Column +class UseInspRowColCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnRow.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) + self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnCol.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) + + return useInspRowColumnSizer + + def MakeBindString(self): + row = self.useInspRowColumnRow.GetSelection()+1 + col = self.useInspRowColumnCol.GetSelection()+1 + + return f"inspexectray {col} {row}" + + def Serialize(self): + return { + 'col' : self.useInspRowColumnCol.GetSelection(), + 'row' : self.useInspRowColumnRow.GetSelection(), + } + + def Deserialize(self, init): + if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) + if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) + +####### Use Power +class UsePowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + outerSizer = wx.BoxSizer(wx.HORIZONTAL) + + usePowerSizer = wx.GridBagSizer(5,5) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBToggle, (0,1)) + self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOn, (0,2)) + self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOff, (0,3)) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerName = PowerPicker(dialog) + usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) + usePowerSizer.AddGrowableCol(3) + + outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) + + return outerSizer + + def MakeBindString(self): + if self.usePowerRBToggle.GetValue(): + method = "powexecname" + elif self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') + return '' + + return f"{method} {self.usePowerName.GetLabel()}" + + def Serialize(self): + if self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + method = "powexecname" + return { + 'method': method, + 'pname' : self.usePowerName.GetLabel(), + 'picon' : self.usePowerName.IconFilename + } + + def Deserialize(self, init): + method = init.get('method', '') + if method == 'powexectoggleon': + self.usePowerRBOn.SetValue(True) + elif method == 'powexectoggleoff': + self.usePowerRBOff.SetValue(True) + else: + self.usePowerRBToggle.SetValue(True) + if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) + +####### Use Power From Tray +class UsePowerFromTrayCmd(PowerBindCmd): + def BuildUI(self, dialog): + usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTrayTray = wx.Choice(dialog, -1, + choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', + 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) + self.usePowerFromTrayTray.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) + self.usePowerFromTraySlot.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return usePowerFromTraySizer + + def MakeBindString(self): + choice = self.usePowerFromTrayTray + tray = choice.GetSelection() + + choice = self.usePowerFromTraySlot + slot = choice.GetSelection()+1 + + mode = "slot" + mode2 = '' + if tray > 3: + mode = "tray" + mode2 = f" {tray - 3}" + elif tray == 3: + mode = "alt2slot" + elif tray == 2: + mode = "altslot" + + return f"powexec{mode} {slot}{mode2}" + + def Serialize(self): + return { + 'tray' : self.usePowerFromTrayTray.GetSelection(), + 'slot' : self.usePowerFromTraySlot.GetSelection(), + } + + def Deserialize(self, init): + if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) + if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) + +####### Window Color +class WindowColorCmd(PowerBindCmd): + def BuildUI(self, dialog): + windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) + borderSizer = wx.BoxSizer(wx.VERTICAL) + self.ColorBorder.SetSizer(borderSizer) + self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) + borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) + + windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) + + RGBASizer = wx.FlexGridSizer(3, 4, 5) + + RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) + self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) + self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + windowColorSizer.Add(RGBASizer) + + self.UpdateFromSlider() + + return windowColorSizer + + def MakeBindString(self): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + return f"windowcolor {Rval} {Gval} {Bval} {Aval}" + + def Serialize(self): + return { + 'Rval' : self.RSlider.GetValue(), + 'Gval' : self.GSlider.GetValue(), + 'Bval' : self.BSlider.GetValue(), + 'Aval' : self.ASlider.GetValue(), + } + + def Deserialize(self, init): + self.RSlider.SetValue(init['Rval']) + self.GSlider.SetValue(init['Gval']) + self.BSlider.SetValue(init['Bval']) + self.ASlider.SetValue(init['Aval']) + self.UpdateFromSlider() + + def UpdateFromSlider(self, _ = None): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RReadout.SetValue(Rval) + self.GReadout.SetValue(Gval) + self.BReadout.SetValue(Bval) + self.AReadout.SetValue(Aval) + self.ColorBorder.Refresh() + + def UpdateFromText(self, _ = None): + Rval = self.RReadout.GetValue() + Gval = self.GReadout.GetValue() + Bval = self.BReadout.GetValue() + Aval = self.AReadout.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RSlider.SetValue(Rval) + self.GSlider.SetValue(Gval) + self.BSlider.SetValue(Bval) + self.ASlider.SetValue(Aval) + self.ColorBorder.Refresh() + +####### Window Save / Load +class WindowSaveLoadCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) + self.CommandChoice.SetSelection(0) + sizer.Add(self.CommandChoice, 0, wx.ALL, 5) + + self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), + value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) + sizer.Add(self.FilePath, 0, wx.ALL, 5) + + return sizer + + def MakeBindString(self): + command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] + return f'{command} "{self.FilePath.GetValue()}"' + + def Serialize(self): + return { + 'command' : self.CommandChoice.GetSelection(), + 'filename' : self.FilePath.GetValue(), + } + + def Deserialize(self, init): + self.CommandChoice.SetSelection(init.get('command', 0)) + self.FilePath.SetValue(init.get('filename', '')) + +####### Window Toggle +class WindowToggleCmd(PowerBindCmd): + def BuildUI(self, dialog): + self.WindowNames = { + 'Actions' : 'actions', + 'Auction House' : 'ah', + 'Badge' : 'badge', + 'Channel Search' : 'chansearch', + 'Chat' : 'chat', + 'Custom Chat 1' : 'chat1', + 'Custom Chat 2' : 'chat2', + 'Custom Chat 3' : 'chat3', + 'Custom Chat 4' : 'chat4', + 'Clues' : 'clue', + 'Combat Numbers' : 'combatnumbers', + 'Contacts' : 'contact', + 'Contact Finder' : 'contactfinder', + 'Costumes' : 'costume', + 'Email' : 'email', + 'Enhancements' : 'enhancements', + 'Friends' : 'friend', + 'Group' : 'group', + 'Help' : 'helpwindow', + 'Incarnate' : 'incarnate', + 'Inspirations' : 'insp', + 'League' : 'league', + 'LFG' : 'lfg', + 'Map' : 'map', + 'Mission' : 'mission', + 'Nav / Compass' : 'nav', + 'Options' : 'options', + 'Pets' : 'pet', + 'Petition' : 'petition', + 'Power Tray' : 'powers', + 'Power List' : 'powerlist', + 'Quit' : 'quit', + 'Recipes' : 'recipe', + 'Salvage' : 'salvage', + 'Search' : 'search', + 'Supergroup' : 'sg', + 'Target' : 'target', + 'Team' : 'team', + 'Tray' : 'tray', + 'Tray1' : 'tray1', + 'Tray2' : 'tray2', + 'Tray3' : 'tray3', + 'Tray4' : 'tray4', + 'Tray5' : 'tray5', + 'Tray6' : 'tray6', + 'Tray7' : 'tray7', + 'Tray8' : 'tray8', + 'Vault' : 'vault', + } + + self.ShortToggleCommands = { + 'Auction House' : 'ah', + 'Chat' : 'chat', + 'Help' : 'helpwindow', + 'Map' : 'map', + 'Nav / Compass' : 'nav', + 'Power Tray' : 'powers', + 'Target' : 'target', + 'Tray' : 'tray', + } + + windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) + windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) + self.windowToggleTray.SetSelection(0) + windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.windowShowRB = wx.RadioButton(dialog, -1, "Show") + self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") + + windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) + + return windowToggleSizer + + def MakeBindString(self): + choice = self.windowToggleTray + index = choice.GetSelection() + windowdesc = choice.GetString(index) + windowname = self.WindowNames[windowdesc] + + if self.windowShowRB.GetValue(): + return 'show ' + windowname + elif self.windowHideRB.GetValue(): + return 'windowhide ' + windowname + else: + if shortcmd := self.ShortToggleCommands.get(windowdesc, None): + return shortcmd + else: + return 'toggle ' + windowname + + + def Serialize(self): + choice = self.windowToggleTray + if self.windowShowRB.GetValue(): + action = "Show" + elif self.windowHideRB.GetValue(): + action = "Hide" + else: + action = "Toggle" + return { + 'window': choice.GetString(choice.GetSelection()), + 'action': action, + } + + def Deserialize(self, init): + choice = self.windowToggleTray + if window := init.get('window', ''): + if isinstance(window, int): + choice.SetSelection(window) + else: + choice.SetSelection(choice.FindString(window)) + + if choice.GetSelection() == wx.NOT_FOUND: + choice.SetSelection(0) + + action = init.get('action', '') + if action == "Show": + self.windowShowRB.SetValue(True) + elif action == "Hide": + self.windowHideRB.SetValue(True) + else: + self.windowToggleRB.SetValue(True) + + +# Must always add to this list when adding a new command class above +menuStructure = { + 'Graphics / UI' : [ + 'Attribute Monitor', + 'Buff Display Settings', + 'Graphics Settings', + 'Window Color', + 'Window Save / Load', + 'Window Toggle', + ], + 'Inspirations' : [ + 'Use Inspiration By Name', + 'Use Inspiration From Row/Column', + ], + 'Powers' : [ + 'Auto Power', + 'Power Abort', + 'Power Unqueue', + 'Use Power', + 'Use Power From Tray', + ], + 'Social' : [ + 'Away From Keyboard', + 'Chat Command', + 'Chat Command (Global)', + 'Costume Change', + 'Emote', + 'Supergroup Mode', + ], + 'Targeting' : [ + 'Target Custom', + 'Target Enemy', + 'Target Frield', + 'Team/Pet Select', + 'Unselect', + ], + 'Misc' : [ + 'Load Binds Directory', + 'Movement Commands', + ], + # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, + # but I'm leaving it here to remind myself that we do that. + } + +# Must always add to this list when adding a new command class above +commandClasses = { + 'Auto Power' : AutoPowerCmd, + 'Away From Keyboard' : AFKCmd, + 'Attribute Monitor' : AttributeMonitorCmd, + 'Buff Display Settings' : BuffDisplayCmd, + 'Chat Command' : ChatCmd, + 'Chat Command (Global)' : ChatGlobalCmd, + 'Costume Change' : CostumeChangeCmd, + 'Custom Bind' : CustomBindCmd, + 'Emote' : EmoteCmd, + 'Graphics Settings' : GraphicsCmd, + 'Load Binds Directory' : LoadBindsDir, + 'Movement Commands' : MovementCmd, + 'Power Abort' : PowerAbortCmd, + 'Power Unqueue' : PowerUnqueueCmd, + 'Supergroup Mode' : SGModeCmd, + 'Target Custom' : TargetCustomCmd, + 'Target Enemy' : TargetEnemyCmd, + 'Target Friend' : TargetFriendCmd, + 'Team/Pet Select' : TeamPetSelectCmd, + 'Unselect' : UnselectCmd, + 'Use Inspiration By Name' : UseInspByNameCmd, + 'Use Inspiration From Row/Column' : UseInspRowColCmd, + 'Use Power' : UsePowerCmd, + 'Use Power From Tray' : UsePowerFromTrayCmd, + 'Window Color' : WindowColorCmd, + 'Window Save / Load' : WindowSaveLoadCmd, + 'Window Toggle' : WindowToggleCmd, +} +# use these when we rename a commandClass so that old Profiles will still load correctly. +# If we've also updated the class, we need to try to make sure the new class will still +# Deserialize the legacy data, or at least not crash. +deprecatedCommandClasses = { + 'SG Mode Toggle' : SGModeCmd, + 'Use Insp By Name' : UseInspByNameCmd, + 'Use Insp From Row/Column' : UseInspRowColCmd, +} +commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/CustomBindCmd.py b/UI/PowerBinderCommand/CustomBindCmd.py new file mode 100644 index 0000000..4c02ab7 --- /dev/null +++ b/UI/PowerBinderCommand/CustomBindCmd.py @@ -0,0 +1,1800 @@ +import wx +import re +import UI +import UI.EmotePicker +from UI.ControlGroup import ControlGroup +from UI.PowerPicker import PowerPicker +from Help import HelpButton +import wx.adv +from wx.adv import BitmapComboBox, EditableListBox +from pathlib import PureWindowsPath +import GameData +import Profile +from Icon import GetIcon + +class PowerBinderDialog(wx.Dialog): + def __init__(self, parent, button, init = {}): + wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) + + self.Page = parent.Page + self.EditDialog = PowerBinderEditDialog(self) + self.Button = button + self.AddStepMenu = self.makeAddStepMenu() + + sizer = wx.BoxSizer(wx.VERTICAL); + self.mainSizer = sizer + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) + # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) + # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) + #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) + AddStepButton = wx.Button(self, -1, 'Add Step') + AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) + AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) + choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) + choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) + sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) + + rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) + + self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) + self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) + self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) + rearrangeCtrl.Add(self.RearrangeList, 1) + + rearrangeButtons = wx.BoxSizer(wx.VERTICAL) + self.DelButton = wx.Button(self, -1, "Delete") + self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) + self.EditButton = wx.Button(self, -1, "Edit") + self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) + self.EditButton.Disable() + upButton = wx.Button(self, -1, "\u25B2") + upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) + downButton = wx.Button(self, -1, "\u25BC") + downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) + rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) + rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) + + sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.BindStringDisplay = wx.TextCtrl(self, -1) + self.BindStringDisplay.Disable() + choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, + wx.ALIGN_CENTER_VERTICAL) + choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) + + sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) + + sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) + + # need to dig around and get the OK button since we show this dialog modelessly now. + okButton = self.FindWindow(self.GetAffirmativeId()) + okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) + + # Wrap everything in a vbox to add some padding + vbox = wx.BoxSizer(wx.VERTICAL); + vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); + + self.SetSizerAndFit(vbox); + self.Layout() + self.Fit() + self.SetFocus() + + # if we are loading from profile, ie, have "init", build the list from it + if init: self.LoadFromData(init) + + def LoadFromData(self, init): + for item in init: + for type, data in item.items(): + commandClass = commandClasses.get(type, None) + if not commandClass: + commandClass = deprecatedCommandClasses.get(type, None) + if not commandClass: + wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") + continue + newCommand = commandClass(self.EditDialog, data) + index = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.SetClientData(index, newCommand) + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) + self.EditDialog.mainSizer.Hide(newCommand.UI) + self.UpdateBindStringDisplay() + + def SaveToData(self): + data = [] + index = 0 + for _ in self.RearrangeList.GetItems(): + # check whether we have an object already attached to this choice + cmdObject = self.RearrangeList.GetClientData(index) + commandClassName = commandRevClasses[type(cmdObject)] + data.append({commandClassName: cmdObject.Serialize()}) + index = index + 1 + return data + + def OnAddStepButton(self, evt): + button = evt.EventObject + if not self.AddStepMenu: + self.AddStepMenu = self.makeAddStepMenu() + button.PopupMenu(self.AddStepMenu) + + + def OnOKButton(self, _): + if self.Button.tgtTxtCtrl: + bindString = self.MakeBindString() + if bindString != self.Button.tgtTxtCtrl.GetValue(): + self.Button.tgtTxtCtrl.SetValue(bindString) + wx.App.Get().Main.Profile.SetModified() + self.Close() + + def OnRearrangeDelete(self, _): + current = self.RearrangeList.GetSelection() + if current == wx.NOT_FOUND: return + + self.RearrangeList.Delete(current) + self.UpdateBindStringDisplay() + + def OnRearrangeUp(self, _): + self.RearrangeList.MoveCurrentUp() + self.UpdateBindStringDisplay() + + def OnRearrangeDown(self, _): + self.RearrangeList.MoveCurrentDown() + self.UpdateBindStringDisplay() + + def OnRearrangeEdit(self, _): + index = self.RearrangeList.GetSelection() + + # check whether we have an object already attached to this choice + cmdObject = None + try: + cmdObject = self.RearrangeList.GetClientData(index) + except Exception: + pass + + if cmdObject: + self.ShowEditDialogFor(cmdObject) + self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) + else: + print("cmdObject was None") + self.UpdateBindStringDisplay() + + # OnAddStepMenu creates a new step and adds it to the rearrangelist + def OnAddStepMenu(self, evt): + menuitem = self.AddStepMenu.FindItemById(evt.GetId()) + chosenName = menuitem.GetItemLabel() + + # make a new command object, attached to the parent dialog + newCommandClass = commandClasses[chosenName] + newCommand = newCommandClass(self.EditDialog) + + # show the edit dialog if this command needs it + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) + if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): + self.EditDialog.mainSizer.Remove(newCommand.UI) + return + + newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.Select(newBindIndex) + self.RearrangeList.SetClientData(newBindIndex, newCommand) + + self.OnListSelect() + self.UpdateBindStringDisplay() + + def OnListSelect(self, _ = None): + selected = self.RearrangeList.GetSelection() + + if selected != wx.NOT_FOUND: + selCommand = self.RearrangeList.GetClientData(selected) + if selCommand.UI: + self.EditButton.Enable() + else: + self.EditButton.Disable() + + def UpdateBindStringDisplay(self): + self.BindStringDisplay.SetValue(self.MakeBindString()) + self.BindStringDisplay.SetToolTip(self.MakeBindString()) + + def MakeBindString(self): + cmdBindStrings = [] + for index in range(self.RearrangeList.GetCount()): + c = self.RearrangeList.GetClientData(index) + if c: cmdBindStrings.append(c.MakeBindString()) + + bindstring = ('$$'.join(cmdBindStrings)) + return bindstring + + def ShowEditDialogFor(self, command): + if not command.UI: return + + self.EditDialog.mainSizer.Show(command.UI) + + self.EditDialog.Layout() + self.EditDialog.Fit() + + self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') + returnval = self.EditDialog.ShowModal() + + self.EditDialog.mainSizer.Hide(command.UI) + + return returnval + + def makeAddStepMenu(self): + + stepMenu = wx.Menu() + + for subname in menuStructure: + submenu = wx.Menu() + stepMenu.AppendSubMenu(submenu, subname) + for classname in menuStructure[subname]: + submenu.Append(wx.ID_ANY, classname) + + stepMenu.Append(wx.ID_ANY, 'Custom Bind') + + return stepMenu + +class PowerBinderButton(wx.BitmapButton): + + def __init__(self, parent, tgtTxtCtrl, init = {}): + wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) + self.Init = init + self.Dialog = None + self.DialogParent = parent + + self.tgtTxtCtrl = tgtTxtCtrl + self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) + self.SetToolTip("Launch PowerBinder") + + def PowerBinderEventHandler(self, _): + self.PowerBinderDialog().Show() + + def LoadFromData(self, data): + self.PowerBinderDialog().LoadFromData(data) + + def SaveToData(self): + return self.PowerBinderDialog().SaveToData() + + def PowerBinderDialog(self): + if not self.Dialog: + self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) + return self.Dialog + + +class PowerBinderEditDialog(wx.Dialog): + def __init__(self, parent): + wx.Dialog.__init__(self, parent, -1, "Edit Step", + style = wx.DEFAULT_DIALOG_STYLE) + + outerSizer = wx.BoxSizer(wx.VERTICAL) + + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + self.mainSizer.SetMinSize([500, 150]) + + self.Page = parent.Page + + self.mainSizer.Add( + self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), + 0, wx.EXPAND|wx.ALL, 10) + + outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) + + self.SetSizerAndFit(outerSizer) + self.Layout() + self.Fit() + +########### Power Binder Command Objects +class PowerBindCmd(): + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + commandClassName = commandRevClasses[type(self)] + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{commandClassName} - {short_bindstr}" + + +####### Away From Keyboard +class AFKCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) + +####### Attribute Monitor +class AttributeMonitorCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.Groups = {} + self.AttributeTable = { + 'Base' : { + 'Current Hit Points' : 'NT H', + 'Max Hit Points' : 'X H', + 'Current Endurance' : 'T E', + 'Max Endurance' : 'X EN', + 'Regeneration Rate' : 'N RAT', + 'Recovery Rate' : 'Y RA', + 'Endurance Consumption' : 'SU', + 'ToHit Bonus' : 'T B', + 'Accuracy Bonus' : 'CC', + 'Last Hit Chance' : 'T C', + 'Damage Bonus' : 'DA', + 'Healing Bonus' : 'NG B', + 'Recharge Time Bonus' : 'ME B', + 'Endurance Discount' : 'CE DIS', + 'Stealth Radius (PvP)' : 'PVP', + 'Stealth Radius (PvE)' : 'PVE', + 'Perception Radius' : 'RC', + 'Range Bonus' : 'GE B', + 'Threat Level' : 'AT L', + 'Experience to Next Level' : 'XT', + 'Experience Debt' : 'XP', + 'Influence / Infamy' : 'INF', + 'Inherent' : 'NH', + }, + 'Movement Speed' : { + 'Flying Speed' : 'FL', + 'Jumping Speed' : 'PI', + 'Max Jump Height' : 'X J', + 'Run Speed' : 'RU', + }, + 'Damage Resistance' : { + 'Smashing Resistance' : 'G R', + 'Lethal Resistance' : 'L R', + 'Fire Resistance' : 'RE R', + 'Cold Resistance' : 'COLD R', + 'Energy Resistance' : 'DamageType[4]', + 'Negative Energy Resistance' : 'GY R', + 'Psyonic Resistance' : 'NIC R', + 'Toxic Resistance' : 'XIC R', + }, + 'Defense' : { + 'Base Defense' : 'BAS', + 'Ranged Defense' : 'ED', + 'Melee Defense' : 'MEL', + 'AoE Defense' : '2', + 'Smashing Defense' : '3', + 'Lethal Defense' : '4', + 'Fire Defense' : '5', + 'Cold Defense' : '6', + 'Energy Defense' : '7', + 'Negative Energy Defense' : '8', + 'Psionic Defense' : '9', + 'Toxic Defense' : '1', + }, + 'Debuff Resistance' : { + 'Regeneration Resistance' : 'ON R', + 'Recovery Resistance' : 'RY R', + 'To Hit Resistance' : 'IT R', + 'Defense Resistance' : 'NSE RES', + }, + 'Status Effect Protection' : { + 'Hold Protection' : 'D P', + 'Immobilize Protection' : 'LIZE P', + 'Stun Protection' : 'N P', + 'Sleep Protection' : 'P P', + 'Knockback Protection' : 'K P', + 'Confuse Protection' : 'SE P', + 'Terrorize Protection' : 'ZE P', + 'Repel Protection' : 'EL P', + 'Teleport Protection' : 'T P', + }, + 'Status Effect Resistance' : { + 'Hold Resistance' : 'D R', + 'Immobilize Resistance' : 'LIZE R', + 'Stun Resistance' : 'N R', + 'Sleep Resistance' : 'P R', + 'Knockback Resistance' : 'K R', + 'Confuse Resistance' : 'SE R', + 'Terrorize Resistance' : 'ZE R', + 'Placate Resistance' : 'TE R', + 'Taunt Resistance' : 'NT R', + }, + 'Miscellaneous' : { + 'Level Shift' : 'L S', + }, + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.AttributeMenu = wx.Menu() + for group, controls in self.AttributeTable.items(): + submenu = wx.Menu() + self.AttributeMenu.AppendSubMenu(submenu, group) + for cb in controls: + submenu.Append(wx.ID_ANY, cb) + + self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) + + self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) + groupSizer.Add(self.editbox) + + newButton = self.editbox.GetNewButton() + newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) + + return groupSizer + + def MakeBindString(self): + map = {} + bindstrings = [] + for _, controls in self.AttributeTable.items(): + for cb, data in controls.items(): + map[cb] = data + + for string in self.editbox.GetStrings(): + if string: + bindstrings.append(f'monitorattribute {map[string]}') + + return '$$'.join(bindstrings) + + def Serialize(self): + return { + 'attributes' : self.editbox.GetStrings() + } + + def Deserialize(self, init): + self.editbox.SetStrings(init.get('attributes', [])) + + def OnNewButton(self, evt): + evt.GetEventObject().PopupMenu(self.AttributeMenu) + + def OnMenuItem(self, evt): + menuitem = evt.EventObject.FindItemById(evt.GetId()) + existingstrings = self.editbox.GetStrings() + existingstrings.append(menuitem.GetItemLabel()) + self.editbox.SetStrings(existingstrings) + +####### Auto Power +class AutoPowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) + autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.autoPowerName = PowerPicker(dialog) + autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) + + return autoPowerSizer + + def MakeBindString(self): + return f"powexecauto {self.autoPowerName.GetLabel()}" + + def Serialize(self): + return { + 'pname' : self.autoPowerName.GetLabel(), + 'picon' : self.autoPowerName.IconFilename + } + + def Deserialize(self, init): + if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) + +####### Buff Display Command +class BuffDisplayCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.buffDisplayMap = { + 'Status Window' : { + 'Hide Auto' : 1, + 'Hide Toggles' : 2, + 'No Blinking' : 4, + 'No Stacking' : 8, + 'Numeric Stacking' : 16, + 'Hide Buff Numbers' : 32, + 'Stop Sending Buffs' : 64, + }, + 'Group Window' : { + 'Hide Auto' : 256, + 'Hide Toggles' : 512, + 'No Blinking' : 1024, + 'No Stacking' : 2048, + 'Numeric Stacking' : 4096, + 'Hide Buff Numbers' : 8192, + 'Stop Sending Buffs' : 16384, + }, + 'Pet Window' : { + 'Hide Auto' : 65536, + 'Hide Toggles' : 131072, + 'No Blinking' : 262144, + 'No Stacking' : 524288, + 'Numeric Stacking' : 1048576, + 'Hide Buff Numbers' : 2097152, + 'Stop Sending Buffs' : 4194304, + }, + } + self.Groups = {} + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + for group, controls in self.buffDisplayMap.items(): + self.Groups[group] = ControlGroup(dialog, self.Page, label = group) + groupid = self.Groups[group].GetStaticBox().GetId() + for cb, data in controls.items(): + self.Groups[group].AddControl( + ctlType = 'checkbox', + ctlName = f"{groupid}_{group}_{cb}", + label = cb, + data = data, + ) + + groupSizer.Add(self.Groups[group]) + + return groupSizer + + def CalculateValue(self): + page = wx.App.Get().Main.Profile.CustomBinds + + total = 0 + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] + if checkbox.IsChecked(): + total = total + checkbox.Data + return total + + def MakeBindString(self): + return f"optionset buffsettings {self.CalculateValue()}" + + def Serialize(self): + return { 'value' : self.CalculateValue() } + + def Deserialize(self, init): + value = init.get('value', 0) + + value = value or 0 # in case we had for some reason 'None' stashed in the init values + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] + checkbox.SetValue( checkbox.Data & value ) + +####### Chat Command +class ChatCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.chatChannelMap = { # before __init__ + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + chatCommandSizer = wx.GridBagSizer(5, 5) + self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") + chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) + # row 1 + self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) + self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) + self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) + # row 2 + self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) + self.chatCommandDuration.SetRange(1, 20) + self.chatCommandDuration.SetValue(7) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandDuration, (2,1)) + self.chatCommandChatSize = wx.Choice(dialog, -1, + choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) + self.chatCommandChatSize.SetSelection(5) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) + self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) + self.chatCommandChannel.SetSelection(0) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChannel, (2,5)) + # row 3 + self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") + chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) + self.chatCommandMessage = wx.TextCtrl(dialog, -1) + self.chatCommandMessage.SetHint('Chat Command Text') + chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) + + return chatCommandSizer + + def MakeBindString(self): + duration = self.chatCommandDuration.GetValue() + + choice = self.chatCommandChatSize + index = choice.GetSelection() + size = choice.GetString(index) + + duration = f"" if duration != 7 else "" + size = f"" if size != "1" else "" + + bdcolor = fgcolor = bgcolor = '' + if self.chatCommandUseColorsCB.IsChecked(): + bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + + bdcolor = f"" + fgcolor = f"" + bgcolor = f"" + + beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' + text = self.chatCommandMessage.GetValue() + + choice = self.chatCommandChannel + index = choice.GetSelection() + channel = choice.GetString(index) + + return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" + + def Serialize(self): + return { + 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), + 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), + 'channel' : self.chatCommandChannel .GetSelection(), + 'size' : self.chatCommandChatSize.GetSelection(), + 'duration' : self.chatCommandDuration.GetValue(), + 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'text' : self.chatCommandMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) + if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) + if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) + if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) + if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) + if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) + if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) + if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) + if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) + + +####### Chat Command Global +class ChatGlobalCmd(PowerBindCmd): + def BuildUI(self, dialog): + chatCommandGlobalSizer = wx.GridBagSizer(5,5) + + self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") + chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) + + self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalChannel.SetHint("Channel") + chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) + + self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') + chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) + + chatCommandGlobalSizer.AddGrowableCol(1) + + return chatCommandGlobalSizer + + def MakeBindString(self): + useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() + channel = self.chatCommandGlobalChannel.GetValue() + message = self.chatCommandGlobalMessage.GetValue() + + preface = "beginchat /" if useBeginchat else "" + + return f'{preface}send "{channel}" {message}' + + def Serialize(self): + return { + 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), + 'channel' : self.chatCommandGlobalChannel.GetValue(), + 'message' : self.chatCommandGlobalMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) + if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) + if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) + +#######Costume Change +class CostumeChangeCmd(PowerBindCmd): + def BuildUI(self, dialog): + costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeCostume = wx.Choice(dialog, -1, + choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) + self.costumeChangeCostume.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeEmote = wx.Choice(dialog, -1, + choices = GameData.Emotes['costumechange']) + self.costumeChangeEmote.Insert("- None -", 0) + self.costumeChangeEmote.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return costumeChangeSizer + + def MakeBindString(self): + costumeNumber = self.costumeChangeCostume.GetSelection() + costumeEmote = self.costumeChangeEmote.GetSelection() + + if costumeEmote: # None, or 0 == "- None -" + ccCmd = 'cce' + emoteName = self.costumeChangeEmote.GetString(costumeEmote) + emoteName = " CC" + emoteName.replace(" ","") + else: + ccCmd = 'cc' + emoteName = '' + + return f"{ccCmd} {costumeNumber}{emoteName}" + + def Serialize(self): + return{ + 'costumeNumber': self.costumeChangeCostume.GetSelection(), + 'costumeEmote' : self.costumeChangeEmote.GetSelection(), + } + + def Deserialize(self, init): + if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) + if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) + +####### Movement Command +class MovementCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + self.plusbutton.SetValue(True) + + self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.commandchoice = wx.Choice(dialog, choices = [ + "forward", "left", "right", "backward", "up", "down", + "turnleft", "turnright", "first", "autorun", "clicktomove", + ],) + sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) + self.commandchoice.SetSelection(0) + + self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + pre = post = '' + if self.plusbutton.GetValue() : pre = "+" + elif self.plusplusbutton.GetValue() : pre = "++" + elif self.minusbutton.GetValue() : pre = "-" + elif self.zerobutton.GetValue() : post = " 0" + elif self.onebutton.GetValue() : post = " 1" + + command = self.commandchoice.GetString(self.commandchoice.GetSelection()) + + return f"{pre}{command}{post}" + + def Serialize(self): + mod = '' + if self.plusbutton.GetValue() : mod = "plus" + elif self.plusplusbutton.GetValue() : mod = "plusplus" + elif self.minusbutton.GetValue() : mod = "minus" + elif self.zerobutton.GetValue() : mod = "zero" + elif self.onebutton.GetValue() : mod = "one" + + return { + 'mod' : mod, + 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), + } + + def Deserialize(self, init): + mod = init.get('mod', 'plus') + + if mod == 'plus' : self.plusbutton.SetValue(True) + elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) + elif mod == 'minus' : self.minusbutton.SetValue(True) + elif mod == 'zero' : self.zerobutton.SetValue(True) + elif mod == 'one' : self.onebutton.SetValue(True) + + self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) + +####### Graphics Command +class GraphicsCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.FlexGridSizer(2) + + self.visscalecb = wx.CheckBox(dialog, label = "visscale") + sizer.Add(self.visscalecb) + self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) + sizer.Add(self.visscalesc) + + self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") + sizer.Add(self.dofweightcb) + self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) + sizer.Add(self.dofweightsc) + + self.fsaacb = wx.CheckBox(dialog, label = "fsaa") + sizer.Add(self.fsaacb) + self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) + self.fsaach.SetSelection(0) + sizer.Add(self.fsaach) + + self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") + sizer.Add(self.bloomscalecb) + self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) + self.bloomscalech.SetSelection(0) + sizer.Add(self.bloomscalech) + + self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") + sizer.Add(self.bloomweightcb) + self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) + sizer.Add(self.bloomweightsc) + + self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") + sizer.Add(self.lodbiascb) + self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) + sizer.Add(self.lodbiassc) + + self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") + sizer.Add(self.renderscalecb) + self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) + sizer.Add(self.renderscalesc) + + return sizer + + def MakeBindString(self): + # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. + bindstrings = [] + if self.visscalecb.IsChecked(): + bindstrings.append("visscale " + str(self.visscalesc.GetValue())) + if self.dofweightcb.IsChecked(): + bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) + if self.fsaacb.IsChecked(): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bindstrings.append("fsaa " + fsaavalue) + if self.bloomscalecb.IsChecked(): + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + bindstrings.append("bloomscale " + bloomscalevalue) + if self.bloomweightcb.IsChecked(): + bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) + if self.lodbiascb.IsChecked(): + bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) + if self.renderscalecb.IsChecked(): + bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) + + return '$$'.join(bindstrings) + + def Serialize(self): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + return { + 'visscalecb' : self.visscalecb.IsChecked(), + 'visscalesc' : self.visscalesc.GetValue(), + 'dofweightcb' : self.dofweightcb.IsChecked(), + 'dofweightsc' : self.dofweightsc.GetValue(), + 'fsaacb' : self.fsaacb.IsChecked(), + 'fsaach' : fsaavalue, + 'bloomscalecb' : self.bloomscalecb.IsChecked(), + 'bloomscalech' : bloomscalevalue, + 'bloomweightcb' : self.bloomweightcb.IsChecked(), + 'bloomweightsc' : self.bloomweightsc.GetValue(), + 'lodbiascb' : self.lodbiascb.IsChecked(), + 'lodbiassc' : self.lodbiassc.GetValue(), + 'renderscalecb' : self.renderscalecb.IsChecked(), + 'renderscalesc' : self.renderscalesc.GetValue(), + } + + def Deserialize(self, init): + self.visscalecb.SetValue(init.get('visscalecb', False)) + self.visscalesc.SetValue(init.get('visscalesc', 1.0)) + self.dofweightcb.SetValue(init.get('dofweightcb', False)) + self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) + self.fsaacb.SetValue(init.get('fsaacb', False)) + self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) + self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) + self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) + self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) + self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) + self.lodbiascb.SetValue(init.get('lodbiascb', False)) + self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) + self.renderscalecb.SetValue(init.get('renderscalecb', False)) + self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) + +####### Custom Bind +class CustomBindCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.customBindName = wx.TextCtrl(dialog, -1) + self.customBindName.SetHint('Custom Bind Text') + sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + return self.customBindName.GetValue() + + def Serialize(self): + return { 'customBindName': self.customBindName.GetValue() } + + def Deserialize(self,init): + if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) + +####### Emote +class EmoteCmd(PowerBindCmd): + def BuildUI(self, dialog): + emoteSizer = wx.BoxSizer(wx.HORIZONTAL) + self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") + emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + self.emoteName = wx.Button(dialog, -1, "...") + self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) + emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) + + return emoteSizer + + def MakeBindString(self): + displayedEmoteName = self.emoteName.GetLabel() + actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] + + return actualEmotePayload + + def Serialize(self): + return {'emoteName': self.emoteName.GetLabel()} + + def Deserialize(self, init): + if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) + +####### Load Binds Directory +class LoadBindsDir(PowerBindCmd): + def BuildUI(self, dialog): + mainSizer = wx.BoxSizer(wx.VERTICAL) + + lbSizer = wx.BoxSizer(wx.HORIZONTAL) + lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") + lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + profiles = Profile.GetAllProfileBindsDirs() + + self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) + lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") + self.lbResetCB.SetValue(True) + + mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + return mainSizer + + def MakeBindString(self): + + # If the specified binds directory disappeared between runs, we'd crash, so handle that. + if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' + + config = wx.ConfigBase.Get() + if config.Exists('GameBindPath'): + bindpath = config.Read('GameBindPath') + else: + bindpath = config.Read('BindPath') + + reset = "" + if self.lbResetCB.GetValue(): + reset = "keybind_reset$$" + + resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' + return reset + 'bindloadfile ' + str(resetfilepath) + + def Serialize(self): + return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), + 'ResetKeybinds' : self.lbResetCB.GetValue(), + } + + def Deserialize(self, init): + if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) + self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) + +####### Power Abort +class PowerAbortCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecabort' + +####### Power Unqueue +class PowerUnqueueCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecunqueue' + +####### SG Mode +class SGModeCmd(PowerBindCmd): + def BuildUI(self, dialog): + sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) + sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") + self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") + + sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) + + return sgmodeSizer + + def MakeBindString(self): + if self.sgmodeOnRB.GetValue(): + return 'sgmodeset 1' + elif self.sgmodeOffRB.GetValue(): + return 'sgmodeset 0' + else: + return 'sgmode' + + def Serialize(self): + if self.sgmodeOnRB.GetValue(): + val = "On" + elif self.sgmodeOffRB.GetValue(): + val = "Off" + else: + val = "Toggle" + + return {"value" : val} + + def Deserialize(self, init): + val = init.get('value', '') + if val == "On": + self.sgmodeOnRB.SetValue(True) + elif val == "Off": + self.sgmodeOffRB.SetValue(True) + else: + self.sgmodeToggleRB.SetValue(True) + +####### Target Custom +class TargetCustomCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetCustomSizer = wx.GridBagSizer(5,5) + targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), + flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) + self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetCustomModeChoice.SetSelection(0) + targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) + self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) + self.targetCustomOptionalName.SetHint("Optional name to match") + targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) + self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") + targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) + self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") + targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) + self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") + targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) + self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") + targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) + self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") + targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) + self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") + targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) + self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") + targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) + self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") + targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) + + targetCustomSizer.AddGrowableCol(2) + + return targetCustomSizer + + def MakeBindString(self): + choice = self.targetCustomModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + targetCommand = "targetcustom" + mode.lower() + + enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" + friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" + defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" + alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" + mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" + notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" + base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" + notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" + + name = self.targetCustomOptionalName.GetValue() + + return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" + + def Serialize(self): + return { + 'mode' : self.targetCustomModeChoice.GetSelection(), + 'enemy' : self.targetCustomCBEnemies. IsChecked(), + 'friend' : self.targetCustomCBFriends. IsChecked(), + 'defeated' : self.targetCustomCBDefeated. IsChecked(), + 'alive' : self.targetCustomCBAlive. IsChecked(), + 'mypet' : self.targetCustomCBMyPets. IsChecked(), + 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), + 'base' : self.targetCustomCBBaseItems. IsChecked(), + 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), + 'name' : self.targetCustomOptionalName.GetValue(), + } + + def Deserialize(self, init): + if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) + if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) + if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) + if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) + if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) + if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) + if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) + if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) + if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) + if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) + + +####### Target Enemy +class TargetEnemyCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) + targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetEnemyModeChoice.SetSelection(0) + targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetEnemySizer + + def MakeBindString(self): + choice = self.targetEnemyModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetenemy" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetEnemyModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) + +####### Target Friend +class TargetFriendCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) + targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetFriendModeChoice.SetSelection(0) + targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetFriendSizer + + def MakeBindString(self): + choice = self.targetFriendModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetfriend" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetFriendModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) + +####### Team/Pet Select +class TeamPetSelectCmd(PowerBindCmd): + def BuildUI(self, dialog): + teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], + style=wx.ALIGN_CENTER_VERTICAL) + self.teamPetSelectNumber.SetSelection(0) + teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) + + return teamPetSelectSizer + + def MakeBindString(self): + teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' + targetNumber = self.teamPetSelectNumber.GetSelection()+1 + + return f"{teamOrPet}select {targetNumber}" + + def Serialize(self): + return { + 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', + 'targetNum': self.teamPetSelectNumber.GetSelection(), + } + + def Deserialize(self, init): + ToP = init.get('teamOrPet', '') + if ToP == 'pet': + self.teamPetSelectPetRB.SetValue(True) + else: + self.teamPetSelectTeamRB.SetValue(True) + if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) + +####### Unselect +class UnselectCmd(PowerBindCmd): + def MakeBindString(self): + return 'unselect' + +####### Use Insp By Name +class UseInspByNameCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) + for _, types in GameData.Inspirations.items(): + for _, info in types.items(): + for insp in info['tiers']: + name = re.sub(' ', '', str(insp)) + icon = GetIcon(f'Inspirations/{name}') + self.useInspByNameModeChoice.Append(insp, icon) + self.useInspByNameModeChoice.SetSelection(0) + useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) + + return useInspByNameSizer + + def MakeBindString(self): + choice = self.useInspByNameModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "inspexecname " + mode.lower() + + def GetAllInsps(self): + Insplist = [] + for _, info in GameData.Inspirations.items(): + for insp in info['tiers']: + Insplist.append(insp) + Insplist.append("---") + Insplist.pop(-1) # snip the terminal "---" + + return Insplist + + def Serialize(self): + return { 'insp' : self.useInspByNameModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) + +####### Use Insp From Row / Column +class UseInspRowColCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnRow.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) + self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnCol.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) + + return useInspRowColumnSizer + + def MakeBindString(self): + row = self.useInspRowColumnRow.GetSelection()+1 + col = self.useInspRowColumnCol.GetSelection()+1 + + return f"inspexectray {col} {row}" + + def Serialize(self): + return { + 'col' : self.useInspRowColumnCol.GetSelection(), + 'row' : self.useInspRowColumnRow.GetSelection(), + } + + def Deserialize(self, init): + if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) + if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) + +####### Use Power +class UsePowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + outerSizer = wx.BoxSizer(wx.HORIZONTAL) + + usePowerSizer = wx.GridBagSizer(5,5) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBToggle, (0,1)) + self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOn, (0,2)) + self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOff, (0,3)) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerName = PowerPicker(dialog) + usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) + usePowerSizer.AddGrowableCol(3) + + outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) + + return outerSizer + + def MakeBindString(self): + if self.usePowerRBToggle.GetValue(): + method = "powexecname" + elif self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') + return '' + + return f"{method} {self.usePowerName.GetLabel()}" + + def Serialize(self): + if self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + method = "powexecname" + return { + 'method': method, + 'pname' : self.usePowerName.GetLabel(), + 'picon' : self.usePowerName.IconFilename + } + + def Deserialize(self, init): + method = init.get('method', '') + if method == 'powexectoggleon': + self.usePowerRBOn.SetValue(True) + elif method == 'powexectoggleoff': + self.usePowerRBOff.SetValue(True) + else: + self.usePowerRBToggle.SetValue(True) + if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) + +####### Use Power From Tray +class UsePowerFromTrayCmd(PowerBindCmd): + def BuildUI(self, dialog): + usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTrayTray = wx.Choice(dialog, -1, + choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', + 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) + self.usePowerFromTrayTray.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) + self.usePowerFromTraySlot.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return usePowerFromTraySizer + + def MakeBindString(self): + choice = self.usePowerFromTrayTray + tray = choice.GetSelection() + + choice = self.usePowerFromTraySlot + slot = choice.GetSelection()+1 + + mode = "slot" + mode2 = '' + if tray > 3: + mode = "tray" + mode2 = f" {tray - 3}" + elif tray == 3: + mode = "alt2slot" + elif tray == 2: + mode = "altslot" + + return f"powexec{mode} {slot}{mode2}" + + def Serialize(self): + return { + 'tray' : self.usePowerFromTrayTray.GetSelection(), + 'slot' : self.usePowerFromTraySlot.GetSelection(), + } + + def Deserialize(self, init): + if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) + if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) + +####### Window Color +class WindowColorCmd(PowerBindCmd): + def BuildUI(self, dialog): + windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) + borderSizer = wx.BoxSizer(wx.VERTICAL) + self.ColorBorder.SetSizer(borderSizer) + self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) + borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) + + windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) + + RGBASizer = wx.FlexGridSizer(3, 4, 5) + + RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) + self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) + self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + windowColorSizer.Add(RGBASizer) + + self.UpdateFromSlider() + + return windowColorSizer + + def MakeBindString(self): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + return f"windowcolor {Rval} {Gval} {Bval} {Aval}" + + def Serialize(self): + return { + 'Rval' : self.RSlider.GetValue(), + 'Gval' : self.GSlider.GetValue(), + 'Bval' : self.BSlider.GetValue(), + 'Aval' : self.ASlider.GetValue(), + } + + def Deserialize(self, init): + self.RSlider.SetValue(init['Rval']) + self.GSlider.SetValue(init['Gval']) + self.BSlider.SetValue(init['Bval']) + self.ASlider.SetValue(init['Aval']) + self.UpdateFromSlider() + + def UpdateFromSlider(self, _ = None): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RReadout.SetValue(Rval) + self.GReadout.SetValue(Gval) + self.BReadout.SetValue(Bval) + self.AReadout.SetValue(Aval) + self.ColorBorder.Refresh() + + def UpdateFromText(self, _ = None): + Rval = self.RReadout.GetValue() + Gval = self.GReadout.GetValue() + Bval = self.BReadout.GetValue() + Aval = self.AReadout.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RSlider.SetValue(Rval) + self.GSlider.SetValue(Gval) + self.BSlider.SetValue(Bval) + self.ASlider.SetValue(Aval) + self.ColorBorder.Refresh() + +####### Window Save / Load +class WindowSaveLoadCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) + self.CommandChoice.SetSelection(0) + sizer.Add(self.CommandChoice, 0, wx.ALL, 5) + + self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), + value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) + sizer.Add(self.FilePath, 0, wx.ALL, 5) + + return sizer + + def MakeBindString(self): + command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] + return f'{command} "{self.FilePath.GetValue()}"' + + def Serialize(self): + return { + 'command' : self.CommandChoice.GetSelection(), + 'filename' : self.FilePath.GetValue(), + } + + def Deserialize(self, init): + self.CommandChoice.SetSelection(init.get('command', 0)) + self.FilePath.SetValue(init.get('filename', '')) + +####### Window Toggle +class WindowToggleCmd(PowerBindCmd): + def BuildUI(self, dialog): + self.WindowNames = { + 'Actions' : 'actions', + 'Auction House' : 'ah', + 'Badge' : 'badge', + 'Channel Search' : 'chansearch', + 'Chat' : 'chat', + 'Custom Chat 1' : 'chat1', + 'Custom Chat 2' : 'chat2', + 'Custom Chat 3' : 'chat3', + 'Custom Chat 4' : 'chat4', + 'Clues' : 'clue', + 'Combat Numbers' : 'combatnumbers', + 'Contacts' : 'contact', + 'Contact Finder' : 'contactfinder', + 'Costumes' : 'costume', + 'Email' : 'email', + 'Enhancements' : 'enhancements', + 'Friends' : 'friend', + 'Group' : 'group', + 'Help' : 'helpwindow', + 'Incarnate' : 'incarnate', + 'Inspirations' : 'insp', + 'League' : 'league', + 'LFG' : 'lfg', + 'Map' : 'map', + 'Mission' : 'mission', + 'Nav / Compass' : 'nav', + 'Options' : 'options', + 'Pets' : 'pet', + 'Petition' : 'petition', + 'Power Tray' : 'powers', + 'Power List' : 'powerlist', + 'Quit' : 'quit', + 'Recipes' : 'recipe', + 'Salvage' : 'salvage', + 'Search' : 'search', + 'Supergroup' : 'sg', + 'Target' : 'target', + 'Team' : 'team', + 'Tray' : 'tray', + 'Tray1' : 'tray1', + 'Tray2' : 'tray2', + 'Tray3' : 'tray3', + 'Tray4' : 'tray4', + 'Tray5' : 'tray5', + 'Tray6' : 'tray6', + 'Tray7' : 'tray7', + 'Tray8' : 'tray8', + 'Vault' : 'vault', + } + + self.ShortToggleCommands = { + 'Auction House' : 'ah', + 'Chat' : 'chat', + 'Help' : 'helpwindow', + 'Map' : 'map', + 'Nav / Compass' : 'nav', + 'Power Tray' : 'powers', + 'Target' : 'target', + 'Tray' : 'tray', + } + + windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) + windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) + self.windowToggleTray.SetSelection(0) + windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.windowShowRB = wx.RadioButton(dialog, -1, "Show") + self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") + + windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) + + return windowToggleSizer + + def MakeBindString(self): + choice = self.windowToggleTray + index = choice.GetSelection() + windowdesc = choice.GetString(index) + windowname = self.WindowNames[windowdesc] + + if self.windowShowRB.GetValue(): + return 'show ' + windowname + elif self.windowHideRB.GetValue(): + return 'windowhide ' + windowname + else: + if shortcmd := self.ShortToggleCommands.get(windowdesc, None): + return shortcmd + else: + return 'toggle ' + windowname + + + def Serialize(self): + choice = self.windowToggleTray + if self.windowShowRB.GetValue(): + action = "Show" + elif self.windowHideRB.GetValue(): + action = "Hide" + else: + action = "Toggle" + return { + 'window': choice.GetString(choice.GetSelection()), + 'action': action, + } + + def Deserialize(self, init): + choice = self.windowToggleTray + if window := init.get('window', ''): + if isinstance(window, int): + choice.SetSelection(window) + else: + choice.SetSelection(choice.FindString(window)) + + if choice.GetSelection() == wx.NOT_FOUND: + choice.SetSelection(0) + + action = init.get('action', '') + if action == "Show": + self.windowShowRB.SetValue(True) + elif action == "Hide": + self.windowHideRB.SetValue(True) + else: + self.windowToggleRB.SetValue(True) + + +# Must always add to this list when adding a new command class above +menuStructure = { + 'Graphics / UI' : [ + 'Attribute Monitor', + 'Buff Display Settings', + 'Graphics Settings', + 'Window Color', + 'Window Save / Load', + 'Window Toggle', + ], + 'Inspirations' : [ + 'Use Inspiration By Name', + 'Use Inspiration From Row/Column', + ], + 'Powers' : [ + 'Auto Power', + 'Power Abort', + 'Power Unqueue', + 'Use Power', + 'Use Power From Tray', + ], + 'Social' : [ + 'Away From Keyboard', + 'Chat Command', + 'Chat Command (Global)', + 'Costume Change', + 'Emote', + 'Supergroup Mode', + ], + 'Targeting' : [ + 'Target Custom', + 'Target Enemy', + 'Target Frield', + 'Team/Pet Select', + 'Unselect', + ], + 'Misc' : [ + 'Load Binds Directory', + 'Movement Commands', + ], + # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, + # but I'm leaving it here to remind myself that we do that. + } + +# Must always add to this list when adding a new command class above +commandClasses = { + 'Auto Power' : AutoPowerCmd, + 'Away From Keyboard' : AFKCmd, + 'Attribute Monitor' : AttributeMonitorCmd, + 'Buff Display Settings' : BuffDisplayCmd, + 'Chat Command' : ChatCmd, + 'Chat Command (Global)' : ChatGlobalCmd, + 'Costume Change' : CostumeChangeCmd, + 'Custom Bind' : CustomBindCmd, + 'Emote' : EmoteCmd, + 'Graphics Settings' : GraphicsCmd, + 'Load Binds Directory' : LoadBindsDir, + 'Movement Commands' : MovementCmd, + 'Power Abort' : PowerAbortCmd, + 'Power Unqueue' : PowerUnqueueCmd, + 'Supergroup Mode' : SGModeCmd, + 'Target Custom' : TargetCustomCmd, + 'Target Enemy' : TargetEnemyCmd, + 'Target Friend' : TargetFriendCmd, + 'Team/Pet Select' : TeamPetSelectCmd, + 'Unselect' : UnselectCmd, + 'Use Inspiration By Name' : UseInspByNameCmd, + 'Use Inspiration From Row/Column' : UseInspRowColCmd, + 'Use Power' : UsePowerCmd, + 'Use Power From Tray' : UsePowerFromTrayCmd, + 'Window Color' : WindowColorCmd, + 'Window Save / Load' : WindowSaveLoadCmd, + 'Window Toggle' : WindowToggleCmd, +} +# use these when we rename a commandClass so that old Profiles will still load correctly. +# If we've also updated the class, we need to try to make sure the new class will still +# Deserialize the legacy data, or at least not crash. +deprecatedCommandClasses = { + 'SG Mode Toggle' : SGModeCmd, + 'Use Insp By Name' : UseInspByNameCmd, + 'Use Insp From Row/Column' : UseInspRowColCmd, +} +commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/EmoteCmd.py b/UI/PowerBinderCommand/EmoteCmd.py new file mode 100644 index 0000000..4c02ab7 --- /dev/null +++ b/UI/PowerBinderCommand/EmoteCmd.py @@ -0,0 +1,1800 @@ +import wx +import re +import UI +import UI.EmotePicker +from UI.ControlGroup import ControlGroup +from UI.PowerPicker import PowerPicker +from Help import HelpButton +import wx.adv +from wx.adv import BitmapComboBox, EditableListBox +from pathlib import PureWindowsPath +import GameData +import Profile +from Icon import GetIcon + +class PowerBinderDialog(wx.Dialog): + def __init__(self, parent, button, init = {}): + wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) + + self.Page = parent.Page + self.EditDialog = PowerBinderEditDialog(self) + self.Button = button + self.AddStepMenu = self.makeAddStepMenu() + + sizer = wx.BoxSizer(wx.VERTICAL); + self.mainSizer = sizer + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) + # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) + # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) + #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) + AddStepButton = wx.Button(self, -1, 'Add Step') + AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) + AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) + choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) + choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) + sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) + + rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) + + self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) + self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) + self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) + rearrangeCtrl.Add(self.RearrangeList, 1) + + rearrangeButtons = wx.BoxSizer(wx.VERTICAL) + self.DelButton = wx.Button(self, -1, "Delete") + self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) + self.EditButton = wx.Button(self, -1, "Edit") + self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) + self.EditButton.Disable() + upButton = wx.Button(self, -1, "\u25B2") + upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) + downButton = wx.Button(self, -1, "\u25BC") + downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) + rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) + rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) + + sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.BindStringDisplay = wx.TextCtrl(self, -1) + self.BindStringDisplay.Disable() + choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, + wx.ALIGN_CENTER_VERTICAL) + choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) + + sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) + + sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) + + # need to dig around and get the OK button since we show this dialog modelessly now. + okButton = self.FindWindow(self.GetAffirmativeId()) + okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) + + # Wrap everything in a vbox to add some padding + vbox = wx.BoxSizer(wx.VERTICAL); + vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); + + self.SetSizerAndFit(vbox); + self.Layout() + self.Fit() + self.SetFocus() + + # if we are loading from profile, ie, have "init", build the list from it + if init: self.LoadFromData(init) + + def LoadFromData(self, init): + for item in init: + for type, data in item.items(): + commandClass = commandClasses.get(type, None) + if not commandClass: + commandClass = deprecatedCommandClasses.get(type, None) + if not commandClass: + wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") + continue + newCommand = commandClass(self.EditDialog, data) + index = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.SetClientData(index, newCommand) + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) + self.EditDialog.mainSizer.Hide(newCommand.UI) + self.UpdateBindStringDisplay() + + def SaveToData(self): + data = [] + index = 0 + for _ in self.RearrangeList.GetItems(): + # check whether we have an object already attached to this choice + cmdObject = self.RearrangeList.GetClientData(index) + commandClassName = commandRevClasses[type(cmdObject)] + data.append({commandClassName: cmdObject.Serialize()}) + index = index + 1 + return data + + def OnAddStepButton(self, evt): + button = evt.EventObject + if not self.AddStepMenu: + self.AddStepMenu = self.makeAddStepMenu() + button.PopupMenu(self.AddStepMenu) + + + def OnOKButton(self, _): + if self.Button.tgtTxtCtrl: + bindString = self.MakeBindString() + if bindString != self.Button.tgtTxtCtrl.GetValue(): + self.Button.tgtTxtCtrl.SetValue(bindString) + wx.App.Get().Main.Profile.SetModified() + self.Close() + + def OnRearrangeDelete(self, _): + current = self.RearrangeList.GetSelection() + if current == wx.NOT_FOUND: return + + self.RearrangeList.Delete(current) + self.UpdateBindStringDisplay() + + def OnRearrangeUp(self, _): + self.RearrangeList.MoveCurrentUp() + self.UpdateBindStringDisplay() + + def OnRearrangeDown(self, _): + self.RearrangeList.MoveCurrentDown() + self.UpdateBindStringDisplay() + + def OnRearrangeEdit(self, _): + index = self.RearrangeList.GetSelection() + + # check whether we have an object already attached to this choice + cmdObject = None + try: + cmdObject = self.RearrangeList.GetClientData(index) + except Exception: + pass + + if cmdObject: + self.ShowEditDialogFor(cmdObject) + self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) + else: + print("cmdObject was None") + self.UpdateBindStringDisplay() + + # OnAddStepMenu creates a new step and adds it to the rearrangelist + def OnAddStepMenu(self, evt): + menuitem = self.AddStepMenu.FindItemById(evt.GetId()) + chosenName = menuitem.GetItemLabel() + + # make a new command object, attached to the parent dialog + newCommandClass = commandClasses[chosenName] + newCommand = newCommandClass(self.EditDialog) + + # show the edit dialog if this command needs it + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) + if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): + self.EditDialog.mainSizer.Remove(newCommand.UI) + return + + newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.Select(newBindIndex) + self.RearrangeList.SetClientData(newBindIndex, newCommand) + + self.OnListSelect() + self.UpdateBindStringDisplay() + + def OnListSelect(self, _ = None): + selected = self.RearrangeList.GetSelection() + + if selected != wx.NOT_FOUND: + selCommand = self.RearrangeList.GetClientData(selected) + if selCommand.UI: + self.EditButton.Enable() + else: + self.EditButton.Disable() + + def UpdateBindStringDisplay(self): + self.BindStringDisplay.SetValue(self.MakeBindString()) + self.BindStringDisplay.SetToolTip(self.MakeBindString()) + + def MakeBindString(self): + cmdBindStrings = [] + for index in range(self.RearrangeList.GetCount()): + c = self.RearrangeList.GetClientData(index) + if c: cmdBindStrings.append(c.MakeBindString()) + + bindstring = ('$$'.join(cmdBindStrings)) + return bindstring + + def ShowEditDialogFor(self, command): + if not command.UI: return + + self.EditDialog.mainSizer.Show(command.UI) + + self.EditDialog.Layout() + self.EditDialog.Fit() + + self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') + returnval = self.EditDialog.ShowModal() + + self.EditDialog.mainSizer.Hide(command.UI) + + return returnval + + def makeAddStepMenu(self): + + stepMenu = wx.Menu() + + for subname in menuStructure: + submenu = wx.Menu() + stepMenu.AppendSubMenu(submenu, subname) + for classname in menuStructure[subname]: + submenu.Append(wx.ID_ANY, classname) + + stepMenu.Append(wx.ID_ANY, 'Custom Bind') + + return stepMenu + +class PowerBinderButton(wx.BitmapButton): + + def __init__(self, parent, tgtTxtCtrl, init = {}): + wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) + self.Init = init + self.Dialog = None + self.DialogParent = parent + + self.tgtTxtCtrl = tgtTxtCtrl + self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) + self.SetToolTip("Launch PowerBinder") + + def PowerBinderEventHandler(self, _): + self.PowerBinderDialog().Show() + + def LoadFromData(self, data): + self.PowerBinderDialog().LoadFromData(data) + + def SaveToData(self): + return self.PowerBinderDialog().SaveToData() + + def PowerBinderDialog(self): + if not self.Dialog: + self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) + return self.Dialog + + +class PowerBinderEditDialog(wx.Dialog): + def __init__(self, parent): + wx.Dialog.__init__(self, parent, -1, "Edit Step", + style = wx.DEFAULT_DIALOG_STYLE) + + outerSizer = wx.BoxSizer(wx.VERTICAL) + + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + self.mainSizer.SetMinSize([500, 150]) + + self.Page = parent.Page + + self.mainSizer.Add( + self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), + 0, wx.EXPAND|wx.ALL, 10) + + outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) + + self.SetSizerAndFit(outerSizer) + self.Layout() + self.Fit() + +########### Power Binder Command Objects +class PowerBindCmd(): + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + commandClassName = commandRevClasses[type(self)] + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{commandClassName} - {short_bindstr}" + + +####### Away From Keyboard +class AFKCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) + +####### Attribute Monitor +class AttributeMonitorCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.Groups = {} + self.AttributeTable = { + 'Base' : { + 'Current Hit Points' : 'NT H', + 'Max Hit Points' : 'X H', + 'Current Endurance' : 'T E', + 'Max Endurance' : 'X EN', + 'Regeneration Rate' : 'N RAT', + 'Recovery Rate' : 'Y RA', + 'Endurance Consumption' : 'SU', + 'ToHit Bonus' : 'T B', + 'Accuracy Bonus' : 'CC', + 'Last Hit Chance' : 'T C', + 'Damage Bonus' : 'DA', + 'Healing Bonus' : 'NG B', + 'Recharge Time Bonus' : 'ME B', + 'Endurance Discount' : 'CE DIS', + 'Stealth Radius (PvP)' : 'PVP', + 'Stealth Radius (PvE)' : 'PVE', + 'Perception Radius' : 'RC', + 'Range Bonus' : 'GE B', + 'Threat Level' : 'AT L', + 'Experience to Next Level' : 'XT', + 'Experience Debt' : 'XP', + 'Influence / Infamy' : 'INF', + 'Inherent' : 'NH', + }, + 'Movement Speed' : { + 'Flying Speed' : 'FL', + 'Jumping Speed' : 'PI', + 'Max Jump Height' : 'X J', + 'Run Speed' : 'RU', + }, + 'Damage Resistance' : { + 'Smashing Resistance' : 'G R', + 'Lethal Resistance' : 'L R', + 'Fire Resistance' : 'RE R', + 'Cold Resistance' : 'COLD R', + 'Energy Resistance' : 'DamageType[4]', + 'Negative Energy Resistance' : 'GY R', + 'Psyonic Resistance' : 'NIC R', + 'Toxic Resistance' : 'XIC R', + }, + 'Defense' : { + 'Base Defense' : 'BAS', + 'Ranged Defense' : 'ED', + 'Melee Defense' : 'MEL', + 'AoE Defense' : '2', + 'Smashing Defense' : '3', + 'Lethal Defense' : '4', + 'Fire Defense' : '5', + 'Cold Defense' : '6', + 'Energy Defense' : '7', + 'Negative Energy Defense' : '8', + 'Psionic Defense' : '9', + 'Toxic Defense' : '1', + }, + 'Debuff Resistance' : { + 'Regeneration Resistance' : 'ON R', + 'Recovery Resistance' : 'RY R', + 'To Hit Resistance' : 'IT R', + 'Defense Resistance' : 'NSE RES', + }, + 'Status Effect Protection' : { + 'Hold Protection' : 'D P', + 'Immobilize Protection' : 'LIZE P', + 'Stun Protection' : 'N P', + 'Sleep Protection' : 'P P', + 'Knockback Protection' : 'K P', + 'Confuse Protection' : 'SE P', + 'Terrorize Protection' : 'ZE P', + 'Repel Protection' : 'EL P', + 'Teleport Protection' : 'T P', + }, + 'Status Effect Resistance' : { + 'Hold Resistance' : 'D R', + 'Immobilize Resistance' : 'LIZE R', + 'Stun Resistance' : 'N R', + 'Sleep Resistance' : 'P R', + 'Knockback Resistance' : 'K R', + 'Confuse Resistance' : 'SE R', + 'Terrorize Resistance' : 'ZE R', + 'Placate Resistance' : 'TE R', + 'Taunt Resistance' : 'NT R', + }, + 'Miscellaneous' : { + 'Level Shift' : 'L S', + }, + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.AttributeMenu = wx.Menu() + for group, controls in self.AttributeTable.items(): + submenu = wx.Menu() + self.AttributeMenu.AppendSubMenu(submenu, group) + for cb in controls: + submenu.Append(wx.ID_ANY, cb) + + self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) + + self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) + groupSizer.Add(self.editbox) + + newButton = self.editbox.GetNewButton() + newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) + + return groupSizer + + def MakeBindString(self): + map = {} + bindstrings = [] + for _, controls in self.AttributeTable.items(): + for cb, data in controls.items(): + map[cb] = data + + for string in self.editbox.GetStrings(): + if string: + bindstrings.append(f'monitorattribute {map[string]}') + + return '$$'.join(bindstrings) + + def Serialize(self): + return { + 'attributes' : self.editbox.GetStrings() + } + + def Deserialize(self, init): + self.editbox.SetStrings(init.get('attributes', [])) + + def OnNewButton(self, evt): + evt.GetEventObject().PopupMenu(self.AttributeMenu) + + def OnMenuItem(self, evt): + menuitem = evt.EventObject.FindItemById(evt.GetId()) + existingstrings = self.editbox.GetStrings() + existingstrings.append(menuitem.GetItemLabel()) + self.editbox.SetStrings(existingstrings) + +####### Auto Power +class AutoPowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) + autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.autoPowerName = PowerPicker(dialog) + autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) + + return autoPowerSizer + + def MakeBindString(self): + return f"powexecauto {self.autoPowerName.GetLabel()}" + + def Serialize(self): + return { + 'pname' : self.autoPowerName.GetLabel(), + 'picon' : self.autoPowerName.IconFilename + } + + def Deserialize(self, init): + if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) + +####### Buff Display Command +class BuffDisplayCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.buffDisplayMap = { + 'Status Window' : { + 'Hide Auto' : 1, + 'Hide Toggles' : 2, + 'No Blinking' : 4, + 'No Stacking' : 8, + 'Numeric Stacking' : 16, + 'Hide Buff Numbers' : 32, + 'Stop Sending Buffs' : 64, + }, + 'Group Window' : { + 'Hide Auto' : 256, + 'Hide Toggles' : 512, + 'No Blinking' : 1024, + 'No Stacking' : 2048, + 'Numeric Stacking' : 4096, + 'Hide Buff Numbers' : 8192, + 'Stop Sending Buffs' : 16384, + }, + 'Pet Window' : { + 'Hide Auto' : 65536, + 'Hide Toggles' : 131072, + 'No Blinking' : 262144, + 'No Stacking' : 524288, + 'Numeric Stacking' : 1048576, + 'Hide Buff Numbers' : 2097152, + 'Stop Sending Buffs' : 4194304, + }, + } + self.Groups = {} + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + for group, controls in self.buffDisplayMap.items(): + self.Groups[group] = ControlGroup(dialog, self.Page, label = group) + groupid = self.Groups[group].GetStaticBox().GetId() + for cb, data in controls.items(): + self.Groups[group].AddControl( + ctlType = 'checkbox', + ctlName = f"{groupid}_{group}_{cb}", + label = cb, + data = data, + ) + + groupSizer.Add(self.Groups[group]) + + return groupSizer + + def CalculateValue(self): + page = wx.App.Get().Main.Profile.CustomBinds + + total = 0 + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] + if checkbox.IsChecked(): + total = total + checkbox.Data + return total + + def MakeBindString(self): + return f"optionset buffsettings {self.CalculateValue()}" + + def Serialize(self): + return { 'value' : self.CalculateValue() } + + def Deserialize(self, init): + value = init.get('value', 0) + + value = value or 0 # in case we had for some reason 'None' stashed in the init values + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] + checkbox.SetValue( checkbox.Data & value ) + +####### Chat Command +class ChatCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.chatChannelMap = { # before __init__ + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + chatCommandSizer = wx.GridBagSizer(5, 5) + self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") + chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) + # row 1 + self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) + self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) + self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) + # row 2 + self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) + self.chatCommandDuration.SetRange(1, 20) + self.chatCommandDuration.SetValue(7) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandDuration, (2,1)) + self.chatCommandChatSize = wx.Choice(dialog, -1, + choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) + self.chatCommandChatSize.SetSelection(5) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) + self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) + self.chatCommandChannel.SetSelection(0) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChannel, (2,5)) + # row 3 + self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") + chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) + self.chatCommandMessage = wx.TextCtrl(dialog, -1) + self.chatCommandMessage.SetHint('Chat Command Text') + chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) + + return chatCommandSizer + + def MakeBindString(self): + duration = self.chatCommandDuration.GetValue() + + choice = self.chatCommandChatSize + index = choice.GetSelection() + size = choice.GetString(index) + + duration = f"" if duration != 7 else "" + size = f"" if size != "1" else "" + + bdcolor = fgcolor = bgcolor = '' + if self.chatCommandUseColorsCB.IsChecked(): + bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + + bdcolor = f"" + fgcolor = f"" + bgcolor = f"" + + beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' + text = self.chatCommandMessage.GetValue() + + choice = self.chatCommandChannel + index = choice.GetSelection() + channel = choice.GetString(index) + + return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" + + def Serialize(self): + return { + 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), + 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), + 'channel' : self.chatCommandChannel .GetSelection(), + 'size' : self.chatCommandChatSize.GetSelection(), + 'duration' : self.chatCommandDuration.GetValue(), + 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'text' : self.chatCommandMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) + if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) + if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) + if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) + if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) + if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) + if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) + if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) + if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) + + +####### Chat Command Global +class ChatGlobalCmd(PowerBindCmd): + def BuildUI(self, dialog): + chatCommandGlobalSizer = wx.GridBagSizer(5,5) + + self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") + chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) + + self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalChannel.SetHint("Channel") + chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) + + self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') + chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) + + chatCommandGlobalSizer.AddGrowableCol(1) + + return chatCommandGlobalSizer + + def MakeBindString(self): + useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() + channel = self.chatCommandGlobalChannel.GetValue() + message = self.chatCommandGlobalMessage.GetValue() + + preface = "beginchat /" if useBeginchat else "" + + return f'{preface}send "{channel}" {message}' + + def Serialize(self): + return { + 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), + 'channel' : self.chatCommandGlobalChannel.GetValue(), + 'message' : self.chatCommandGlobalMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) + if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) + if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) + +#######Costume Change +class CostumeChangeCmd(PowerBindCmd): + def BuildUI(self, dialog): + costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeCostume = wx.Choice(dialog, -1, + choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) + self.costumeChangeCostume.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeEmote = wx.Choice(dialog, -1, + choices = GameData.Emotes['costumechange']) + self.costumeChangeEmote.Insert("- None -", 0) + self.costumeChangeEmote.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return costumeChangeSizer + + def MakeBindString(self): + costumeNumber = self.costumeChangeCostume.GetSelection() + costumeEmote = self.costumeChangeEmote.GetSelection() + + if costumeEmote: # None, or 0 == "- None -" + ccCmd = 'cce' + emoteName = self.costumeChangeEmote.GetString(costumeEmote) + emoteName = " CC" + emoteName.replace(" ","") + else: + ccCmd = 'cc' + emoteName = '' + + return f"{ccCmd} {costumeNumber}{emoteName}" + + def Serialize(self): + return{ + 'costumeNumber': self.costumeChangeCostume.GetSelection(), + 'costumeEmote' : self.costumeChangeEmote.GetSelection(), + } + + def Deserialize(self, init): + if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) + if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) + +####### Movement Command +class MovementCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + self.plusbutton.SetValue(True) + + self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.commandchoice = wx.Choice(dialog, choices = [ + "forward", "left", "right", "backward", "up", "down", + "turnleft", "turnright", "first", "autorun", "clicktomove", + ],) + sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) + self.commandchoice.SetSelection(0) + + self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + pre = post = '' + if self.plusbutton.GetValue() : pre = "+" + elif self.plusplusbutton.GetValue() : pre = "++" + elif self.minusbutton.GetValue() : pre = "-" + elif self.zerobutton.GetValue() : post = " 0" + elif self.onebutton.GetValue() : post = " 1" + + command = self.commandchoice.GetString(self.commandchoice.GetSelection()) + + return f"{pre}{command}{post}" + + def Serialize(self): + mod = '' + if self.plusbutton.GetValue() : mod = "plus" + elif self.plusplusbutton.GetValue() : mod = "plusplus" + elif self.minusbutton.GetValue() : mod = "minus" + elif self.zerobutton.GetValue() : mod = "zero" + elif self.onebutton.GetValue() : mod = "one" + + return { + 'mod' : mod, + 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), + } + + def Deserialize(self, init): + mod = init.get('mod', 'plus') + + if mod == 'plus' : self.plusbutton.SetValue(True) + elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) + elif mod == 'minus' : self.minusbutton.SetValue(True) + elif mod == 'zero' : self.zerobutton.SetValue(True) + elif mod == 'one' : self.onebutton.SetValue(True) + + self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) + +####### Graphics Command +class GraphicsCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.FlexGridSizer(2) + + self.visscalecb = wx.CheckBox(dialog, label = "visscale") + sizer.Add(self.visscalecb) + self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) + sizer.Add(self.visscalesc) + + self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") + sizer.Add(self.dofweightcb) + self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) + sizer.Add(self.dofweightsc) + + self.fsaacb = wx.CheckBox(dialog, label = "fsaa") + sizer.Add(self.fsaacb) + self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) + self.fsaach.SetSelection(0) + sizer.Add(self.fsaach) + + self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") + sizer.Add(self.bloomscalecb) + self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) + self.bloomscalech.SetSelection(0) + sizer.Add(self.bloomscalech) + + self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") + sizer.Add(self.bloomweightcb) + self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) + sizer.Add(self.bloomweightsc) + + self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") + sizer.Add(self.lodbiascb) + self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) + sizer.Add(self.lodbiassc) + + self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") + sizer.Add(self.renderscalecb) + self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) + sizer.Add(self.renderscalesc) + + return sizer + + def MakeBindString(self): + # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. + bindstrings = [] + if self.visscalecb.IsChecked(): + bindstrings.append("visscale " + str(self.visscalesc.GetValue())) + if self.dofweightcb.IsChecked(): + bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) + if self.fsaacb.IsChecked(): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bindstrings.append("fsaa " + fsaavalue) + if self.bloomscalecb.IsChecked(): + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + bindstrings.append("bloomscale " + bloomscalevalue) + if self.bloomweightcb.IsChecked(): + bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) + if self.lodbiascb.IsChecked(): + bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) + if self.renderscalecb.IsChecked(): + bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) + + return '$$'.join(bindstrings) + + def Serialize(self): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + return { + 'visscalecb' : self.visscalecb.IsChecked(), + 'visscalesc' : self.visscalesc.GetValue(), + 'dofweightcb' : self.dofweightcb.IsChecked(), + 'dofweightsc' : self.dofweightsc.GetValue(), + 'fsaacb' : self.fsaacb.IsChecked(), + 'fsaach' : fsaavalue, + 'bloomscalecb' : self.bloomscalecb.IsChecked(), + 'bloomscalech' : bloomscalevalue, + 'bloomweightcb' : self.bloomweightcb.IsChecked(), + 'bloomweightsc' : self.bloomweightsc.GetValue(), + 'lodbiascb' : self.lodbiascb.IsChecked(), + 'lodbiassc' : self.lodbiassc.GetValue(), + 'renderscalecb' : self.renderscalecb.IsChecked(), + 'renderscalesc' : self.renderscalesc.GetValue(), + } + + def Deserialize(self, init): + self.visscalecb.SetValue(init.get('visscalecb', False)) + self.visscalesc.SetValue(init.get('visscalesc', 1.0)) + self.dofweightcb.SetValue(init.get('dofweightcb', False)) + self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) + self.fsaacb.SetValue(init.get('fsaacb', False)) + self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) + self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) + self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) + self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) + self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) + self.lodbiascb.SetValue(init.get('lodbiascb', False)) + self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) + self.renderscalecb.SetValue(init.get('renderscalecb', False)) + self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) + +####### Custom Bind +class CustomBindCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.customBindName = wx.TextCtrl(dialog, -1) + self.customBindName.SetHint('Custom Bind Text') + sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + return self.customBindName.GetValue() + + def Serialize(self): + return { 'customBindName': self.customBindName.GetValue() } + + def Deserialize(self,init): + if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) + +####### Emote +class EmoteCmd(PowerBindCmd): + def BuildUI(self, dialog): + emoteSizer = wx.BoxSizer(wx.HORIZONTAL) + self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") + emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + self.emoteName = wx.Button(dialog, -1, "...") + self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) + emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) + + return emoteSizer + + def MakeBindString(self): + displayedEmoteName = self.emoteName.GetLabel() + actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] + + return actualEmotePayload + + def Serialize(self): + return {'emoteName': self.emoteName.GetLabel()} + + def Deserialize(self, init): + if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) + +####### Load Binds Directory +class LoadBindsDir(PowerBindCmd): + def BuildUI(self, dialog): + mainSizer = wx.BoxSizer(wx.VERTICAL) + + lbSizer = wx.BoxSizer(wx.HORIZONTAL) + lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") + lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + profiles = Profile.GetAllProfileBindsDirs() + + self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) + lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") + self.lbResetCB.SetValue(True) + + mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + return mainSizer + + def MakeBindString(self): + + # If the specified binds directory disappeared between runs, we'd crash, so handle that. + if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' + + config = wx.ConfigBase.Get() + if config.Exists('GameBindPath'): + bindpath = config.Read('GameBindPath') + else: + bindpath = config.Read('BindPath') + + reset = "" + if self.lbResetCB.GetValue(): + reset = "keybind_reset$$" + + resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' + return reset + 'bindloadfile ' + str(resetfilepath) + + def Serialize(self): + return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), + 'ResetKeybinds' : self.lbResetCB.GetValue(), + } + + def Deserialize(self, init): + if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) + self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) + +####### Power Abort +class PowerAbortCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecabort' + +####### Power Unqueue +class PowerUnqueueCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecunqueue' + +####### SG Mode +class SGModeCmd(PowerBindCmd): + def BuildUI(self, dialog): + sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) + sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") + self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") + + sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) + + return sgmodeSizer + + def MakeBindString(self): + if self.sgmodeOnRB.GetValue(): + return 'sgmodeset 1' + elif self.sgmodeOffRB.GetValue(): + return 'sgmodeset 0' + else: + return 'sgmode' + + def Serialize(self): + if self.sgmodeOnRB.GetValue(): + val = "On" + elif self.sgmodeOffRB.GetValue(): + val = "Off" + else: + val = "Toggle" + + return {"value" : val} + + def Deserialize(self, init): + val = init.get('value', '') + if val == "On": + self.sgmodeOnRB.SetValue(True) + elif val == "Off": + self.sgmodeOffRB.SetValue(True) + else: + self.sgmodeToggleRB.SetValue(True) + +####### Target Custom +class TargetCustomCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetCustomSizer = wx.GridBagSizer(5,5) + targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), + flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) + self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetCustomModeChoice.SetSelection(0) + targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) + self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) + self.targetCustomOptionalName.SetHint("Optional name to match") + targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) + self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") + targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) + self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") + targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) + self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") + targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) + self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") + targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) + self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") + targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) + self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") + targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) + self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") + targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) + self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") + targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) + + targetCustomSizer.AddGrowableCol(2) + + return targetCustomSizer + + def MakeBindString(self): + choice = self.targetCustomModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + targetCommand = "targetcustom" + mode.lower() + + enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" + friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" + defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" + alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" + mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" + notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" + base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" + notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" + + name = self.targetCustomOptionalName.GetValue() + + return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" + + def Serialize(self): + return { + 'mode' : self.targetCustomModeChoice.GetSelection(), + 'enemy' : self.targetCustomCBEnemies. IsChecked(), + 'friend' : self.targetCustomCBFriends. IsChecked(), + 'defeated' : self.targetCustomCBDefeated. IsChecked(), + 'alive' : self.targetCustomCBAlive. IsChecked(), + 'mypet' : self.targetCustomCBMyPets. IsChecked(), + 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), + 'base' : self.targetCustomCBBaseItems. IsChecked(), + 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), + 'name' : self.targetCustomOptionalName.GetValue(), + } + + def Deserialize(self, init): + if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) + if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) + if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) + if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) + if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) + if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) + if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) + if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) + if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) + if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) + + +####### Target Enemy +class TargetEnemyCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) + targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetEnemyModeChoice.SetSelection(0) + targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetEnemySizer + + def MakeBindString(self): + choice = self.targetEnemyModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetenemy" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetEnemyModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) + +####### Target Friend +class TargetFriendCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) + targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetFriendModeChoice.SetSelection(0) + targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetFriendSizer + + def MakeBindString(self): + choice = self.targetFriendModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetfriend" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetFriendModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) + +####### Team/Pet Select +class TeamPetSelectCmd(PowerBindCmd): + def BuildUI(self, dialog): + teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], + style=wx.ALIGN_CENTER_VERTICAL) + self.teamPetSelectNumber.SetSelection(0) + teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) + + return teamPetSelectSizer + + def MakeBindString(self): + teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' + targetNumber = self.teamPetSelectNumber.GetSelection()+1 + + return f"{teamOrPet}select {targetNumber}" + + def Serialize(self): + return { + 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', + 'targetNum': self.teamPetSelectNumber.GetSelection(), + } + + def Deserialize(self, init): + ToP = init.get('teamOrPet', '') + if ToP == 'pet': + self.teamPetSelectPetRB.SetValue(True) + else: + self.teamPetSelectTeamRB.SetValue(True) + if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) + +####### Unselect +class UnselectCmd(PowerBindCmd): + def MakeBindString(self): + return 'unselect' + +####### Use Insp By Name +class UseInspByNameCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) + for _, types in GameData.Inspirations.items(): + for _, info in types.items(): + for insp in info['tiers']: + name = re.sub(' ', '', str(insp)) + icon = GetIcon(f'Inspirations/{name}') + self.useInspByNameModeChoice.Append(insp, icon) + self.useInspByNameModeChoice.SetSelection(0) + useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) + + return useInspByNameSizer + + def MakeBindString(self): + choice = self.useInspByNameModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "inspexecname " + mode.lower() + + def GetAllInsps(self): + Insplist = [] + for _, info in GameData.Inspirations.items(): + for insp in info['tiers']: + Insplist.append(insp) + Insplist.append("---") + Insplist.pop(-1) # snip the terminal "---" + + return Insplist + + def Serialize(self): + return { 'insp' : self.useInspByNameModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) + +####### Use Insp From Row / Column +class UseInspRowColCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnRow.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) + self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnCol.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) + + return useInspRowColumnSizer + + def MakeBindString(self): + row = self.useInspRowColumnRow.GetSelection()+1 + col = self.useInspRowColumnCol.GetSelection()+1 + + return f"inspexectray {col} {row}" + + def Serialize(self): + return { + 'col' : self.useInspRowColumnCol.GetSelection(), + 'row' : self.useInspRowColumnRow.GetSelection(), + } + + def Deserialize(self, init): + if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) + if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) + +####### Use Power +class UsePowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + outerSizer = wx.BoxSizer(wx.HORIZONTAL) + + usePowerSizer = wx.GridBagSizer(5,5) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBToggle, (0,1)) + self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOn, (0,2)) + self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOff, (0,3)) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerName = PowerPicker(dialog) + usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) + usePowerSizer.AddGrowableCol(3) + + outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) + + return outerSizer + + def MakeBindString(self): + if self.usePowerRBToggle.GetValue(): + method = "powexecname" + elif self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') + return '' + + return f"{method} {self.usePowerName.GetLabel()}" + + def Serialize(self): + if self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + method = "powexecname" + return { + 'method': method, + 'pname' : self.usePowerName.GetLabel(), + 'picon' : self.usePowerName.IconFilename + } + + def Deserialize(self, init): + method = init.get('method', '') + if method == 'powexectoggleon': + self.usePowerRBOn.SetValue(True) + elif method == 'powexectoggleoff': + self.usePowerRBOff.SetValue(True) + else: + self.usePowerRBToggle.SetValue(True) + if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) + +####### Use Power From Tray +class UsePowerFromTrayCmd(PowerBindCmd): + def BuildUI(self, dialog): + usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTrayTray = wx.Choice(dialog, -1, + choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', + 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) + self.usePowerFromTrayTray.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) + self.usePowerFromTraySlot.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return usePowerFromTraySizer + + def MakeBindString(self): + choice = self.usePowerFromTrayTray + tray = choice.GetSelection() + + choice = self.usePowerFromTraySlot + slot = choice.GetSelection()+1 + + mode = "slot" + mode2 = '' + if tray > 3: + mode = "tray" + mode2 = f" {tray - 3}" + elif tray == 3: + mode = "alt2slot" + elif tray == 2: + mode = "altslot" + + return f"powexec{mode} {slot}{mode2}" + + def Serialize(self): + return { + 'tray' : self.usePowerFromTrayTray.GetSelection(), + 'slot' : self.usePowerFromTraySlot.GetSelection(), + } + + def Deserialize(self, init): + if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) + if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) + +####### Window Color +class WindowColorCmd(PowerBindCmd): + def BuildUI(self, dialog): + windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) + borderSizer = wx.BoxSizer(wx.VERTICAL) + self.ColorBorder.SetSizer(borderSizer) + self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) + borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) + + windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) + + RGBASizer = wx.FlexGridSizer(3, 4, 5) + + RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) + self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) + self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + windowColorSizer.Add(RGBASizer) + + self.UpdateFromSlider() + + return windowColorSizer + + def MakeBindString(self): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + return f"windowcolor {Rval} {Gval} {Bval} {Aval}" + + def Serialize(self): + return { + 'Rval' : self.RSlider.GetValue(), + 'Gval' : self.GSlider.GetValue(), + 'Bval' : self.BSlider.GetValue(), + 'Aval' : self.ASlider.GetValue(), + } + + def Deserialize(self, init): + self.RSlider.SetValue(init['Rval']) + self.GSlider.SetValue(init['Gval']) + self.BSlider.SetValue(init['Bval']) + self.ASlider.SetValue(init['Aval']) + self.UpdateFromSlider() + + def UpdateFromSlider(self, _ = None): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RReadout.SetValue(Rval) + self.GReadout.SetValue(Gval) + self.BReadout.SetValue(Bval) + self.AReadout.SetValue(Aval) + self.ColorBorder.Refresh() + + def UpdateFromText(self, _ = None): + Rval = self.RReadout.GetValue() + Gval = self.GReadout.GetValue() + Bval = self.BReadout.GetValue() + Aval = self.AReadout.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RSlider.SetValue(Rval) + self.GSlider.SetValue(Gval) + self.BSlider.SetValue(Bval) + self.ASlider.SetValue(Aval) + self.ColorBorder.Refresh() + +####### Window Save / Load +class WindowSaveLoadCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) + self.CommandChoice.SetSelection(0) + sizer.Add(self.CommandChoice, 0, wx.ALL, 5) + + self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), + value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) + sizer.Add(self.FilePath, 0, wx.ALL, 5) + + return sizer + + def MakeBindString(self): + command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] + return f'{command} "{self.FilePath.GetValue()}"' + + def Serialize(self): + return { + 'command' : self.CommandChoice.GetSelection(), + 'filename' : self.FilePath.GetValue(), + } + + def Deserialize(self, init): + self.CommandChoice.SetSelection(init.get('command', 0)) + self.FilePath.SetValue(init.get('filename', '')) + +####### Window Toggle +class WindowToggleCmd(PowerBindCmd): + def BuildUI(self, dialog): + self.WindowNames = { + 'Actions' : 'actions', + 'Auction House' : 'ah', + 'Badge' : 'badge', + 'Channel Search' : 'chansearch', + 'Chat' : 'chat', + 'Custom Chat 1' : 'chat1', + 'Custom Chat 2' : 'chat2', + 'Custom Chat 3' : 'chat3', + 'Custom Chat 4' : 'chat4', + 'Clues' : 'clue', + 'Combat Numbers' : 'combatnumbers', + 'Contacts' : 'contact', + 'Contact Finder' : 'contactfinder', + 'Costumes' : 'costume', + 'Email' : 'email', + 'Enhancements' : 'enhancements', + 'Friends' : 'friend', + 'Group' : 'group', + 'Help' : 'helpwindow', + 'Incarnate' : 'incarnate', + 'Inspirations' : 'insp', + 'League' : 'league', + 'LFG' : 'lfg', + 'Map' : 'map', + 'Mission' : 'mission', + 'Nav / Compass' : 'nav', + 'Options' : 'options', + 'Pets' : 'pet', + 'Petition' : 'petition', + 'Power Tray' : 'powers', + 'Power List' : 'powerlist', + 'Quit' : 'quit', + 'Recipes' : 'recipe', + 'Salvage' : 'salvage', + 'Search' : 'search', + 'Supergroup' : 'sg', + 'Target' : 'target', + 'Team' : 'team', + 'Tray' : 'tray', + 'Tray1' : 'tray1', + 'Tray2' : 'tray2', + 'Tray3' : 'tray3', + 'Tray4' : 'tray4', + 'Tray5' : 'tray5', + 'Tray6' : 'tray6', + 'Tray7' : 'tray7', + 'Tray8' : 'tray8', + 'Vault' : 'vault', + } + + self.ShortToggleCommands = { + 'Auction House' : 'ah', + 'Chat' : 'chat', + 'Help' : 'helpwindow', + 'Map' : 'map', + 'Nav / Compass' : 'nav', + 'Power Tray' : 'powers', + 'Target' : 'target', + 'Tray' : 'tray', + } + + windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) + windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) + self.windowToggleTray.SetSelection(0) + windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.windowShowRB = wx.RadioButton(dialog, -1, "Show") + self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") + + windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) + + return windowToggleSizer + + def MakeBindString(self): + choice = self.windowToggleTray + index = choice.GetSelection() + windowdesc = choice.GetString(index) + windowname = self.WindowNames[windowdesc] + + if self.windowShowRB.GetValue(): + return 'show ' + windowname + elif self.windowHideRB.GetValue(): + return 'windowhide ' + windowname + else: + if shortcmd := self.ShortToggleCommands.get(windowdesc, None): + return shortcmd + else: + return 'toggle ' + windowname + + + def Serialize(self): + choice = self.windowToggleTray + if self.windowShowRB.GetValue(): + action = "Show" + elif self.windowHideRB.GetValue(): + action = "Hide" + else: + action = "Toggle" + return { + 'window': choice.GetString(choice.GetSelection()), + 'action': action, + } + + def Deserialize(self, init): + choice = self.windowToggleTray + if window := init.get('window', ''): + if isinstance(window, int): + choice.SetSelection(window) + else: + choice.SetSelection(choice.FindString(window)) + + if choice.GetSelection() == wx.NOT_FOUND: + choice.SetSelection(0) + + action = init.get('action', '') + if action == "Show": + self.windowShowRB.SetValue(True) + elif action == "Hide": + self.windowHideRB.SetValue(True) + else: + self.windowToggleRB.SetValue(True) + + +# Must always add to this list when adding a new command class above +menuStructure = { + 'Graphics / UI' : [ + 'Attribute Monitor', + 'Buff Display Settings', + 'Graphics Settings', + 'Window Color', + 'Window Save / Load', + 'Window Toggle', + ], + 'Inspirations' : [ + 'Use Inspiration By Name', + 'Use Inspiration From Row/Column', + ], + 'Powers' : [ + 'Auto Power', + 'Power Abort', + 'Power Unqueue', + 'Use Power', + 'Use Power From Tray', + ], + 'Social' : [ + 'Away From Keyboard', + 'Chat Command', + 'Chat Command (Global)', + 'Costume Change', + 'Emote', + 'Supergroup Mode', + ], + 'Targeting' : [ + 'Target Custom', + 'Target Enemy', + 'Target Frield', + 'Team/Pet Select', + 'Unselect', + ], + 'Misc' : [ + 'Load Binds Directory', + 'Movement Commands', + ], + # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, + # but I'm leaving it here to remind myself that we do that. + } + +# Must always add to this list when adding a new command class above +commandClasses = { + 'Auto Power' : AutoPowerCmd, + 'Away From Keyboard' : AFKCmd, + 'Attribute Monitor' : AttributeMonitorCmd, + 'Buff Display Settings' : BuffDisplayCmd, + 'Chat Command' : ChatCmd, + 'Chat Command (Global)' : ChatGlobalCmd, + 'Costume Change' : CostumeChangeCmd, + 'Custom Bind' : CustomBindCmd, + 'Emote' : EmoteCmd, + 'Graphics Settings' : GraphicsCmd, + 'Load Binds Directory' : LoadBindsDir, + 'Movement Commands' : MovementCmd, + 'Power Abort' : PowerAbortCmd, + 'Power Unqueue' : PowerUnqueueCmd, + 'Supergroup Mode' : SGModeCmd, + 'Target Custom' : TargetCustomCmd, + 'Target Enemy' : TargetEnemyCmd, + 'Target Friend' : TargetFriendCmd, + 'Team/Pet Select' : TeamPetSelectCmd, + 'Unselect' : UnselectCmd, + 'Use Inspiration By Name' : UseInspByNameCmd, + 'Use Inspiration From Row/Column' : UseInspRowColCmd, + 'Use Power' : UsePowerCmd, + 'Use Power From Tray' : UsePowerFromTrayCmd, + 'Window Color' : WindowColorCmd, + 'Window Save / Load' : WindowSaveLoadCmd, + 'Window Toggle' : WindowToggleCmd, +} +# use these when we rename a commandClass so that old Profiles will still load correctly. +# If we've also updated the class, we need to try to make sure the new class will still +# Deserialize the legacy data, or at least not crash. +deprecatedCommandClasses = { + 'SG Mode Toggle' : SGModeCmd, + 'Use Insp By Name' : UseInspByNameCmd, + 'Use Insp From Row/Column' : UseInspRowColCmd, +} +commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/GraphicsCmd.py b/UI/PowerBinderCommand/GraphicsCmd.py new file mode 100644 index 0000000..4c02ab7 --- /dev/null +++ b/UI/PowerBinderCommand/GraphicsCmd.py @@ -0,0 +1,1800 @@ +import wx +import re +import UI +import UI.EmotePicker +from UI.ControlGroup import ControlGroup +from UI.PowerPicker import PowerPicker +from Help import HelpButton +import wx.adv +from wx.adv import BitmapComboBox, EditableListBox +from pathlib import PureWindowsPath +import GameData +import Profile +from Icon import GetIcon + +class PowerBinderDialog(wx.Dialog): + def __init__(self, parent, button, init = {}): + wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) + + self.Page = parent.Page + self.EditDialog = PowerBinderEditDialog(self) + self.Button = button + self.AddStepMenu = self.makeAddStepMenu() + + sizer = wx.BoxSizer(wx.VERTICAL); + self.mainSizer = sizer + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) + # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) + # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) + #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) + AddStepButton = wx.Button(self, -1, 'Add Step') + AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) + AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) + choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) + choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) + sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) + + rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) + + self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) + self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) + self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) + rearrangeCtrl.Add(self.RearrangeList, 1) + + rearrangeButtons = wx.BoxSizer(wx.VERTICAL) + self.DelButton = wx.Button(self, -1, "Delete") + self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) + self.EditButton = wx.Button(self, -1, "Edit") + self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) + self.EditButton.Disable() + upButton = wx.Button(self, -1, "\u25B2") + upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) + downButton = wx.Button(self, -1, "\u25BC") + downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) + rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) + rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) + + sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.BindStringDisplay = wx.TextCtrl(self, -1) + self.BindStringDisplay.Disable() + choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, + wx.ALIGN_CENTER_VERTICAL) + choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) + + sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) + + sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) + + # need to dig around and get the OK button since we show this dialog modelessly now. + okButton = self.FindWindow(self.GetAffirmativeId()) + okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) + + # Wrap everything in a vbox to add some padding + vbox = wx.BoxSizer(wx.VERTICAL); + vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); + + self.SetSizerAndFit(vbox); + self.Layout() + self.Fit() + self.SetFocus() + + # if we are loading from profile, ie, have "init", build the list from it + if init: self.LoadFromData(init) + + def LoadFromData(self, init): + for item in init: + for type, data in item.items(): + commandClass = commandClasses.get(type, None) + if not commandClass: + commandClass = deprecatedCommandClasses.get(type, None) + if not commandClass: + wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") + continue + newCommand = commandClass(self.EditDialog, data) + index = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.SetClientData(index, newCommand) + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) + self.EditDialog.mainSizer.Hide(newCommand.UI) + self.UpdateBindStringDisplay() + + def SaveToData(self): + data = [] + index = 0 + for _ in self.RearrangeList.GetItems(): + # check whether we have an object already attached to this choice + cmdObject = self.RearrangeList.GetClientData(index) + commandClassName = commandRevClasses[type(cmdObject)] + data.append({commandClassName: cmdObject.Serialize()}) + index = index + 1 + return data + + def OnAddStepButton(self, evt): + button = evt.EventObject + if not self.AddStepMenu: + self.AddStepMenu = self.makeAddStepMenu() + button.PopupMenu(self.AddStepMenu) + + + def OnOKButton(self, _): + if self.Button.tgtTxtCtrl: + bindString = self.MakeBindString() + if bindString != self.Button.tgtTxtCtrl.GetValue(): + self.Button.tgtTxtCtrl.SetValue(bindString) + wx.App.Get().Main.Profile.SetModified() + self.Close() + + def OnRearrangeDelete(self, _): + current = self.RearrangeList.GetSelection() + if current == wx.NOT_FOUND: return + + self.RearrangeList.Delete(current) + self.UpdateBindStringDisplay() + + def OnRearrangeUp(self, _): + self.RearrangeList.MoveCurrentUp() + self.UpdateBindStringDisplay() + + def OnRearrangeDown(self, _): + self.RearrangeList.MoveCurrentDown() + self.UpdateBindStringDisplay() + + def OnRearrangeEdit(self, _): + index = self.RearrangeList.GetSelection() + + # check whether we have an object already attached to this choice + cmdObject = None + try: + cmdObject = self.RearrangeList.GetClientData(index) + except Exception: + pass + + if cmdObject: + self.ShowEditDialogFor(cmdObject) + self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) + else: + print("cmdObject was None") + self.UpdateBindStringDisplay() + + # OnAddStepMenu creates a new step and adds it to the rearrangelist + def OnAddStepMenu(self, evt): + menuitem = self.AddStepMenu.FindItemById(evt.GetId()) + chosenName = menuitem.GetItemLabel() + + # make a new command object, attached to the parent dialog + newCommandClass = commandClasses[chosenName] + newCommand = newCommandClass(self.EditDialog) + + # show the edit dialog if this command needs it + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) + if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): + self.EditDialog.mainSizer.Remove(newCommand.UI) + return + + newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.Select(newBindIndex) + self.RearrangeList.SetClientData(newBindIndex, newCommand) + + self.OnListSelect() + self.UpdateBindStringDisplay() + + def OnListSelect(self, _ = None): + selected = self.RearrangeList.GetSelection() + + if selected != wx.NOT_FOUND: + selCommand = self.RearrangeList.GetClientData(selected) + if selCommand.UI: + self.EditButton.Enable() + else: + self.EditButton.Disable() + + def UpdateBindStringDisplay(self): + self.BindStringDisplay.SetValue(self.MakeBindString()) + self.BindStringDisplay.SetToolTip(self.MakeBindString()) + + def MakeBindString(self): + cmdBindStrings = [] + for index in range(self.RearrangeList.GetCount()): + c = self.RearrangeList.GetClientData(index) + if c: cmdBindStrings.append(c.MakeBindString()) + + bindstring = ('$$'.join(cmdBindStrings)) + return bindstring + + def ShowEditDialogFor(self, command): + if not command.UI: return + + self.EditDialog.mainSizer.Show(command.UI) + + self.EditDialog.Layout() + self.EditDialog.Fit() + + self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') + returnval = self.EditDialog.ShowModal() + + self.EditDialog.mainSizer.Hide(command.UI) + + return returnval + + def makeAddStepMenu(self): + + stepMenu = wx.Menu() + + for subname in menuStructure: + submenu = wx.Menu() + stepMenu.AppendSubMenu(submenu, subname) + for classname in menuStructure[subname]: + submenu.Append(wx.ID_ANY, classname) + + stepMenu.Append(wx.ID_ANY, 'Custom Bind') + + return stepMenu + +class PowerBinderButton(wx.BitmapButton): + + def __init__(self, parent, tgtTxtCtrl, init = {}): + wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) + self.Init = init + self.Dialog = None + self.DialogParent = parent + + self.tgtTxtCtrl = tgtTxtCtrl + self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) + self.SetToolTip("Launch PowerBinder") + + def PowerBinderEventHandler(self, _): + self.PowerBinderDialog().Show() + + def LoadFromData(self, data): + self.PowerBinderDialog().LoadFromData(data) + + def SaveToData(self): + return self.PowerBinderDialog().SaveToData() + + def PowerBinderDialog(self): + if not self.Dialog: + self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) + return self.Dialog + + +class PowerBinderEditDialog(wx.Dialog): + def __init__(self, parent): + wx.Dialog.__init__(self, parent, -1, "Edit Step", + style = wx.DEFAULT_DIALOG_STYLE) + + outerSizer = wx.BoxSizer(wx.VERTICAL) + + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + self.mainSizer.SetMinSize([500, 150]) + + self.Page = parent.Page + + self.mainSizer.Add( + self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), + 0, wx.EXPAND|wx.ALL, 10) + + outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) + + self.SetSizerAndFit(outerSizer) + self.Layout() + self.Fit() + +########### Power Binder Command Objects +class PowerBindCmd(): + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + commandClassName = commandRevClasses[type(self)] + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{commandClassName} - {short_bindstr}" + + +####### Away From Keyboard +class AFKCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) + +####### Attribute Monitor +class AttributeMonitorCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.Groups = {} + self.AttributeTable = { + 'Base' : { + 'Current Hit Points' : 'NT H', + 'Max Hit Points' : 'X H', + 'Current Endurance' : 'T E', + 'Max Endurance' : 'X EN', + 'Regeneration Rate' : 'N RAT', + 'Recovery Rate' : 'Y RA', + 'Endurance Consumption' : 'SU', + 'ToHit Bonus' : 'T B', + 'Accuracy Bonus' : 'CC', + 'Last Hit Chance' : 'T C', + 'Damage Bonus' : 'DA', + 'Healing Bonus' : 'NG B', + 'Recharge Time Bonus' : 'ME B', + 'Endurance Discount' : 'CE DIS', + 'Stealth Radius (PvP)' : 'PVP', + 'Stealth Radius (PvE)' : 'PVE', + 'Perception Radius' : 'RC', + 'Range Bonus' : 'GE B', + 'Threat Level' : 'AT L', + 'Experience to Next Level' : 'XT', + 'Experience Debt' : 'XP', + 'Influence / Infamy' : 'INF', + 'Inherent' : 'NH', + }, + 'Movement Speed' : { + 'Flying Speed' : 'FL', + 'Jumping Speed' : 'PI', + 'Max Jump Height' : 'X J', + 'Run Speed' : 'RU', + }, + 'Damage Resistance' : { + 'Smashing Resistance' : 'G R', + 'Lethal Resistance' : 'L R', + 'Fire Resistance' : 'RE R', + 'Cold Resistance' : 'COLD R', + 'Energy Resistance' : 'DamageType[4]', + 'Negative Energy Resistance' : 'GY R', + 'Psyonic Resistance' : 'NIC R', + 'Toxic Resistance' : 'XIC R', + }, + 'Defense' : { + 'Base Defense' : 'BAS', + 'Ranged Defense' : 'ED', + 'Melee Defense' : 'MEL', + 'AoE Defense' : '2', + 'Smashing Defense' : '3', + 'Lethal Defense' : '4', + 'Fire Defense' : '5', + 'Cold Defense' : '6', + 'Energy Defense' : '7', + 'Negative Energy Defense' : '8', + 'Psionic Defense' : '9', + 'Toxic Defense' : '1', + }, + 'Debuff Resistance' : { + 'Regeneration Resistance' : 'ON R', + 'Recovery Resistance' : 'RY R', + 'To Hit Resistance' : 'IT R', + 'Defense Resistance' : 'NSE RES', + }, + 'Status Effect Protection' : { + 'Hold Protection' : 'D P', + 'Immobilize Protection' : 'LIZE P', + 'Stun Protection' : 'N P', + 'Sleep Protection' : 'P P', + 'Knockback Protection' : 'K P', + 'Confuse Protection' : 'SE P', + 'Terrorize Protection' : 'ZE P', + 'Repel Protection' : 'EL P', + 'Teleport Protection' : 'T P', + }, + 'Status Effect Resistance' : { + 'Hold Resistance' : 'D R', + 'Immobilize Resistance' : 'LIZE R', + 'Stun Resistance' : 'N R', + 'Sleep Resistance' : 'P R', + 'Knockback Resistance' : 'K R', + 'Confuse Resistance' : 'SE R', + 'Terrorize Resistance' : 'ZE R', + 'Placate Resistance' : 'TE R', + 'Taunt Resistance' : 'NT R', + }, + 'Miscellaneous' : { + 'Level Shift' : 'L S', + }, + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.AttributeMenu = wx.Menu() + for group, controls in self.AttributeTable.items(): + submenu = wx.Menu() + self.AttributeMenu.AppendSubMenu(submenu, group) + for cb in controls: + submenu.Append(wx.ID_ANY, cb) + + self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) + + self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) + groupSizer.Add(self.editbox) + + newButton = self.editbox.GetNewButton() + newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) + + return groupSizer + + def MakeBindString(self): + map = {} + bindstrings = [] + for _, controls in self.AttributeTable.items(): + for cb, data in controls.items(): + map[cb] = data + + for string in self.editbox.GetStrings(): + if string: + bindstrings.append(f'monitorattribute {map[string]}') + + return '$$'.join(bindstrings) + + def Serialize(self): + return { + 'attributes' : self.editbox.GetStrings() + } + + def Deserialize(self, init): + self.editbox.SetStrings(init.get('attributes', [])) + + def OnNewButton(self, evt): + evt.GetEventObject().PopupMenu(self.AttributeMenu) + + def OnMenuItem(self, evt): + menuitem = evt.EventObject.FindItemById(evt.GetId()) + existingstrings = self.editbox.GetStrings() + existingstrings.append(menuitem.GetItemLabel()) + self.editbox.SetStrings(existingstrings) + +####### Auto Power +class AutoPowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) + autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.autoPowerName = PowerPicker(dialog) + autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) + + return autoPowerSizer + + def MakeBindString(self): + return f"powexecauto {self.autoPowerName.GetLabel()}" + + def Serialize(self): + return { + 'pname' : self.autoPowerName.GetLabel(), + 'picon' : self.autoPowerName.IconFilename + } + + def Deserialize(self, init): + if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) + +####### Buff Display Command +class BuffDisplayCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.buffDisplayMap = { + 'Status Window' : { + 'Hide Auto' : 1, + 'Hide Toggles' : 2, + 'No Blinking' : 4, + 'No Stacking' : 8, + 'Numeric Stacking' : 16, + 'Hide Buff Numbers' : 32, + 'Stop Sending Buffs' : 64, + }, + 'Group Window' : { + 'Hide Auto' : 256, + 'Hide Toggles' : 512, + 'No Blinking' : 1024, + 'No Stacking' : 2048, + 'Numeric Stacking' : 4096, + 'Hide Buff Numbers' : 8192, + 'Stop Sending Buffs' : 16384, + }, + 'Pet Window' : { + 'Hide Auto' : 65536, + 'Hide Toggles' : 131072, + 'No Blinking' : 262144, + 'No Stacking' : 524288, + 'Numeric Stacking' : 1048576, + 'Hide Buff Numbers' : 2097152, + 'Stop Sending Buffs' : 4194304, + }, + } + self.Groups = {} + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + for group, controls in self.buffDisplayMap.items(): + self.Groups[group] = ControlGroup(dialog, self.Page, label = group) + groupid = self.Groups[group].GetStaticBox().GetId() + for cb, data in controls.items(): + self.Groups[group].AddControl( + ctlType = 'checkbox', + ctlName = f"{groupid}_{group}_{cb}", + label = cb, + data = data, + ) + + groupSizer.Add(self.Groups[group]) + + return groupSizer + + def CalculateValue(self): + page = wx.App.Get().Main.Profile.CustomBinds + + total = 0 + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] + if checkbox.IsChecked(): + total = total + checkbox.Data + return total + + def MakeBindString(self): + return f"optionset buffsettings {self.CalculateValue()}" + + def Serialize(self): + return { 'value' : self.CalculateValue() } + + def Deserialize(self, init): + value = init.get('value', 0) + + value = value or 0 # in case we had for some reason 'None' stashed in the init values + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] + checkbox.SetValue( checkbox.Data & value ) + +####### Chat Command +class ChatCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.chatChannelMap = { # before __init__ + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + chatCommandSizer = wx.GridBagSizer(5, 5) + self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") + chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) + # row 1 + self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) + self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) + self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) + # row 2 + self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) + self.chatCommandDuration.SetRange(1, 20) + self.chatCommandDuration.SetValue(7) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandDuration, (2,1)) + self.chatCommandChatSize = wx.Choice(dialog, -1, + choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) + self.chatCommandChatSize.SetSelection(5) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) + self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) + self.chatCommandChannel.SetSelection(0) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChannel, (2,5)) + # row 3 + self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") + chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) + self.chatCommandMessage = wx.TextCtrl(dialog, -1) + self.chatCommandMessage.SetHint('Chat Command Text') + chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) + + return chatCommandSizer + + def MakeBindString(self): + duration = self.chatCommandDuration.GetValue() + + choice = self.chatCommandChatSize + index = choice.GetSelection() + size = choice.GetString(index) + + duration = f"" if duration != 7 else "" + size = f"" if size != "1" else "" + + bdcolor = fgcolor = bgcolor = '' + if self.chatCommandUseColorsCB.IsChecked(): + bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + + bdcolor = f"" + fgcolor = f"" + bgcolor = f"" + + beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' + text = self.chatCommandMessage.GetValue() + + choice = self.chatCommandChannel + index = choice.GetSelection() + channel = choice.GetString(index) + + return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" + + def Serialize(self): + return { + 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), + 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), + 'channel' : self.chatCommandChannel .GetSelection(), + 'size' : self.chatCommandChatSize.GetSelection(), + 'duration' : self.chatCommandDuration.GetValue(), + 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'text' : self.chatCommandMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) + if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) + if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) + if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) + if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) + if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) + if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) + if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) + if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) + + +####### Chat Command Global +class ChatGlobalCmd(PowerBindCmd): + def BuildUI(self, dialog): + chatCommandGlobalSizer = wx.GridBagSizer(5,5) + + self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") + chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) + + self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalChannel.SetHint("Channel") + chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) + + self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') + chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) + + chatCommandGlobalSizer.AddGrowableCol(1) + + return chatCommandGlobalSizer + + def MakeBindString(self): + useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() + channel = self.chatCommandGlobalChannel.GetValue() + message = self.chatCommandGlobalMessage.GetValue() + + preface = "beginchat /" if useBeginchat else "" + + return f'{preface}send "{channel}" {message}' + + def Serialize(self): + return { + 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), + 'channel' : self.chatCommandGlobalChannel.GetValue(), + 'message' : self.chatCommandGlobalMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) + if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) + if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) + +#######Costume Change +class CostumeChangeCmd(PowerBindCmd): + def BuildUI(self, dialog): + costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeCostume = wx.Choice(dialog, -1, + choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) + self.costumeChangeCostume.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeEmote = wx.Choice(dialog, -1, + choices = GameData.Emotes['costumechange']) + self.costumeChangeEmote.Insert("- None -", 0) + self.costumeChangeEmote.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return costumeChangeSizer + + def MakeBindString(self): + costumeNumber = self.costumeChangeCostume.GetSelection() + costumeEmote = self.costumeChangeEmote.GetSelection() + + if costumeEmote: # None, or 0 == "- None -" + ccCmd = 'cce' + emoteName = self.costumeChangeEmote.GetString(costumeEmote) + emoteName = " CC" + emoteName.replace(" ","") + else: + ccCmd = 'cc' + emoteName = '' + + return f"{ccCmd} {costumeNumber}{emoteName}" + + def Serialize(self): + return{ + 'costumeNumber': self.costumeChangeCostume.GetSelection(), + 'costumeEmote' : self.costumeChangeEmote.GetSelection(), + } + + def Deserialize(self, init): + if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) + if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) + +####### Movement Command +class MovementCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + self.plusbutton.SetValue(True) + + self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.commandchoice = wx.Choice(dialog, choices = [ + "forward", "left", "right", "backward", "up", "down", + "turnleft", "turnright", "first", "autorun", "clicktomove", + ],) + sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) + self.commandchoice.SetSelection(0) + + self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + pre = post = '' + if self.plusbutton.GetValue() : pre = "+" + elif self.plusplusbutton.GetValue() : pre = "++" + elif self.minusbutton.GetValue() : pre = "-" + elif self.zerobutton.GetValue() : post = " 0" + elif self.onebutton.GetValue() : post = " 1" + + command = self.commandchoice.GetString(self.commandchoice.GetSelection()) + + return f"{pre}{command}{post}" + + def Serialize(self): + mod = '' + if self.plusbutton.GetValue() : mod = "plus" + elif self.plusplusbutton.GetValue() : mod = "plusplus" + elif self.minusbutton.GetValue() : mod = "minus" + elif self.zerobutton.GetValue() : mod = "zero" + elif self.onebutton.GetValue() : mod = "one" + + return { + 'mod' : mod, + 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), + } + + def Deserialize(self, init): + mod = init.get('mod', 'plus') + + if mod == 'plus' : self.plusbutton.SetValue(True) + elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) + elif mod == 'minus' : self.minusbutton.SetValue(True) + elif mod == 'zero' : self.zerobutton.SetValue(True) + elif mod == 'one' : self.onebutton.SetValue(True) + + self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) + +####### Graphics Command +class GraphicsCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.FlexGridSizer(2) + + self.visscalecb = wx.CheckBox(dialog, label = "visscale") + sizer.Add(self.visscalecb) + self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) + sizer.Add(self.visscalesc) + + self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") + sizer.Add(self.dofweightcb) + self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) + sizer.Add(self.dofweightsc) + + self.fsaacb = wx.CheckBox(dialog, label = "fsaa") + sizer.Add(self.fsaacb) + self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) + self.fsaach.SetSelection(0) + sizer.Add(self.fsaach) + + self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") + sizer.Add(self.bloomscalecb) + self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) + self.bloomscalech.SetSelection(0) + sizer.Add(self.bloomscalech) + + self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") + sizer.Add(self.bloomweightcb) + self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) + sizer.Add(self.bloomweightsc) + + self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") + sizer.Add(self.lodbiascb) + self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) + sizer.Add(self.lodbiassc) + + self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") + sizer.Add(self.renderscalecb) + self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) + sizer.Add(self.renderscalesc) + + return sizer + + def MakeBindString(self): + # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. + bindstrings = [] + if self.visscalecb.IsChecked(): + bindstrings.append("visscale " + str(self.visscalesc.GetValue())) + if self.dofweightcb.IsChecked(): + bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) + if self.fsaacb.IsChecked(): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bindstrings.append("fsaa " + fsaavalue) + if self.bloomscalecb.IsChecked(): + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + bindstrings.append("bloomscale " + bloomscalevalue) + if self.bloomweightcb.IsChecked(): + bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) + if self.lodbiascb.IsChecked(): + bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) + if self.renderscalecb.IsChecked(): + bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) + + return '$$'.join(bindstrings) + + def Serialize(self): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + return { + 'visscalecb' : self.visscalecb.IsChecked(), + 'visscalesc' : self.visscalesc.GetValue(), + 'dofweightcb' : self.dofweightcb.IsChecked(), + 'dofweightsc' : self.dofweightsc.GetValue(), + 'fsaacb' : self.fsaacb.IsChecked(), + 'fsaach' : fsaavalue, + 'bloomscalecb' : self.bloomscalecb.IsChecked(), + 'bloomscalech' : bloomscalevalue, + 'bloomweightcb' : self.bloomweightcb.IsChecked(), + 'bloomweightsc' : self.bloomweightsc.GetValue(), + 'lodbiascb' : self.lodbiascb.IsChecked(), + 'lodbiassc' : self.lodbiassc.GetValue(), + 'renderscalecb' : self.renderscalecb.IsChecked(), + 'renderscalesc' : self.renderscalesc.GetValue(), + } + + def Deserialize(self, init): + self.visscalecb.SetValue(init.get('visscalecb', False)) + self.visscalesc.SetValue(init.get('visscalesc', 1.0)) + self.dofweightcb.SetValue(init.get('dofweightcb', False)) + self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) + self.fsaacb.SetValue(init.get('fsaacb', False)) + self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) + self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) + self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) + self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) + self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) + self.lodbiascb.SetValue(init.get('lodbiascb', False)) + self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) + self.renderscalecb.SetValue(init.get('renderscalecb', False)) + self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) + +####### Custom Bind +class CustomBindCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.customBindName = wx.TextCtrl(dialog, -1) + self.customBindName.SetHint('Custom Bind Text') + sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + return self.customBindName.GetValue() + + def Serialize(self): + return { 'customBindName': self.customBindName.GetValue() } + + def Deserialize(self,init): + if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) + +####### Emote +class EmoteCmd(PowerBindCmd): + def BuildUI(self, dialog): + emoteSizer = wx.BoxSizer(wx.HORIZONTAL) + self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") + emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + self.emoteName = wx.Button(dialog, -1, "...") + self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) + emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) + + return emoteSizer + + def MakeBindString(self): + displayedEmoteName = self.emoteName.GetLabel() + actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] + + return actualEmotePayload + + def Serialize(self): + return {'emoteName': self.emoteName.GetLabel()} + + def Deserialize(self, init): + if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) + +####### Load Binds Directory +class LoadBindsDir(PowerBindCmd): + def BuildUI(self, dialog): + mainSizer = wx.BoxSizer(wx.VERTICAL) + + lbSizer = wx.BoxSizer(wx.HORIZONTAL) + lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") + lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + profiles = Profile.GetAllProfileBindsDirs() + + self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) + lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") + self.lbResetCB.SetValue(True) + + mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + return mainSizer + + def MakeBindString(self): + + # If the specified binds directory disappeared between runs, we'd crash, so handle that. + if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' + + config = wx.ConfigBase.Get() + if config.Exists('GameBindPath'): + bindpath = config.Read('GameBindPath') + else: + bindpath = config.Read('BindPath') + + reset = "" + if self.lbResetCB.GetValue(): + reset = "keybind_reset$$" + + resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' + return reset + 'bindloadfile ' + str(resetfilepath) + + def Serialize(self): + return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), + 'ResetKeybinds' : self.lbResetCB.GetValue(), + } + + def Deserialize(self, init): + if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) + self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) + +####### Power Abort +class PowerAbortCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecabort' + +####### Power Unqueue +class PowerUnqueueCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecunqueue' + +####### SG Mode +class SGModeCmd(PowerBindCmd): + def BuildUI(self, dialog): + sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) + sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") + self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") + + sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) + + return sgmodeSizer + + def MakeBindString(self): + if self.sgmodeOnRB.GetValue(): + return 'sgmodeset 1' + elif self.sgmodeOffRB.GetValue(): + return 'sgmodeset 0' + else: + return 'sgmode' + + def Serialize(self): + if self.sgmodeOnRB.GetValue(): + val = "On" + elif self.sgmodeOffRB.GetValue(): + val = "Off" + else: + val = "Toggle" + + return {"value" : val} + + def Deserialize(self, init): + val = init.get('value', '') + if val == "On": + self.sgmodeOnRB.SetValue(True) + elif val == "Off": + self.sgmodeOffRB.SetValue(True) + else: + self.sgmodeToggleRB.SetValue(True) + +####### Target Custom +class TargetCustomCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetCustomSizer = wx.GridBagSizer(5,5) + targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), + flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) + self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetCustomModeChoice.SetSelection(0) + targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) + self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) + self.targetCustomOptionalName.SetHint("Optional name to match") + targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) + self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") + targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) + self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") + targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) + self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") + targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) + self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") + targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) + self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") + targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) + self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") + targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) + self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") + targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) + self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") + targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) + + targetCustomSizer.AddGrowableCol(2) + + return targetCustomSizer + + def MakeBindString(self): + choice = self.targetCustomModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + targetCommand = "targetcustom" + mode.lower() + + enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" + friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" + defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" + alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" + mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" + notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" + base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" + notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" + + name = self.targetCustomOptionalName.GetValue() + + return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" + + def Serialize(self): + return { + 'mode' : self.targetCustomModeChoice.GetSelection(), + 'enemy' : self.targetCustomCBEnemies. IsChecked(), + 'friend' : self.targetCustomCBFriends. IsChecked(), + 'defeated' : self.targetCustomCBDefeated. IsChecked(), + 'alive' : self.targetCustomCBAlive. IsChecked(), + 'mypet' : self.targetCustomCBMyPets. IsChecked(), + 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), + 'base' : self.targetCustomCBBaseItems. IsChecked(), + 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), + 'name' : self.targetCustomOptionalName.GetValue(), + } + + def Deserialize(self, init): + if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) + if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) + if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) + if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) + if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) + if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) + if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) + if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) + if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) + if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) + + +####### Target Enemy +class TargetEnemyCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) + targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetEnemyModeChoice.SetSelection(0) + targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetEnemySizer + + def MakeBindString(self): + choice = self.targetEnemyModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetenemy" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetEnemyModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) + +####### Target Friend +class TargetFriendCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) + targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetFriendModeChoice.SetSelection(0) + targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetFriendSizer + + def MakeBindString(self): + choice = self.targetFriendModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetfriend" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetFriendModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) + +####### Team/Pet Select +class TeamPetSelectCmd(PowerBindCmd): + def BuildUI(self, dialog): + teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], + style=wx.ALIGN_CENTER_VERTICAL) + self.teamPetSelectNumber.SetSelection(0) + teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) + + return teamPetSelectSizer + + def MakeBindString(self): + teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' + targetNumber = self.teamPetSelectNumber.GetSelection()+1 + + return f"{teamOrPet}select {targetNumber}" + + def Serialize(self): + return { + 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', + 'targetNum': self.teamPetSelectNumber.GetSelection(), + } + + def Deserialize(self, init): + ToP = init.get('teamOrPet', '') + if ToP == 'pet': + self.teamPetSelectPetRB.SetValue(True) + else: + self.teamPetSelectTeamRB.SetValue(True) + if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) + +####### Unselect +class UnselectCmd(PowerBindCmd): + def MakeBindString(self): + return 'unselect' + +####### Use Insp By Name +class UseInspByNameCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) + for _, types in GameData.Inspirations.items(): + for _, info in types.items(): + for insp in info['tiers']: + name = re.sub(' ', '', str(insp)) + icon = GetIcon(f'Inspirations/{name}') + self.useInspByNameModeChoice.Append(insp, icon) + self.useInspByNameModeChoice.SetSelection(0) + useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) + + return useInspByNameSizer + + def MakeBindString(self): + choice = self.useInspByNameModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "inspexecname " + mode.lower() + + def GetAllInsps(self): + Insplist = [] + for _, info in GameData.Inspirations.items(): + for insp in info['tiers']: + Insplist.append(insp) + Insplist.append("---") + Insplist.pop(-1) # snip the terminal "---" + + return Insplist + + def Serialize(self): + return { 'insp' : self.useInspByNameModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) + +####### Use Insp From Row / Column +class UseInspRowColCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnRow.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) + self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnCol.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) + + return useInspRowColumnSizer + + def MakeBindString(self): + row = self.useInspRowColumnRow.GetSelection()+1 + col = self.useInspRowColumnCol.GetSelection()+1 + + return f"inspexectray {col} {row}" + + def Serialize(self): + return { + 'col' : self.useInspRowColumnCol.GetSelection(), + 'row' : self.useInspRowColumnRow.GetSelection(), + } + + def Deserialize(self, init): + if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) + if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) + +####### Use Power +class UsePowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + outerSizer = wx.BoxSizer(wx.HORIZONTAL) + + usePowerSizer = wx.GridBagSizer(5,5) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBToggle, (0,1)) + self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOn, (0,2)) + self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOff, (0,3)) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerName = PowerPicker(dialog) + usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) + usePowerSizer.AddGrowableCol(3) + + outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) + + return outerSizer + + def MakeBindString(self): + if self.usePowerRBToggle.GetValue(): + method = "powexecname" + elif self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') + return '' + + return f"{method} {self.usePowerName.GetLabel()}" + + def Serialize(self): + if self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + method = "powexecname" + return { + 'method': method, + 'pname' : self.usePowerName.GetLabel(), + 'picon' : self.usePowerName.IconFilename + } + + def Deserialize(self, init): + method = init.get('method', '') + if method == 'powexectoggleon': + self.usePowerRBOn.SetValue(True) + elif method == 'powexectoggleoff': + self.usePowerRBOff.SetValue(True) + else: + self.usePowerRBToggle.SetValue(True) + if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) + +####### Use Power From Tray +class UsePowerFromTrayCmd(PowerBindCmd): + def BuildUI(self, dialog): + usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTrayTray = wx.Choice(dialog, -1, + choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', + 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) + self.usePowerFromTrayTray.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) + self.usePowerFromTraySlot.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return usePowerFromTraySizer + + def MakeBindString(self): + choice = self.usePowerFromTrayTray + tray = choice.GetSelection() + + choice = self.usePowerFromTraySlot + slot = choice.GetSelection()+1 + + mode = "slot" + mode2 = '' + if tray > 3: + mode = "tray" + mode2 = f" {tray - 3}" + elif tray == 3: + mode = "alt2slot" + elif tray == 2: + mode = "altslot" + + return f"powexec{mode} {slot}{mode2}" + + def Serialize(self): + return { + 'tray' : self.usePowerFromTrayTray.GetSelection(), + 'slot' : self.usePowerFromTraySlot.GetSelection(), + } + + def Deserialize(self, init): + if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) + if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) + +####### Window Color +class WindowColorCmd(PowerBindCmd): + def BuildUI(self, dialog): + windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) + borderSizer = wx.BoxSizer(wx.VERTICAL) + self.ColorBorder.SetSizer(borderSizer) + self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) + borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) + + windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) + + RGBASizer = wx.FlexGridSizer(3, 4, 5) + + RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) + self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) + self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + windowColorSizer.Add(RGBASizer) + + self.UpdateFromSlider() + + return windowColorSizer + + def MakeBindString(self): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + return f"windowcolor {Rval} {Gval} {Bval} {Aval}" + + def Serialize(self): + return { + 'Rval' : self.RSlider.GetValue(), + 'Gval' : self.GSlider.GetValue(), + 'Bval' : self.BSlider.GetValue(), + 'Aval' : self.ASlider.GetValue(), + } + + def Deserialize(self, init): + self.RSlider.SetValue(init['Rval']) + self.GSlider.SetValue(init['Gval']) + self.BSlider.SetValue(init['Bval']) + self.ASlider.SetValue(init['Aval']) + self.UpdateFromSlider() + + def UpdateFromSlider(self, _ = None): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RReadout.SetValue(Rval) + self.GReadout.SetValue(Gval) + self.BReadout.SetValue(Bval) + self.AReadout.SetValue(Aval) + self.ColorBorder.Refresh() + + def UpdateFromText(self, _ = None): + Rval = self.RReadout.GetValue() + Gval = self.GReadout.GetValue() + Bval = self.BReadout.GetValue() + Aval = self.AReadout.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RSlider.SetValue(Rval) + self.GSlider.SetValue(Gval) + self.BSlider.SetValue(Bval) + self.ASlider.SetValue(Aval) + self.ColorBorder.Refresh() + +####### Window Save / Load +class WindowSaveLoadCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) + self.CommandChoice.SetSelection(0) + sizer.Add(self.CommandChoice, 0, wx.ALL, 5) + + self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), + value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) + sizer.Add(self.FilePath, 0, wx.ALL, 5) + + return sizer + + def MakeBindString(self): + command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] + return f'{command} "{self.FilePath.GetValue()}"' + + def Serialize(self): + return { + 'command' : self.CommandChoice.GetSelection(), + 'filename' : self.FilePath.GetValue(), + } + + def Deserialize(self, init): + self.CommandChoice.SetSelection(init.get('command', 0)) + self.FilePath.SetValue(init.get('filename', '')) + +####### Window Toggle +class WindowToggleCmd(PowerBindCmd): + def BuildUI(self, dialog): + self.WindowNames = { + 'Actions' : 'actions', + 'Auction House' : 'ah', + 'Badge' : 'badge', + 'Channel Search' : 'chansearch', + 'Chat' : 'chat', + 'Custom Chat 1' : 'chat1', + 'Custom Chat 2' : 'chat2', + 'Custom Chat 3' : 'chat3', + 'Custom Chat 4' : 'chat4', + 'Clues' : 'clue', + 'Combat Numbers' : 'combatnumbers', + 'Contacts' : 'contact', + 'Contact Finder' : 'contactfinder', + 'Costumes' : 'costume', + 'Email' : 'email', + 'Enhancements' : 'enhancements', + 'Friends' : 'friend', + 'Group' : 'group', + 'Help' : 'helpwindow', + 'Incarnate' : 'incarnate', + 'Inspirations' : 'insp', + 'League' : 'league', + 'LFG' : 'lfg', + 'Map' : 'map', + 'Mission' : 'mission', + 'Nav / Compass' : 'nav', + 'Options' : 'options', + 'Pets' : 'pet', + 'Petition' : 'petition', + 'Power Tray' : 'powers', + 'Power List' : 'powerlist', + 'Quit' : 'quit', + 'Recipes' : 'recipe', + 'Salvage' : 'salvage', + 'Search' : 'search', + 'Supergroup' : 'sg', + 'Target' : 'target', + 'Team' : 'team', + 'Tray' : 'tray', + 'Tray1' : 'tray1', + 'Tray2' : 'tray2', + 'Tray3' : 'tray3', + 'Tray4' : 'tray4', + 'Tray5' : 'tray5', + 'Tray6' : 'tray6', + 'Tray7' : 'tray7', + 'Tray8' : 'tray8', + 'Vault' : 'vault', + } + + self.ShortToggleCommands = { + 'Auction House' : 'ah', + 'Chat' : 'chat', + 'Help' : 'helpwindow', + 'Map' : 'map', + 'Nav / Compass' : 'nav', + 'Power Tray' : 'powers', + 'Target' : 'target', + 'Tray' : 'tray', + } + + windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) + windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) + self.windowToggleTray.SetSelection(0) + windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.windowShowRB = wx.RadioButton(dialog, -1, "Show") + self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") + + windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) + + return windowToggleSizer + + def MakeBindString(self): + choice = self.windowToggleTray + index = choice.GetSelection() + windowdesc = choice.GetString(index) + windowname = self.WindowNames[windowdesc] + + if self.windowShowRB.GetValue(): + return 'show ' + windowname + elif self.windowHideRB.GetValue(): + return 'windowhide ' + windowname + else: + if shortcmd := self.ShortToggleCommands.get(windowdesc, None): + return shortcmd + else: + return 'toggle ' + windowname + + + def Serialize(self): + choice = self.windowToggleTray + if self.windowShowRB.GetValue(): + action = "Show" + elif self.windowHideRB.GetValue(): + action = "Hide" + else: + action = "Toggle" + return { + 'window': choice.GetString(choice.GetSelection()), + 'action': action, + } + + def Deserialize(self, init): + choice = self.windowToggleTray + if window := init.get('window', ''): + if isinstance(window, int): + choice.SetSelection(window) + else: + choice.SetSelection(choice.FindString(window)) + + if choice.GetSelection() == wx.NOT_FOUND: + choice.SetSelection(0) + + action = init.get('action', '') + if action == "Show": + self.windowShowRB.SetValue(True) + elif action == "Hide": + self.windowHideRB.SetValue(True) + else: + self.windowToggleRB.SetValue(True) + + +# Must always add to this list when adding a new command class above +menuStructure = { + 'Graphics / UI' : [ + 'Attribute Monitor', + 'Buff Display Settings', + 'Graphics Settings', + 'Window Color', + 'Window Save / Load', + 'Window Toggle', + ], + 'Inspirations' : [ + 'Use Inspiration By Name', + 'Use Inspiration From Row/Column', + ], + 'Powers' : [ + 'Auto Power', + 'Power Abort', + 'Power Unqueue', + 'Use Power', + 'Use Power From Tray', + ], + 'Social' : [ + 'Away From Keyboard', + 'Chat Command', + 'Chat Command (Global)', + 'Costume Change', + 'Emote', + 'Supergroup Mode', + ], + 'Targeting' : [ + 'Target Custom', + 'Target Enemy', + 'Target Frield', + 'Team/Pet Select', + 'Unselect', + ], + 'Misc' : [ + 'Load Binds Directory', + 'Movement Commands', + ], + # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, + # but I'm leaving it here to remind myself that we do that. + } + +# Must always add to this list when adding a new command class above +commandClasses = { + 'Auto Power' : AutoPowerCmd, + 'Away From Keyboard' : AFKCmd, + 'Attribute Monitor' : AttributeMonitorCmd, + 'Buff Display Settings' : BuffDisplayCmd, + 'Chat Command' : ChatCmd, + 'Chat Command (Global)' : ChatGlobalCmd, + 'Costume Change' : CostumeChangeCmd, + 'Custom Bind' : CustomBindCmd, + 'Emote' : EmoteCmd, + 'Graphics Settings' : GraphicsCmd, + 'Load Binds Directory' : LoadBindsDir, + 'Movement Commands' : MovementCmd, + 'Power Abort' : PowerAbortCmd, + 'Power Unqueue' : PowerUnqueueCmd, + 'Supergroup Mode' : SGModeCmd, + 'Target Custom' : TargetCustomCmd, + 'Target Enemy' : TargetEnemyCmd, + 'Target Friend' : TargetFriendCmd, + 'Team/Pet Select' : TeamPetSelectCmd, + 'Unselect' : UnselectCmd, + 'Use Inspiration By Name' : UseInspByNameCmd, + 'Use Inspiration From Row/Column' : UseInspRowColCmd, + 'Use Power' : UsePowerCmd, + 'Use Power From Tray' : UsePowerFromTrayCmd, + 'Window Color' : WindowColorCmd, + 'Window Save / Load' : WindowSaveLoadCmd, + 'Window Toggle' : WindowToggleCmd, +} +# use these when we rename a commandClass so that old Profiles will still load correctly. +# If we've also updated the class, we need to try to make sure the new class will still +# Deserialize the legacy data, or at least not crash. +deprecatedCommandClasses = { + 'SG Mode Toggle' : SGModeCmd, + 'Use Insp By Name' : UseInspByNameCmd, + 'Use Insp From Row/Column' : UseInspRowColCmd, +} +commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/LoadBindsDir.py b/UI/PowerBinderCommand/LoadBindsDir.py new file mode 100644 index 0000000..4c02ab7 --- /dev/null +++ b/UI/PowerBinderCommand/LoadBindsDir.py @@ -0,0 +1,1800 @@ +import wx +import re +import UI +import UI.EmotePicker +from UI.ControlGroup import ControlGroup +from UI.PowerPicker import PowerPicker +from Help import HelpButton +import wx.adv +from wx.adv import BitmapComboBox, EditableListBox +from pathlib import PureWindowsPath +import GameData +import Profile +from Icon import GetIcon + +class PowerBinderDialog(wx.Dialog): + def __init__(self, parent, button, init = {}): + wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) + + self.Page = parent.Page + self.EditDialog = PowerBinderEditDialog(self) + self.Button = button + self.AddStepMenu = self.makeAddStepMenu() + + sizer = wx.BoxSizer(wx.VERTICAL); + self.mainSizer = sizer + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) + # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) + # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) + #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) + AddStepButton = wx.Button(self, -1, 'Add Step') + AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) + AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) + choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) + choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) + sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) + + rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) + + self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) + self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) + self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) + rearrangeCtrl.Add(self.RearrangeList, 1) + + rearrangeButtons = wx.BoxSizer(wx.VERTICAL) + self.DelButton = wx.Button(self, -1, "Delete") + self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) + self.EditButton = wx.Button(self, -1, "Edit") + self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) + self.EditButton.Disable() + upButton = wx.Button(self, -1, "\u25B2") + upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) + downButton = wx.Button(self, -1, "\u25BC") + downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) + rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) + rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) + + sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.BindStringDisplay = wx.TextCtrl(self, -1) + self.BindStringDisplay.Disable() + choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, + wx.ALIGN_CENTER_VERTICAL) + choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) + + sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) + + sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) + + # need to dig around and get the OK button since we show this dialog modelessly now. + okButton = self.FindWindow(self.GetAffirmativeId()) + okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) + + # Wrap everything in a vbox to add some padding + vbox = wx.BoxSizer(wx.VERTICAL); + vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); + + self.SetSizerAndFit(vbox); + self.Layout() + self.Fit() + self.SetFocus() + + # if we are loading from profile, ie, have "init", build the list from it + if init: self.LoadFromData(init) + + def LoadFromData(self, init): + for item in init: + for type, data in item.items(): + commandClass = commandClasses.get(type, None) + if not commandClass: + commandClass = deprecatedCommandClasses.get(type, None) + if not commandClass: + wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") + continue + newCommand = commandClass(self.EditDialog, data) + index = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.SetClientData(index, newCommand) + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) + self.EditDialog.mainSizer.Hide(newCommand.UI) + self.UpdateBindStringDisplay() + + def SaveToData(self): + data = [] + index = 0 + for _ in self.RearrangeList.GetItems(): + # check whether we have an object already attached to this choice + cmdObject = self.RearrangeList.GetClientData(index) + commandClassName = commandRevClasses[type(cmdObject)] + data.append({commandClassName: cmdObject.Serialize()}) + index = index + 1 + return data + + def OnAddStepButton(self, evt): + button = evt.EventObject + if not self.AddStepMenu: + self.AddStepMenu = self.makeAddStepMenu() + button.PopupMenu(self.AddStepMenu) + + + def OnOKButton(self, _): + if self.Button.tgtTxtCtrl: + bindString = self.MakeBindString() + if bindString != self.Button.tgtTxtCtrl.GetValue(): + self.Button.tgtTxtCtrl.SetValue(bindString) + wx.App.Get().Main.Profile.SetModified() + self.Close() + + def OnRearrangeDelete(self, _): + current = self.RearrangeList.GetSelection() + if current == wx.NOT_FOUND: return + + self.RearrangeList.Delete(current) + self.UpdateBindStringDisplay() + + def OnRearrangeUp(self, _): + self.RearrangeList.MoveCurrentUp() + self.UpdateBindStringDisplay() + + def OnRearrangeDown(self, _): + self.RearrangeList.MoveCurrentDown() + self.UpdateBindStringDisplay() + + def OnRearrangeEdit(self, _): + index = self.RearrangeList.GetSelection() + + # check whether we have an object already attached to this choice + cmdObject = None + try: + cmdObject = self.RearrangeList.GetClientData(index) + except Exception: + pass + + if cmdObject: + self.ShowEditDialogFor(cmdObject) + self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) + else: + print("cmdObject was None") + self.UpdateBindStringDisplay() + + # OnAddStepMenu creates a new step and adds it to the rearrangelist + def OnAddStepMenu(self, evt): + menuitem = self.AddStepMenu.FindItemById(evt.GetId()) + chosenName = menuitem.GetItemLabel() + + # make a new command object, attached to the parent dialog + newCommandClass = commandClasses[chosenName] + newCommand = newCommandClass(self.EditDialog) + + # show the edit dialog if this command needs it + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) + if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): + self.EditDialog.mainSizer.Remove(newCommand.UI) + return + + newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.Select(newBindIndex) + self.RearrangeList.SetClientData(newBindIndex, newCommand) + + self.OnListSelect() + self.UpdateBindStringDisplay() + + def OnListSelect(self, _ = None): + selected = self.RearrangeList.GetSelection() + + if selected != wx.NOT_FOUND: + selCommand = self.RearrangeList.GetClientData(selected) + if selCommand.UI: + self.EditButton.Enable() + else: + self.EditButton.Disable() + + def UpdateBindStringDisplay(self): + self.BindStringDisplay.SetValue(self.MakeBindString()) + self.BindStringDisplay.SetToolTip(self.MakeBindString()) + + def MakeBindString(self): + cmdBindStrings = [] + for index in range(self.RearrangeList.GetCount()): + c = self.RearrangeList.GetClientData(index) + if c: cmdBindStrings.append(c.MakeBindString()) + + bindstring = ('$$'.join(cmdBindStrings)) + return bindstring + + def ShowEditDialogFor(self, command): + if not command.UI: return + + self.EditDialog.mainSizer.Show(command.UI) + + self.EditDialog.Layout() + self.EditDialog.Fit() + + self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') + returnval = self.EditDialog.ShowModal() + + self.EditDialog.mainSizer.Hide(command.UI) + + return returnval + + def makeAddStepMenu(self): + + stepMenu = wx.Menu() + + for subname in menuStructure: + submenu = wx.Menu() + stepMenu.AppendSubMenu(submenu, subname) + for classname in menuStructure[subname]: + submenu.Append(wx.ID_ANY, classname) + + stepMenu.Append(wx.ID_ANY, 'Custom Bind') + + return stepMenu + +class PowerBinderButton(wx.BitmapButton): + + def __init__(self, parent, tgtTxtCtrl, init = {}): + wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) + self.Init = init + self.Dialog = None + self.DialogParent = parent + + self.tgtTxtCtrl = tgtTxtCtrl + self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) + self.SetToolTip("Launch PowerBinder") + + def PowerBinderEventHandler(self, _): + self.PowerBinderDialog().Show() + + def LoadFromData(self, data): + self.PowerBinderDialog().LoadFromData(data) + + def SaveToData(self): + return self.PowerBinderDialog().SaveToData() + + def PowerBinderDialog(self): + if not self.Dialog: + self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) + return self.Dialog + + +class PowerBinderEditDialog(wx.Dialog): + def __init__(self, parent): + wx.Dialog.__init__(self, parent, -1, "Edit Step", + style = wx.DEFAULT_DIALOG_STYLE) + + outerSizer = wx.BoxSizer(wx.VERTICAL) + + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + self.mainSizer.SetMinSize([500, 150]) + + self.Page = parent.Page + + self.mainSizer.Add( + self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), + 0, wx.EXPAND|wx.ALL, 10) + + outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) + + self.SetSizerAndFit(outerSizer) + self.Layout() + self.Fit() + +########### Power Binder Command Objects +class PowerBindCmd(): + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + commandClassName = commandRevClasses[type(self)] + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{commandClassName} - {short_bindstr}" + + +####### Away From Keyboard +class AFKCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) + +####### Attribute Monitor +class AttributeMonitorCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.Groups = {} + self.AttributeTable = { + 'Base' : { + 'Current Hit Points' : 'NT H', + 'Max Hit Points' : 'X H', + 'Current Endurance' : 'T E', + 'Max Endurance' : 'X EN', + 'Regeneration Rate' : 'N RAT', + 'Recovery Rate' : 'Y RA', + 'Endurance Consumption' : 'SU', + 'ToHit Bonus' : 'T B', + 'Accuracy Bonus' : 'CC', + 'Last Hit Chance' : 'T C', + 'Damage Bonus' : 'DA', + 'Healing Bonus' : 'NG B', + 'Recharge Time Bonus' : 'ME B', + 'Endurance Discount' : 'CE DIS', + 'Stealth Radius (PvP)' : 'PVP', + 'Stealth Radius (PvE)' : 'PVE', + 'Perception Radius' : 'RC', + 'Range Bonus' : 'GE B', + 'Threat Level' : 'AT L', + 'Experience to Next Level' : 'XT', + 'Experience Debt' : 'XP', + 'Influence / Infamy' : 'INF', + 'Inherent' : 'NH', + }, + 'Movement Speed' : { + 'Flying Speed' : 'FL', + 'Jumping Speed' : 'PI', + 'Max Jump Height' : 'X J', + 'Run Speed' : 'RU', + }, + 'Damage Resistance' : { + 'Smashing Resistance' : 'G R', + 'Lethal Resistance' : 'L R', + 'Fire Resistance' : 'RE R', + 'Cold Resistance' : 'COLD R', + 'Energy Resistance' : 'DamageType[4]', + 'Negative Energy Resistance' : 'GY R', + 'Psyonic Resistance' : 'NIC R', + 'Toxic Resistance' : 'XIC R', + }, + 'Defense' : { + 'Base Defense' : 'BAS', + 'Ranged Defense' : 'ED', + 'Melee Defense' : 'MEL', + 'AoE Defense' : '2', + 'Smashing Defense' : '3', + 'Lethal Defense' : '4', + 'Fire Defense' : '5', + 'Cold Defense' : '6', + 'Energy Defense' : '7', + 'Negative Energy Defense' : '8', + 'Psionic Defense' : '9', + 'Toxic Defense' : '1', + }, + 'Debuff Resistance' : { + 'Regeneration Resistance' : 'ON R', + 'Recovery Resistance' : 'RY R', + 'To Hit Resistance' : 'IT R', + 'Defense Resistance' : 'NSE RES', + }, + 'Status Effect Protection' : { + 'Hold Protection' : 'D P', + 'Immobilize Protection' : 'LIZE P', + 'Stun Protection' : 'N P', + 'Sleep Protection' : 'P P', + 'Knockback Protection' : 'K P', + 'Confuse Protection' : 'SE P', + 'Terrorize Protection' : 'ZE P', + 'Repel Protection' : 'EL P', + 'Teleport Protection' : 'T P', + }, + 'Status Effect Resistance' : { + 'Hold Resistance' : 'D R', + 'Immobilize Resistance' : 'LIZE R', + 'Stun Resistance' : 'N R', + 'Sleep Resistance' : 'P R', + 'Knockback Resistance' : 'K R', + 'Confuse Resistance' : 'SE R', + 'Terrorize Resistance' : 'ZE R', + 'Placate Resistance' : 'TE R', + 'Taunt Resistance' : 'NT R', + }, + 'Miscellaneous' : { + 'Level Shift' : 'L S', + }, + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.AttributeMenu = wx.Menu() + for group, controls in self.AttributeTable.items(): + submenu = wx.Menu() + self.AttributeMenu.AppendSubMenu(submenu, group) + for cb in controls: + submenu.Append(wx.ID_ANY, cb) + + self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) + + self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) + groupSizer.Add(self.editbox) + + newButton = self.editbox.GetNewButton() + newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) + + return groupSizer + + def MakeBindString(self): + map = {} + bindstrings = [] + for _, controls in self.AttributeTable.items(): + for cb, data in controls.items(): + map[cb] = data + + for string in self.editbox.GetStrings(): + if string: + bindstrings.append(f'monitorattribute {map[string]}') + + return '$$'.join(bindstrings) + + def Serialize(self): + return { + 'attributes' : self.editbox.GetStrings() + } + + def Deserialize(self, init): + self.editbox.SetStrings(init.get('attributes', [])) + + def OnNewButton(self, evt): + evt.GetEventObject().PopupMenu(self.AttributeMenu) + + def OnMenuItem(self, evt): + menuitem = evt.EventObject.FindItemById(evt.GetId()) + existingstrings = self.editbox.GetStrings() + existingstrings.append(menuitem.GetItemLabel()) + self.editbox.SetStrings(existingstrings) + +####### Auto Power +class AutoPowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) + autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.autoPowerName = PowerPicker(dialog) + autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) + + return autoPowerSizer + + def MakeBindString(self): + return f"powexecauto {self.autoPowerName.GetLabel()}" + + def Serialize(self): + return { + 'pname' : self.autoPowerName.GetLabel(), + 'picon' : self.autoPowerName.IconFilename + } + + def Deserialize(self, init): + if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) + +####### Buff Display Command +class BuffDisplayCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.buffDisplayMap = { + 'Status Window' : { + 'Hide Auto' : 1, + 'Hide Toggles' : 2, + 'No Blinking' : 4, + 'No Stacking' : 8, + 'Numeric Stacking' : 16, + 'Hide Buff Numbers' : 32, + 'Stop Sending Buffs' : 64, + }, + 'Group Window' : { + 'Hide Auto' : 256, + 'Hide Toggles' : 512, + 'No Blinking' : 1024, + 'No Stacking' : 2048, + 'Numeric Stacking' : 4096, + 'Hide Buff Numbers' : 8192, + 'Stop Sending Buffs' : 16384, + }, + 'Pet Window' : { + 'Hide Auto' : 65536, + 'Hide Toggles' : 131072, + 'No Blinking' : 262144, + 'No Stacking' : 524288, + 'Numeric Stacking' : 1048576, + 'Hide Buff Numbers' : 2097152, + 'Stop Sending Buffs' : 4194304, + }, + } + self.Groups = {} + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + for group, controls in self.buffDisplayMap.items(): + self.Groups[group] = ControlGroup(dialog, self.Page, label = group) + groupid = self.Groups[group].GetStaticBox().GetId() + for cb, data in controls.items(): + self.Groups[group].AddControl( + ctlType = 'checkbox', + ctlName = f"{groupid}_{group}_{cb}", + label = cb, + data = data, + ) + + groupSizer.Add(self.Groups[group]) + + return groupSizer + + def CalculateValue(self): + page = wx.App.Get().Main.Profile.CustomBinds + + total = 0 + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] + if checkbox.IsChecked(): + total = total + checkbox.Data + return total + + def MakeBindString(self): + return f"optionset buffsettings {self.CalculateValue()}" + + def Serialize(self): + return { 'value' : self.CalculateValue() } + + def Deserialize(self, init): + value = init.get('value', 0) + + value = value or 0 # in case we had for some reason 'None' stashed in the init values + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] + checkbox.SetValue( checkbox.Data & value ) + +####### Chat Command +class ChatCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.chatChannelMap = { # before __init__ + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + chatCommandSizer = wx.GridBagSizer(5, 5) + self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") + chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) + # row 1 + self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) + self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) + self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) + # row 2 + self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) + self.chatCommandDuration.SetRange(1, 20) + self.chatCommandDuration.SetValue(7) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandDuration, (2,1)) + self.chatCommandChatSize = wx.Choice(dialog, -1, + choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) + self.chatCommandChatSize.SetSelection(5) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) + self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) + self.chatCommandChannel.SetSelection(0) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChannel, (2,5)) + # row 3 + self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") + chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) + self.chatCommandMessage = wx.TextCtrl(dialog, -1) + self.chatCommandMessage.SetHint('Chat Command Text') + chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) + + return chatCommandSizer + + def MakeBindString(self): + duration = self.chatCommandDuration.GetValue() + + choice = self.chatCommandChatSize + index = choice.GetSelection() + size = choice.GetString(index) + + duration = f"" if duration != 7 else "" + size = f"" if size != "1" else "" + + bdcolor = fgcolor = bgcolor = '' + if self.chatCommandUseColorsCB.IsChecked(): + bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + + bdcolor = f"" + fgcolor = f"" + bgcolor = f"" + + beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' + text = self.chatCommandMessage.GetValue() + + choice = self.chatCommandChannel + index = choice.GetSelection() + channel = choice.GetString(index) + + return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" + + def Serialize(self): + return { + 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), + 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), + 'channel' : self.chatCommandChannel .GetSelection(), + 'size' : self.chatCommandChatSize.GetSelection(), + 'duration' : self.chatCommandDuration.GetValue(), + 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'text' : self.chatCommandMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) + if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) + if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) + if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) + if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) + if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) + if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) + if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) + if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) + + +####### Chat Command Global +class ChatGlobalCmd(PowerBindCmd): + def BuildUI(self, dialog): + chatCommandGlobalSizer = wx.GridBagSizer(5,5) + + self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") + chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) + + self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalChannel.SetHint("Channel") + chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) + + self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') + chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) + + chatCommandGlobalSizer.AddGrowableCol(1) + + return chatCommandGlobalSizer + + def MakeBindString(self): + useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() + channel = self.chatCommandGlobalChannel.GetValue() + message = self.chatCommandGlobalMessage.GetValue() + + preface = "beginchat /" if useBeginchat else "" + + return f'{preface}send "{channel}" {message}' + + def Serialize(self): + return { + 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), + 'channel' : self.chatCommandGlobalChannel.GetValue(), + 'message' : self.chatCommandGlobalMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) + if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) + if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) + +#######Costume Change +class CostumeChangeCmd(PowerBindCmd): + def BuildUI(self, dialog): + costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeCostume = wx.Choice(dialog, -1, + choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) + self.costumeChangeCostume.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeEmote = wx.Choice(dialog, -1, + choices = GameData.Emotes['costumechange']) + self.costumeChangeEmote.Insert("- None -", 0) + self.costumeChangeEmote.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return costumeChangeSizer + + def MakeBindString(self): + costumeNumber = self.costumeChangeCostume.GetSelection() + costumeEmote = self.costumeChangeEmote.GetSelection() + + if costumeEmote: # None, or 0 == "- None -" + ccCmd = 'cce' + emoteName = self.costumeChangeEmote.GetString(costumeEmote) + emoteName = " CC" + emoteName.replace(" ","") + else: + ccCmd = 'cc' + emoteName = '' + + return f"{ccCmd} {costumeNumber}{emoteName}" + + def Serialize(self): + return{ + 'costumeNumber': self.costumeChangeCostume.GetSelection(), + 'costumeEmote' : self.costumeChangeEmote.GetSelection(), + } + + def Deserialize(self, init): + if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) + if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) + +####### Movement Command +class MovementCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + self.plusbutton.SetValue(True) + + self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.commandchoice = wx.Choice(dialog, choices = [ + "forward", "left", "right", "backward", "up", "down", + "turnleft", "turnright", "first", "autorun", "clicktomove", + ],) + sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) + self.commandchoice.SetSelection(0) + + self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + pre = post = '' + if self.plusbutton.GetValue() : pre = "+" + elif self.plusplusbutton.GetValue() : pre = "++" + elif self.minusbutton.GetValue() : pre = "-" + elif self.zerobutton.GetValue() : post = " 0" + elif self.onebutton.GetValue() : post = " 1" + + command = self.commandchoice.GetString(self.commandchoice.GetSelection()) + + return f"{pre}{command}{post}" + + def Serialize(self): + mod = '' + if self.plusbutton.GetValue() : mod = "plus" + elif self.plusplusbutton.GetValue() : mod = "plusplus" + elif self.minusbutton.GetValue() : mod = "minus" + elif self.zerobutton.GetValue() : mod = "zero" + elif self.onebutton.GetValue() : mod = "one" + + return { + 'mod' : mod, + 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), + } + + def Deserialize(self, init): + mod = init.get('mod', 'plus') + + if mod == 'plus' : self.plusbutton.SetValue(True) + elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) + elif mod == 'minus' : self.minusbutton.SetValue(True) + elif mod == 'zero' : self.zerobutton.SetValue(True) + elif mod == 'one' : self.onebutton.SetValue(True) + + self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) + +####### Graphics Command +class GraphicsCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.FlexGridSizer(2) + + self.visscalecb = wx.CheckBox(dialog, label = "visscale") + sizer.Add(self.visscalecb) + self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) + sizer.Add(self.visscalesc) + + self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") + sizer.Add(self.dofweightcb) + self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) + sizer.Add(self.dofweightsc) + + self.fsaacb = wx.CheckBox(dialog, label = "fsaa") + sizer.Add(self.fsaacb) + self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) + self.fsaach.SetSelection(0) + sizer.Add(self.fsaach) + + self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") + sizer.Add(self.bloomscalecb) + self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) + self.bloomscalech.SetSelection(0) + sizer.Add(self.bloomscalech) + + self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") + sizer.Add(self.bloomweightcb) + self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) + sizer.Add(self.bloomweightsc) + + self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") + sizer.Add(self.lodbiascb) + self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) + sizer.Add(self.lodbiassc) + + self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") + sizer.Add(self.renderscalecb) + self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) + sizer.Add(self.renderscalesc) + + return sizer + + def MakeBindString(self): + # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. + bindstrings = [] + if self.visscalecb.IsChecked(): + bindstrings.append("visscale " + str(self.visscalesc.GetValue())) + if self.dofweightcb.IsChecked(): + bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) + if self.fsaacb.IsChecked(): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bindstrings.append("fsaa " + fsaavalue) + if self.bloomscalecb.IsChecked(): + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + bindstrings.append("bloomscale " + bloomscalevalue) + if self.bloomweightcb.IsChecked(): + bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) + if self.lodbiascb.IsChecked(): + bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) + if self.renderscalecb.IsChecked(): + bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) + + return '$$'.join(bindstrings) + + def Serialize(self): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + return { + 'visscalecb' : self.visscalecb.IsChecked(), + 'visscalesc' : self.visscalesc.GetValue(), + 'dofweightcb' : self.dofweightcb.IsChecked(), + 'dofweightsc' : self.dofweightsc.GetValue(), + 'fsaacb' : self.fsaacb.IsChecked(), + 'fsaach' : fsaavalue, + 'bloomscalecb' : self.bloomscalecb.IsChecked(), + 'bloomscalech' : bloomscalevalue, + 'bloomweightcb' : self.bloomweightcb.IsChecked(), + 'bloomweightsc' : self.bloomweightsc.GetValue(), + 'lodbiascb' : self.lodbiascb.IsChecked(), + 'lodbiassc' : self.lodbiassc.GetValue(), + 'renderscalecb' : self.renderscalecb.IsChecked(), + 'renderscalesc' : self.renderscalesc.GetValue(), + } + + def Deserialize(self, init): + self.visscalecb.SetValue(init.get('visscalecb', False)) + self.visscalesc.SetValue(init.get('visscalesc', 1.0)) + self.dofweightcb.SetValue(init.get('dofweightcb', False)) + self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) + self.fsaacb.SetValue(init.get('fsaacb', False)) + self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) + self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) + self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) + self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) + self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) + self.lodbiascb.SetValue(init.get('lodbiascb', False)) + self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) + self.renderscalecb.SetValue(init.get('renderscalecb', False)) + self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) + +####### Custom Bind +class CustomBindCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.customBindName = wx.TextCtrl(dialog, -1) + self.customBindName.SetHint('Custom Bind Text') + sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + return self.customBindName.GetValue() + + def Serialize(self): + return { 'customBindName': self.customBindName.GetValue() } + + def Deserialize(self,init): + if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) + +####### Emote +class EmoteCmd(PowerBindCmd): + def BuildUI(self, dialog): + emoteSizer = wx.BoxSizer(wx.HORIZONTAL) + self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") + emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + self.emoteName = wx.Button(dialog, -1, "...") + self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) + emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) + + return emoteSizer + + def MakeBindString(self): + displayedEmoteName = self.emoteName.GetLabel() + actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] + + return actualEmotePayload + + def Serialize(self): + return {'emoteName': self.emoteName.GetLabel()} + + def Deserialize(self, init): + if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) + +####### Load Binds Directory +class LoadBindsDir(PowerBindCmd): + def BuildUI(self, dialog): + mainSizer = wx.BoxSizer(wx.VERTICAL) + + lbSizer = wx.BoxSizer(wx.HORIZONTAL) + lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") + lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + profiles = Profile.GetAllProfileBindsDirs() + + self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) + lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") + self.lbResetCB.SetValue(True) + + mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + return mainSizer + + def MakeBindString(self): + + # If the specified binds directory disappeared between runs, we'd crash, so handle that. + if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' + + config = wx.ConfigBase.Get() + if config.Exists('GameBindPath'): + bindpath = config.Read('GameBindPath') + else: + bindpath = config.Read('BindPath') + + reset = "" + if self.lbResetCB.GetValue(): + reset = "keybind_reset$$" + + resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' + return reset + 'bindloadfile ' + str(resetfilepath) + + def Serialize(self): + return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), + 'ResetKeybinds' : self.lbResetCB.GetValue(), + } + + def Deserialize(self, init): + if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) + self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) + +####### Power Abort +class PowerAbortCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecabort' + +####### Power Unqueue +class PowerUnqueueCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecunqueue' + +####### SG Mode +class SGModeCmd(PowerBindCmd): + def BuildUI(self, dialog): + sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) + sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") + self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") + + sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) + + return sgmodeSizer + + def MakeBindString(self): + if self.sgmodeOnRB.GetValue(): + return 'sgmodeset 1' + elif self.sgmodeOffRB.GetValue(): + return 'sgmodeset 0' + else: + return 'sgmode' + + def Serialize(self): + if self.sgmodeOnRB.GetValue(): + val = "On" + elif self.sgmodeOffRB.GetValue(): + val = "Off" + else: + val = "Toggle" + + return {"value" : val} + + def Deserialize(self, init): + val = init.get('value', '') + if val == "On": + self.sgmodeOnRB.SetValue(True) + elif val == "Off": + self.sgmodeOffRB.SetValue(True) + else: + self.sgmodeToggleRB.SetValue(True) + +####### Target Custom +class TargetCustomCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetCustomSizer = wx.GridBagSizer(5,5) + targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), + flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) + self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetCustomModeChoice.SetSelection(0) + targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) + self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) + self.targetCustomOptionalName.SetHint("Optional name to match") + targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) + self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") + targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) + self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") + targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) + self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") + targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) + self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") + targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) + self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") + targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) + self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") + targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) + self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") + targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) + self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") + targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) + + targetCustomSizer.AddGrowableCol(2) + + return targetCustomSizer + + def MakeBindString(self): + choice = self.targetCustomModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + targetCommand = "targetcustom" + mode.lower() + + enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" + friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" + defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" + alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" + mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" + notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" + base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" + notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" + + name = self.targetCustomOptionalName.GetValue() + + return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" + + def Serialize(self): + return { + 'mode' : self.targetCustomModeChoice.GetSelection(), + 'enemy' : self.targetCustomCBEnemies. IsChecked(), + 'friend' : self.targetCustomCBFriends. IsChecked(), + 'defeated' : self.targetCustomCBDefeated. IsChecked(), + 'alive' : self.targetCustomCBAlive. IsChecked(), + 'mypet' : self.targetCustomCBMyPets. IsChecked(), + 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), + 'base' : self.targetCustomCBBaseItems. IsChecked(), + 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), + 'name' : self.targetCustomOptionalName.GetValue(), + } + + def Deserialize(self, init): + if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) + if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) + if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) + if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) + if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) + if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) + if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) + if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) + if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) + if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) + + +####### Target Enemy +class TargetEnemyCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) + targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetEnemyModeChoice.SetSelection(0) + targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetEnemySizer + + def MakeBindString(self): + choice = self.targetEnemyModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetenemy" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetEnemyModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) + +####### Target Friend +class TargetFriendCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) + targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetFriendModeChoice.SetSelection(0) + targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetFriendSizer + + def MakeBindString(self): + choice = self.targetFriendModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetfriend" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetFriendModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) + +####### Team/Pet Select +class TeamPetSelectCmd(PowerBindCmd): + def BuildUI(self, dialog): + teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], + style=wx.ALIGN_CENTER_VERTICAL) + self.teamPetSelectNumber.SetSelection(0) + teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) + + return teamPetSelectSizer + + def MakeBindString(self): + teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' + targetNumber = self.teamPetSelectNumber.GetSelection()+1 + + return f"{teamOrPet}select {targetNumber}" + + def Serialize(self): + return { + 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', + 'targetNum': self.teamPetSelectNumber.GetSelection(), + } + + def Deserialize(self, init): + ToP = init.get('teamOrPet', '') + if ToP == 'pet': + self.teamPetSelectPetRB.SetValue(True) + else: + self.teamPetSelectTeamRB.SetValue(True) + if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) + +####### Unselect +class UnselectCmd(PowerBindCmd): + def MakeBindString(self): + return 'unselect' + +####### Use Insp By Name +class UseInspByNameCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) + for _, types in GameData.Inspirations.items(): + for _, info in types.items(): + for insp in info['tiers']: + name = re.sub(' ', '', str(insp)) + icon = GetIcon(f'Inspirations/{name}') + self.useInspByNameModeChoice.Append(insp, icon) + self.useInspByNameModeChoice.SetSelection(0) + useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) + + return useInspByNameSizer + + def MakeBindString(self): + choice = self.useInspByNameModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "inspexecname " + mode.lower() + + def GetAllInsps(self): + Insplist = [] + for _, info in GameData.Inspirations.items(): + for insp in info['tiers']: + Insplist.append(insp) + Insplist.append("---") + Insplist.pop(-1) # snip the terminal "---" + + return Insplist + + def Serialize(self): + return { 'insp' : self.useInspByNameModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) + +####### Use Insp From Row / Column +class UseInspRowColCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnRow.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) + self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnCol.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) + + return useInspRowColumnSizer + + def MakeBindString(self): + row = self.useInspRowColumnRow.GetSelection()+1 + col = self.useInspRowColumnCol.GetSelection()+1 + + return f"inspexectray {col} {row}" + + def Serialize(self): + return { + 'col' : self.useInspRowColumnCol.GetSelection(), + 'row' : self.useInspRowColumnRow.GetSelection(), + } + + def Deserialize(self, init): + if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) + if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) + +####### Use Power +class UsePowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + outerSizer = wx.BoxSizer(wx.HORIZONTAL) + + usePowerSizer = wx.GridBagSizer(5,5) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBToggle, (0,1)) + self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOn, (0,2)) + self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOff, (0,3)) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerName = PowerPicker(dialog) + usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) + usePowerSizer.AddGrowableCol(3) + + outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) + + return outerSizer + + def MakeBindString(self): + if self.usePowerRBToggle.GetValue(): + method = "powexecname" + elif self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') + return '' + + return f"{method} {self.usePowerName.GetLabel()}" + + def Serialize(self): + if self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + method = "powexecname" + return { + 'method': method, + 'pname' : self.usePowerName.GetLabel(), + 'picon' : self.usePowerName.IconFilename + } + + def Deserialize(self, init): + method = init.get('method', '') + if method == 'powexectoggleon': + self.usePowerRBOn.SetValue(True) + elif method == 'powexectoggleoff': + self.usePowerRBOff.SetValue(True) + else: + self.usePowerRBToggle.SetValue(True) + if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) + +####### Use Power From Tray +class UsePowerFromTrayCmd(PowerBindCmd): + def BuildUI(self, dialog): + usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTrayTray = wx.Choice(dialog, -1, + choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', + 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) + self.usePowerFromTrayTray.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) + self.usePowerFromTraySlot.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return usePowerFromTraySizer + + def MakeBindString(self): + choice = self.usePowerFromTrayTray + tray = choice.GetSelection() + + choice = self.usePowerFromTraySlot + slot = choice.GetSelection()+1 + + mode = "slot" + mode2 = '' + if tray > 3: + mode = "tray" + mode2 = f" {tray - 3}" + elif tray == 3: + mode = "alt2slot" + elif tray == 2: + mode = "altslot" + + return f"powexec{mode} {slot}{mode2}" + + def Serialize(self): + return { + 'tray' : self.usePowerFromTrayTray.GetSelection(), + 'slot' : self.usePowerFromTraySlot.GetSelection(), + } + + def Deserialize(self, init): + if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) + if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) + +####### Window Color +class WindowColorCmd(PowerBindCmd): + def BuildUI(self, dialog): + windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) + borderSizer = wx.BoxSizer(wx.VERTICAL) + self.ColorBorder.SetSizer(borderSizer) + self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) + borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) + + windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) + + RGBASizer = wx.FlexGridSizer(3, 4, 5) + + RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) + self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) + self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + windowColorSizer.Add(RGBASizer) + + self.UpdateFromSlider() + + return windowColorSizer + + def MakeBindString(self): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + return f"windowcolor {Rval} {Gval} {Bval} {Aval}" + + def Serialize(self): + return { + 'Rval' : self.RSlider.GetValue(), + 'Gval' : self.GSlider.GetValue(), + 'Bval' : self.BSlider.GetValue(), + 'Aval' : self.ASlider.GetValue(), + } + + def Deserialize(self, init): + self.RSlider.SetValue(init['Rval']) + self.GSlider.SetValue(init['Gval']) + self.BSlider.SetValue(init['Bval']) + self.ASlider.SetValue(init['Aval']) + self.UpdateFromSlider() + + def UpdateFromSlider(self, _ = None): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RReadout.SetValue(Rval) + self.GReadout.SetValue(Gval) + self.BReadout.SetValue(Bval) + self.AReadout.SetValue(Aval) + self.ColorBorder.Refresh() + + def UpdateFromText(self, _ = None): + Rval = self.RReadout.GetValue() + Gval = self.GReadout.GetValue() + Bval = self.BReadout.GetValue() + Aval = self.AReadout.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RSlider.SetValue(Rval) + self.GSlider.SetValue(Gval) + self.BSlider.SetValue(Bval) + self.ASlider.SetValue(Aval) + self.ColorBorder.Refresh() + +####### Window Save / Load +class WindowSaveLoadCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) + self.CommandChoice.SetSelection(0) + sizer.Add(self.CommandChoice, 0, wx.ALL, 5) + + self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), + value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) + sizer.Add(self.FilePath, 0, wx.ALL, 5) + + return sizer + + def MakeBindString(self): + command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] + return f'{command} "{self.FilePath.GetValue()}"' + + def Serialize(self): + return { + 'command' : self.CommandChoice.GetSelection(), + 'filename' : self.FilePath.GetValue(), + } + + def Deserialize(self, init): + self.CommandChoice.SetSelection(init.get('command', 0)) + self.FilePath.SetValue(init.get('filename', '')) + +####### Window Toggle +class WindowToggleCmd(PowerBindCmd): + def BuildUI(self, dialog): + self.WindowNames = { + 'Actions' : 'actions', + 'Auction House' : 'ah', + 'Badge' : 'badge', + 'Channel Search' : 'chansearch', + 'Chat' : 'chat', + 'Custom Chat 1' : 'chat1', + 'Custom Chat 2' : 'chat2', + 'Custom Chat 3' : 'chat3', + 'Custom Chat 4' : 'chat4', + 'Clues' : 'clue', + 'Combat Numbers' : 'combatnumbers', + 'Contacts' : 'contact', + 'Contact Finder' : 'contactfinder', + 'Costumes' : 'costume', + 'Email' : 'email', + 'Enhancements' : 'enhancements', + 'Friends' : 'friend', + 'Group' : 'group', + 'Help' : 'helpwindow', + 'Incarnate' : 'incarnate', + 'Inspirations' : 'insp', + 'League' : 'league', + 'LFG' : 'lfg', + 'Map' : 'map', + 'Mission' : 'mission', + 'Nav / Compass' : 'nav', + 'Options' : 'options', + 'Pets' : 'pet', + 'Petition' : 'petition', + 'Power Tray' : 'powers', + 'Power List' : 'powerlist', + 'Quit' : 'quit', + 'Recipes' : 'recipe', + 'Salvage' : 'salvage', + 'Search' : 'search', + 'Supergroup' : 'sg', + 'Target' : 'target', + 'Team' : 'team', + 'Tray' : 'tray', + 'Tray1' : 'tray1', + 'Tray2' : 'tray2', + 'Tray3' : 'tray3', + 'Tray4' : 'tray4', + 'Tray5' : 'tray5', + 'Tray6' : 'tray6', + 'Tray7' : 'tray7', + 'Tray8' : 'tray8', + 'Vault' : 'vault', + } + + self.ShortToggleCommands = { + 'Auction House' : 'ah', + 'Chat' : 'chat', + 'Help' : 'helpwindow', + 'Map' : 'map', + 'Nav / Compass' : 'nav', + 'Power Tray' : 'powers', + 'Target' : 'target', + 'Tray' : 'tray', + } + + windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) + windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) + self.windowToggleTray.SetSelection(0) + windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.windowShowRB = wx.RadioButton(dialog, -1, "Show") + self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") + + windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) + + return windowToggleSizer + + def MakeBindString(self): + choice = self.windowToggleTray + index = choice.GetSelection() + windowdesc = choice.GetString(index) + windowname = self.WindowNames[windowdesc] + + if self.windowShowRB.GetValue(): + return 'show ' + windowname + elif self.windowHideRB.GetValue(): + return 'windowhide ' + windowname + else: + if shortcmd := self.ShortToggleCommands.get(windowdesc, None): + return shortcmd + else: + return 'toggle ' + windowname + + + def Serialize(self): + choice = self.windowToggleTray + if self.windowShowRB.GetValue(): + action = "Show" + elif self.windowHideRB.GetValue(): + action = "Hide" + else: + action = "Toggle" + return { + 'window': choice.GetString(choice.GetSelection()), + 'action': action, + } + + def Deserialize(self, init): + choice = self.windowToggleTray + if window := init.get('window', ''): + if isinstance(window, int): + choice.SetSelection(window) + else: + choice.SetSelection(choice.FindString(window)) + + if choice.GetSelection() == wx.NOT_FOUND: + choice.SetSelection(0) + + action = init.get('action', '') + if action == "Show": + self.windowShowRB.SetValue(True) + elif action == "Hide": + self.windowHideRB.SetValue(True) + else: + self.windowToggleRB.SetValue(True) + + +# Must always add to this list when adding a new command class above +menuStructure = { + 'Graphics / UI' : [ + 'Attribute Monitor', + 'Buff Display Settings', + 'Graphics Settings', + 'Window Color', + 'Window Save / Load', + 'Window Toggle', + ], + 'Inspirations' : [ + 'Use Inspiration By Name', + 'Use Inspiration From Row/Column', + ], + 'Powers' : [ + 'Auto Power', + 'Power Abort', + 'Power Unqueue', + 'Use Power', + 'Use Power From Tray', + ], + 'Social' : [ + 'Away From Keyboard', + 'Chat Command', + 'Chat Command (Global)', + 'Costume Change', + 'Emote', + 'Supergroup Mode', + ], + 'Targeting' : [ + 'Target Custom', + 'Target Enemy', + 'Target Frield', + 'Team/Pet Select', + 'Unselect', + ], + 'Misc' : [ + 'Load Binds Directory', + 'Movement Commands', + ], + # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, + # but I'm leaving it here to remind myself that we do that. + } + +# Must always add to this list when adding a new command class above +commandClasses = { + 'Auto Power' : AutoPowerCmd, + 'Away From Keyboard' : AFKCmd, + 'Attribute Monitor' : AttributeMonitorCmd, + 'Buff Display Settings' : BuffDisplayCmd, + 'Chat Command' : ChatCmd, + 'Chat Command (Global)' : ChatGlobalCmd, + 'Costume Change' : CostumeChangeCmd, + 'Custom Bind' : CustomBindCmd, + 'Emote' : EmoteCmd, + 'Graphics Settings' : GraphicsCmd, + 'Load Binds Directory' : LoadBindsDir, + 'Movement Commands' : MovementCmd, + 'Power Abort' : PowerAbortCmd, + 'Power Unqueue' : PowerUnqueueCmd, + 'Supergroup Mode' : SGModeCmd, + 'Target Custom' : TargetCustomCmd, + 'Target Enemy' : TargetEnemyCmd, + 'Target Friend' : TargetFriendCmd, + 'Team/Pet Select' : TeamPetSelectCmd, + 'Unselect' : UnselectCmd, + 'Use Inspiration By Name' : UseInspByNameCmd, + 'Use Inspiration From Row/Column' : UseInspRowColCmd, + 'Use Power' : UsePowerCmd, + 'Use Power From Tray' : UsePowerFromTrayCmd, + 'Window Color' : WindowColorCmd, + 'Window Save / Load' : WindowSaveLoadCmd, + 'Window Toggle' : WindowToggleCmd, +} +# use these when we rename a commandClass so that old Profiles will still load correctly. +# If we've also updated the class, we need to try to make sure the new class will still +# Deserialize the legacy data, or at least not crash. +deprecatedCommandClasses = { + 'SG Mode Toggle' : SGModeCmd, + 'Use Insp By Name' : UseInspByNameCmd, + 'Use Insp From Row/Column' : UseInspRowColCmd, +} +commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/MovementCmd.py b/UI/PowerBinderCommand/MovementCmd.py new file mode 100644 index 0000000..4c02ab7 --- /dev/null +++ b/UI/PowerBinderCommand/MovementCmd.py @@ -0,0 +1,1800 @@ +import wx +import re +import UI +import UI.EmotePicker +from UI.ControlGroup import ControlGroup +from UI.PowerPicker import PowerPicker +from Help import HelpButton +import wx.adv +from wx.adv import BitmapComboBox, EditableListBox +from pathlib import PureWindowsPath +import GameData +import Profile +from Icon import GetIcon + +class PowerBinderDialog(wx.Dialog): + def __init__(self, parent, button, init = {}): + wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) + + self.Page = parent.Page + self.EditDialog = PowerBinderEditDialog(self) + self.Button = button + self.AddStepMenu = self.makeAddStepMenu() + + sizer = wx.BoxSizer(wx.VERTICAL); + self.mainSizer = sizer + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) + # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) + # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) + #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) + AddStepButton = wx.Button(self, -1, 'Add Step') + AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) + AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) + choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) + choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) + sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) + + rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) + + self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) + self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) + self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) + rearrangeCtrl.Add(self.RearrangeList, 1) + + rearrangeButtons = wx.BoxSizer(wx.VERTICAL) + self.DelButton = wx.Button(self, -1, "Delete") + self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) + self.EditButton = wx.Button(self, -1, "Edit") + self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) + self.EditButton.Disable() + upButton = wx.Button(self, -1, "\u25B2") + upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) + downButton = wx.Button(self, -1, "\u25BC") + downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) + rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) + rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) + + sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.BindStringDisplay = wx.TextCtrl(self, -1) + self.BindStringDisplay.Disable() + choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, + wx.ALIGN_CENTER_VERTICAL) + choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) + + sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) + + sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) + + # need to dig around and get the OK button since we show this dialog modelessly now. + okButton = self.FindWindow(self.GetAffirmativeId()) + okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) + + # Wrap everything in a vbox to add some padding + vbox = wx.BoxSizer(wx.VERTICAL); + vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); + + self.SetSizerAndFit(vbox); + self.Layout() + self.Fit() + self.SetFocus() + + # if we are loading from profile, ie, have "init", build the list from it + if init: self.LoadFromData(init) + + def LoadFromData(self, init): + for item in init: + for type, data in item.items(): + commandClass = commandClasses.get(type, None) + if not commandClass: + commandClass = deprecatedCommandClasses.get(type, None) + if not commandClass: + wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") + continue + newCommand = commandClass(self.EditDialog, data) + index = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.SetClientData(index, newCommand) + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) + self.EditDialog.mainSizer.Hide(newCommand.UI) + self.UpdateBindStringDisplay() + + def SaveToData(self): + data = [] + index = 0 + for _ in self.RearrangeList.GetItems(): + # check whether we have an object already attached to this choice + cmdObject = self.RearrangeList.GetClientData(index) + commandClassName = commandRevClasses[type(cmdObject)] + data.append({commandClassName: cmdObject.Serialize()}) + index = index + 1 + return data + + def OnAddStepButton(self, evt): + button = evt.EventObject + if not self.AddStepMenu: + self.AddStepMenu = self.makeAddStepMenu() + button.PopupMenu(self.AddStepMenu) + + + def OnOKButton(self, _): + if self.Button.tgtTxtCtrl: + bindString = self.MakeBindString() + if bindString != self.Button.tgtTxtCtrl.GetValue(): + self.Button.tgtTxtCtrl.SetValue(bindString) + wx.App.Get().Main.Profile.SetModified() + self.Close() + + def OnRearrangeDelete(self, _): + current = self.RearrangeList.GetSelection() + if current == wx.NOT_FOUND: return + + self.RearrangeList.Delete(current) + self.UpdateBindStringDisplay() + + def OnRearrangeUp(self, _): + self.RearrangeList.MoveCurrentUp() + self.UpdateBindStringDisplay() + + def OnRearrangeDown(self, _): + self.RearrangeList.MoveCurrentDown() + self.UpdateBindStringDisplay() + + def OnRearrangeEdit(self, _): + index = self.RearrangeList.GetSelection() + + # check whether we have an object already attached to this choice + cmdObject = None + try: + cmdObject = self.RearrangeList.GetClientData(index) + except Exception: + pass + + if cmdObject: + self.ShowEditDialogFor(cmdObject) + self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) + else: + print("cmdObject was None") + self.UpdateBindStringDisplay() + + # OnAddStepMenu creates a new step and adds it to the rearrangelist + def OnAddStepMenu(self, evt): + menuitem = self.AddStepMenu.FindItemById(evt.GetId()) + chosenName = menuitem.GetItemLabel() + + # make a new command object, attached to the parent dialog + newCommandClass = commandClasses[chosenName] + newCommand = newCommandClass(self.EditDialog) + + # show the edit dialog if this command needs it + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) + if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): + self.EditDialog.mainSizer.Remove(newCommand.UI) + return + + newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.Select(newBindIndex) + self.RearrangeList.SetClientData(newBindIndex, newCommand) + + self.OnListSelect() + self.UpdateBindStringDisplay() + + def OnListSelect(self, _ = None): + selected = self.RearrangeList.GetSelection() + + if selected != wx.NOT_FOUND: + selCommand = self.RearrangeList.GetClientData(selected) + if selCommand.UI: + self.EditButton.Enable() + else: + self.EditButton.Disable() + + def UpdateBindStringDisplay(self): + self.BindStringDisplay.SetValue(self.MakeBindString()) + self.BindStringDisplay.SetToolTip(self.MakeBindString()) + + def MakeBindString(self): + cmdBindStrings = [] + for index in range(self.RearrangeList.GetCount()): + c = self.RearrangeList.GetClientData(index) + if c: cmdBindStrings.append(c.MakeBindString()) + + bindstring = ('$$'.join(cmdBindStrings)) + return bindstring + + def ShowEditDialogFor(self, command): + if not command.UI: return + + self.EditDialog.mainSizer.Show(command.UI) + + self.EditDialog.Layout() + self.EditDialog.Fit() + + self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') + returnval = self.EditDialog.ShowModal() + + self.EditDialog.mainSizer.Hide(command.UI) + + return returnval + + def makeAddStepMenu(self): + + stepMenu = wx.Menu() + + for subname in menuStructure: + submenu = wx.Menu() + stepMenu.AppendSubMenu(submenu, subname) + for classname in menuStructure[subname]: + submenu.Append(wx.ID_ANY, classname) + + stepMenu.Append(wx.ID_ANY, 'Custom Bind') + + return stepMenu + +class PowerBinderButton(wx.BitmapButton): + + def __init__(self, parent, tgtTxtCtrl, init = {}): + wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) + self.Init = init + self.Dialog = None + self.DialogParent = parent + + self.tgtTxtCtrl = tgtTxtCtrl + self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) + self.SetToolTip("Launch PowerBinder") + + def PowerBinderEventHandler(self, _): + self.PowerBinderDialog().Show() + + def LoadFromData(self, data): + self.PowerBinderDialog().LoadFromData(data) + + def SaveToData(self): + return self.PowerBinderDialog().SaveToData() + + def PowerBinderDialog(self): + if not self.Dialog: + self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) + return self.Dialog + + +class PowerBinderEditDialog(wx.Dialog): + def __init__(self, parent): + wx.Dialog.__init__(self, parent, -1, "Edit Step", + style = wx.DEFAULT_DIALOG_STYLE) + + outerSizer = wx.BoxSizer(wx.VERTICAL) + + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + self.mainSizer.SetMinSize([500, 150]) + + self.Page = parent.Page + + self.mainSizer.Add( + self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), + 0, wx.EXPAND|wx.ALL, 10) + + outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) + + self.SetSizerAndFit(outerSizer) + self.Layout() + self.Fit() + +########### Power Binder Command Objects +class PowerBindCmd(): + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + commandClassName = commandRevClasses[type(self)] + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{commandClassName} - {short_bindstr}" + + +####### Away From Keyboard +class AFKCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) + +####### Attribute Monitor +class AttributeMonitorCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.Groups = {} + self.AttributeTable = { + 'Base' : { + 'Current Hit Points' : 'NT H', + 'Max Hit Points' : 'X H', + 'Current Endurance' : 'T E', + 'Max Endurance' : 'X EN', + 'Regeneration Rate' : 'N RAT', + 'Recovery Rate' : 'Y RA', + 'Endurance Consumption' : 'SU', + 'ToHit Bonus' : 'T B', + 'Accuracy Bonus' : 'CC', + 'Last Hit Chance' : 'T C', + 'Damage Bonus' : 'DA', + 'Healing Bonus' : 'NG B', + 'Recharge Time Bonus' : 'ME B', + 'Endurance Discount' : 'CE DIS', + 'Stealth Radius (PvP)' : 'PVP', + 'Stealth Radius (PvE)' : 'PVE', + 'Perception Radius' : 'RC', + 'Range Bonus' : 'GE B', + 'Threat Level' : 'AT L', + 'Experience to Next Level' : 'XT', + 'Experience Debt' : 'XP', + 'Influence / Infamy' : 'INF', + 'Inherent' : 'NH', + }, + 'Movement Speed' : { + 'Flying Speed' : 'FL', + 'Jumping Speed' : 'PI', + 'Max Jump Height' : 'X J', + 'Run Speed' : 'RU', + }, + 'Damage Resistance' : { + 'Smashing Resistance' : 'G R', + 'Lethal Resistance' : 'L R', + 'Fire Resistance' : 'RE R', + 'Cold Resistance' : 'COLD R', + 'Energy Resistance' : 'DamageType[4]', + 'Negative Energy Resistance' : 'GY R', + 'Psyonic Resistance' : 'NIC R', + 'Toxic Resistance' : 'XIC R', + }, + 'Defense' : { + 'Base Defense' : 'BAS', + 'Ranged Defense' : 'ED', + 'Melee Defense' : 'MEL', + 'AoE Defense' : '2', + 'Smashing Defense' : '3', + 'Lethal Defense' : '4', + 'Fire Defense' : '5', + 'Cold Defense' : '6', + 'Energy Defense' : '7', + 'Negative Energy Defense' : '8', + 'Psionic Defense' : '9', + 'Toxic Defense' : '1', + }, + 'Debuff Resistance' : { + 'Regeneration Resistance' : 'ON R', + 'Recovery Resistance' : 'RY R', + 'To Hit Resistance' : 'IT R', + 'Defense Resistance' : 'NSE RES', + }, + 'Status Effect Protection' : { + 'Hold Protection' : 'D P', + 'Immobilize Protection' : 'LIZE P', + 'Stun Protection' : 'N P', + 'Sleep Protection' : 'P P', + 'Knockback Protection' : 'K P', + 'Confuse Protection' : 'SE P', + 'Terrorize Protection' : 'ZE P', + 'Repel Protection' : 'EL P', + 'Teleport Protection' : 'T P', + }, + 'Status Effect Resistance' : { + 'Hold Resistance' : 'D R', + 'Immobilize Resistance' : 'LIZE R', + 'Stun Resistance' : 'N R', + 'Sleep Resistance' : 'P R', + 'Knockback Resistance' : 'K R', + 'Confuse Resistance' : 'SE R', + 'Terrorize Resistance' : 'ZE R', + 'Placate Resistance' : 'TE R', + 'Taunt Resistance' : 'NT R', + }, + 'Miscellaneous' : { + 'Level Shift' : 'L S', + }, + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.AttributeMenu = wx.Menu() + for group, controls in self.AttributeTable.items(): + submenu = wx.Menu() + self.AttributeMenu.AppendSubMenu(submenu, group) + for cb in controls: + submenu.Append(wx.ID_ANY, cb) + + self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) + + self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) + groupSizer.Add(self.editbox) + + newButton = self.editbox.GetNewButton() + newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) + + return groupSizer + + def MakeBindString(self): + map = {} + bindstrings = [] + for _, controls in self.AttributeTable.items(): + for cb, data in controls.items(): + map[cb] = data + + for string in self.editbox.GetStrings(): + if string: + bindstrings.append(f'monitorattribute {map[string]}') + + return '$$'.join(bindstrings) + + def Serialize(self): + return { + 'attributes' : self.editbox.GetStrings() + } + + def Deserialize(self, init): + self.editbox.SetStrings(init.get('attributes', [])) + + def OnNewButton(self, evt): + evt.GetEventObject().PopupMenu(self.AttributeMenu) + + def OnMenuItem(self, evt): + menuitem = evt.EventObject.FindItemById(evt.GetId()) + existingstrings = self.editbox.GetStrings() + existingstrings.append(menuitem.GetItemLabel()) + self.editbox.SetStrings(existingstrings) + +####### Auto Power +class AutoPowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) + autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.autoPowerName = PowerPicker(dialog) + autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) + + return autoPowerSizer + + def MakeBindString(self): + return f"powexecauto {self.autoPowerName.GetLabel()}" + + def Serialize(self): + return { + 'pname' : self.autoPowerName.GetLabel(), + 'picon' : self.autoPowerName.IconFilename + } + + def Deserialize(self, init): + if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) + +####### Buff Display Command +class BuffDisplayCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.buffDisplayMap = { + 'Status Window' : { + 'Hide Auto' : 1, + 'Hide Toggles' : 2, + 'No Blinking' : 4, + 'No Stacking' : 8, + 'Numeric Stacking' : 16, + 'Hide Buff Numbers' : 32, + 'Stop Sending Buffs' : 64, + }, + 'Group Window' : { + 'Hide Auto' : 256, + 'Hide Toggles' : 512, + 'No Blinking' : 1024, + 'No Stacking' : 2048, + 'Numeric Stacking' : 4096, + 'Hide Buff Numbers' : 8192, + 'Stop Sending Buffs' : 16384, + }, + 'Pet Window' : { + 'Hide Auto' : 65536, + 'Hide Toggles' : 131072, + 'No Blinking' : 262144, + 'No Stacking' : 524288, + 'Numeric Stacking' : 1048576, + 'Hide Buff Numbers' : 2097152, + 'Stop Sending Buffs' : 4194304, + }, + } + self.Groups = {} + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + for group, controls in self.buffDisplayMap.items(): + self.Groups[group] = ControlGroup(dialog, self.Page, label = group) + groupid = self.Groups[group].GetStaticBox().GetId() + for cb, data in controls.items(): + self.Groups[group].AddControl( + ctlType = 'checkbox', + ctlName = f"{groupid}_{group}_{cb}", + label = cb, + data = data, + ) + + groupSizer.Add(self.Groups[group]) + + return groupSizer + + def CalculateValue(self): + page = wx.App.Get().Main.Profile.CustomBinds + + total = 0 + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] + if checkbox.IsChecked(): + total = total + checkbox.Data + return total + + def MakeBindString(self): + return f"optionset buffsettings {self.CalculateValue()}" + + def Serialize(self): + return { 'value' : self.CalculateValue() } + + def Deserialize(self, init): + value = init.get('value', 0) + + value = value or 0 # in case we had for some reason 'None' stashed in the init values + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] + checkbox.SetValue( checkbox.Data & value ) + +####### Chat Command +class ChatCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.chatChannelMap = { # before __init__ + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + chatCommandSizer = wx.GridBagSizer(5, 5) + self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") + chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) + # row 1 + self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) + self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) + self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) + # row 2 + self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) + self.chatCommandDuration.SetRange(1, 20) + self.chatCommandDuration.SetValue(7) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandDuration, (2,1)) + self.chatCommandChatSize = wx.Choice(dialog, -1, + choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) + self.chatCommandChatSize.SetSelection(5) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) + self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) + self.chatCommandChannel.SetSelection(0) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChannel, (2,5)) + # row 3 + self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") + chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) + self.chatCommandMessage = wx.TextCtrl(dialog, -1) + self.chatCommandMessage.SetHint('Chat Command Text') + chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) + + return chatCommandSizer + + def MakeBindString(self): + duration = self.chatCommandDuration.GetValue() + + choice = self.chatCommandChatSize + index = choice.GetSelection() + size = choice.GetString(index) + + duration = f"" if duration != 7 else "" + size = f"" if size != "1" else "" + + bdcolor = fgcolor = bgcolor = '' + if self.chatCommandUseColorsCB.IsChecked(): + bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + + bdcolor = f"" + fgcolor = f"" + bgcolor = f"" + + beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' + text = self.chatCommandMessage.GetValue() + + choice = self.chatCommandChannel + index = choice.GetSelection() + channel = choice.GetString(index) + + return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" + + def Serialize(self): + return { + 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), + 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), + 'channel' : self.chatCommandChannel .GetSelection(), + 'size' : self.chatCommandChatSize.GetSelection(), + 'duration' : self.chatCommandDuration.GetValue(), + 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'text' : self.chatCommandMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) + if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) + if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) + if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) + if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) + if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) + if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) + if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) + if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) + + +####### Chat Command Global +class ChatGlobalCmd(PowerBindCmd): + def BuildUI(self, dialog): + chatCommandGlobalSizer = wx.GridBagSizer(5,5) + + self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") + chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) + + self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalChannel.SetHint("Channel") + chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) + + self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') + chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) + + chatCommandGlobalSizer.AddGrowableCol(1) + + return chatCommandGlobalSizer + + def MakeBindString(self): + useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() + channel = self.chatCommandGlobalChannel.GetValue() + message = self.chatCommandGlobalMessage.GetValue() + + preface = "beginchat /" if useBeginchat else "" + + return f'{preface}send "{channel}" {message}' + + def Serialize(self): + return { + 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), + 'channel' : self.chatCommandGlobalChannel.GetValue(), + 'message' : self.chatCommandGlobalMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) + if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) + if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) + +#######Costume Change +class CostumeChangeCmd(PowerBindCmd): + def BuildUI(self, dialog): + costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeCostume = wx.Choice(dialog, -1, + choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) + self.costumeChangeCostume.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeEmote = wx.Choice(dialog, -1, + choices = GameData.Emotes['costumechange']) + self.costumeChangeEmote.Insert("- None -", 0) + self.costumeChangeEmote.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return costumeChangeSizer + + def MakeBindString(self): + costumeNumber = self.costumeChangeCostume.GetSelection() + costumeEmote = self.costumeChangeEmote.GetSelection() + + if costumeEmote: # None, or 0 == "- None -" + ccCmd = 'cce' + emoteName = self.costumeChangeEmote.GetString(costumeEmote) + emoteName = " CC" + emoteName.replace(" ","") + else: + ccCmd = 'cc' + emoteName = '' + + return f"{ccCmd} {costumeNumber}{emoteName}" + + def Serialize(self): + return{ + 'costumeNumber': self.costumeChangeCostume.GetSelection(), + 'costumeEmote' : self.costumeChangeEmote.GetSelection(), + } + + def Deserialize(self, init): + if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) + if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) + +####### Movement Command +class MovementCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + self.plusbutton.SetValue(True) + + self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.commandchoice = wx.Choice(dialog, choices = [ + "forward", "left", "right", "backward", "up", "down", + "turnleft", "turnright", "first", "autorun", "clicktomove", + ],) + sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) + self.commandchoice.SetSelection(0) + + self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + pre = post = '' + if self.plusbutton.GetValue() : pre = "+" + elif self.plusplusbutton.GetValue() : pre = "++" + elif self.minusbutton.GetValue() : pre = "-" + elif self.zerobutton.GetValue() : post = " 0" + elif self.onebutton.GetValue() : post = " 1" + + command = self.commandchoice.GetString(self.commandchoice.GetSelection()) + + return f"{pre}{command}{post}" + + def Serialize(self): + mod = '' + if self.plusbutton.GetValue() : mod = "plus" + elif self.plusplusbutton.GetValue() : mod = "plusplus" + elif self.minusbutton.GetValue() : mod = "minus" + elif self.zerobutton.GetValue() : mod = "zero" + elif self.onebutton.GetValue() : mod = "one" + + return { + 'mod' : mod, + 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), + } + + def Deserialize(self, init): + mod = init.get('mod', 'plus') + + if mod == 'plus' : self.plusbutton.SetValue(True) + elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) + elif mod == 'minus' : self.minusbutton.SetValue(True) + elif mod == 'zero' : self.zerobutton.SetValue(True) + elif mod == 'one' : self.onebutton.SetValue(True) + + self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) + +####### Graphics Command +class GraphicsCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.FlexGridSizer(2) + + self.visscalecb = wx.CheckBox(dialog, label = "visscale") + sizer.Add(self.visscalecb) + self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) + sizer.Add(self.visscalesc) + + self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") + sizer.Add(self.dofweightcb) + self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) + sizer.Add(self.dofweightsc) + + self.fsaacb = wx.CheckBox(dialog, label = "fsaa") + sizer.Add(self.fsaacb) + self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) + self.fsaach.SetSelection(0) + sizer.Add(self.fsaach) + + self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") + sizer.Add(self.bloomscalecb) + self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) + self.bloomscalech.SetSelection(0) + sizer.Add(self.bloomscalech) + + self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") + sizer.Add(self.bloomweightcb) + self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) + sizer.Add(self.bloomweightsc) + + self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") + sizer.Add(self.lodbiascb) + self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) + sizer.Add(self.lodbiassc) + + self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") + sizer.Add(self.renderscalecb) + self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) + sizer.Add(self.renderscalesc) + + return sizer + + def MakeBindString(self): + # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. + bindstrings = [] + if self.visscalecb.IsChecked(): + bindstrings.append("visscale " + str(self.visscalesc.GetValue())) + if self.dofweightcb.IsChecked(): + bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) + if self.fsaacb.IsChecked(): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bindstrings.append("fsaa " + fsaavalue) + if self.bloomscalecb.IsChecked(): + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + bindstrings.append("bloomscale " + bloomscalevalue) + if self.bloomweightcb.IsChecked(): + bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) + if self.lodbiascb.IsChecked(): + bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) + if self.renderscalecb.IsChecked(): + bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) + + return '$$'.join(bindstrings) + + def Serialize(self): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + return { + 'visscalecb' : self.visscalecb.IsChecked(), + 'visscalesc' : self.visscalesc.GetValue(), + 'dofweightcb' : self.dofweightcb.IsChecked(), + 'dofweightsc' : self.dofweightsc.GetValue(), + 'fsaacb' : self.fsaacb.IsChecked(), + 'fsaach' : fsaavalue, + 'bloomscalecb' : self.bloomscalecb.IsChecked(), + 'bloomscalech' : bloomscalevalue, + 'bloomweightcb' : self.bloomweightcb.IsChecked(), + 'bloomweightsc' : self.bloomweightsc.GetValue(), + 'lodbiascb' : self.lodbiascb.IsChecked(), + 'lodbiassc' : self.lodbiassc.GetValue(), + 'renderscalecb' : self.renderscalecb.IsChecked(), + 'renderscalesc' : self.renderscalesc.GetValue(), + } + + def Deserialize(self, init): + self.visscalecb.SetValue(init.get('visscalecb', False)) + self.visscalesc.SetValue(init.get('visscalesc', 1.0)) + self.dofweightcb.SetValue(init.get('dofweightcb', False)) + self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) + self.fsaacb.SetValue(init.get('fsaacb', False)) + self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) + self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) + self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) + self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) + self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) + self.lodbiascb.SetValue(init.get('lodbiascb', False)) + self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) + self.renderscalecb.SetValue(init.get('renderscalecb', False)) + self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) + +####### Custom Bind +class CustomBindCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.customBindName = wx.TextCtrl(dialog, -1) + self.customBindName.SetHint('Custom Bind Text') + sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + return self.customBindName.GetValue() + + def Serialize(self): + return { 'customBindName': self.customBindName.GetValue() } + + def Deserialize(self,init): + if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) + +####### Emote +class EmoteCmd(PowerBindCmd): + def BuildUI(self, dialog): + emoteSizer = wx.BoxSizer(wx.HORIZONTAL) + self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") + emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + self.emoteName = wx.Button(dialog, -1, "...") + self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) + emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) + + return emoteSizer + + def MakeBindString(self): + displayedEmoteName = self.emoteName.GetLabel() + actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] + + return actualEmotePayload + + def Serialize(self): + return {'emoteName': self.emoteName.GetLabel()} + + def Deserialize(self, init): + if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) + +####### Load Binds Directory +class LoadBindsDir(PowerBindCmd): + def BuildUI(self, dialog): + mainSizer = wx.BoxSizer(wx.VERTICAL) + + lbSizer = wx.BoxSizer(wx.HORIZONTAL) + lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") + lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + profiles = Profile.GetAllProfileBindsDirs() + + self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) + lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") + self.lbResetCB.SetValue(True) + + mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + return mainSizer + + def MakeBindString(self): + + # If the specified binds directory disappeared between runs, we'd crash, so handle that. + if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' + + config = wx.ConfigBase.Get() + if config.Exists('GameBindPath'): + bindpath = config.Read('GameBindPath') + else: + bindpath = config.Read('BindPath') + + reset = "" + if self.lbResetCB.GetValue(): + reset = "keybind_reset$$" + + resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' + return reset + 'bindloadfile ' + str(resetfilepath) + + def Serialize(self): + return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), + 'ResetKeybinds' : self.lbResetCB.GetValue(), + } + + def Deserialize(self, init): + if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) + self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) + +####### Power Abort +class PowerAbortCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecabort' + +####### Power Unqueue +class PowerUnqueueCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecunqueue' + +####### SG Mode +class SGModeCmd(PowerBindCmd): + def BuildUI(self, dialog): + sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) + sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") + self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") + + sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) + + return sgmodeSizer + + def MakeBindString(self): + if self.sgmodeOnRB.GetValue(): + return 'sgmodeset 1' + elif self.sgmodeOffRB.GetValue(): + return 'sgmodeset 0' + else: + return 'sgmode' + + def Serialize(self): + if self.sgmodeOnRB.GetValue(): + val = "On" + elif self.sgmodeOffRB.GetValue(): + val = "Off" + else: + val = "Toggle" + + return {"value" : val} + + def Deserialize(self, init): + val = init.get('value', '') + if val == "On": + self.sgmodeOnRB.SetValue(True) + elif val == "Off": + self.sgmodeOffRB.SetValue(True) + else: + self.sgmodeToggleRB.SetValue(True) + +####### Target Custom +class TargetCustomCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetCustomSizer = wx.GridBagSizer(5,5) + targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), + flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) + self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetCustomModeChoice.SetSelection(0) + targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) + self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) + self.targetCustomOptionalName.SetHint("Optional name to match") + targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) + self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") + targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) + self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") + targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) + self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") + targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) + self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") + targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) + self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") + targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) + self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") + targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) + self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") + targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) + self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") + targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) + + targetCustomSizer.AddGrowableCol(2) + + return targetCustomSizer + + def MakeBindString(self): + choice = self.targetCustomModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + targetCommand = "targetcustom" + mode.lower() + + enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" + friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" + defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" + alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" + mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" + notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" + base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" + notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" + + name = self.targetCustomOptionalName.GetValue() + + return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" + + def Serialize(self): + return { + 'mode' : self.targetCustomModeChoice.GetSelection(), + 'enemy' : self.targetCustomCBEnemies. IsChecked(), + 'friend' : self.targetCustomCBFriends. IsChecked(), + 'defeated' : self.targetCustomCBDefeated. IsChecked(), + 'alive' : self.targetCustomCBAlive. IsChecked(), + 'mypet' : self.targetCustomCBMyPets. IsChecked(), + 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), + 'base' : self.targetCustomCBBaseItems. IsChecked(), + 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), + 'name' : self.targetCustomOptionalName.GetValue(), + } + + def Deserialize(self, init): + if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) + if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) + if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) + if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) + if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) + if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) + if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) + if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) + if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) + if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) + + +####### Target Enemy +class TargetEnemyCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) + targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetEnemyModeChoice.SetSelection(0) + targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetEnemySizer + + def MakeBindString(self): + choice = self.targetEnemyModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetenemy" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetEnemyModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) + +####### Target Friend +class TargetFriendCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) + targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetFriendModeChoice.SetSelection(0) + targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetFriendSizer + + def MakeBindString(self): + choice = self.targetFriendModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetfriend" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetFriendModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) + +####### Team/Pet Select +class TeamPetSelectCmd(PowerBindCmd): + def BuildUI(self, dialog): + teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], + style=wx.ALIGN_CENTER_VERTICAL) + self.teamPetSelectNumber.SetSelection(0) + teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) + + return teamPetSelectSizer + + def MakeBindString(self): + teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' + targetNumber = self.teamPetSelectNumber.GetSelection()+1 + + return f"{teamOrPet}select {targetNumber}" + + def Serialize(self): + return { + 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', + 'targetNum': self.teamPetSelectNumber.GetSelection(), + } + + def Deserialize(self, init): + ToP = init.get('teamOrPet', '') + if ToP == 'pet': + self.teamPetSelectPetRB.SetValue(True) + else: + self.teamPetSelectTeamRB.SetValue(True) + if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) + +####### Unselect +class UnselectCmd(PowerBindCmd): + def MakeBindString(self): + return 'unselect' + +####### Use Insp By Name +class UseInspByNameCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) + for _, types in GameData.Inspirations.items(): + for _, info in types.items(): + for insp in info['tiers']: + name = re.sub(' ', '', str(insp)) + icon = GetIcon(f'Inspirations/{name}') + self.useInspByNameModeChoice.Append(insp, icon) + self.useInspByNameModeChoice.SetSelection(0) + useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) + + return useInspByNameSizer + + def MakeBindString(self): + choice = self.useInspByNameModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "inspexecname " + mode.lower() + + def GetAllInsps(self): + Insplist = [] + for _, info in GameData.Inspirations.items(): + for insp in info['tiers']: + Insplist.append(insp) + Insplist.append("---") + Insplist.pop(-1) # snip the terminal "---" + + return Insplist + + def Serialize(self): + return { 'insp' : self.useInspByNameModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) + +####### Use Insp From Row / Column +class UseInspRowColCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnRow.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) + self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnCol.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) + + return useInspRowColumnSizer + + def MakeBindString(self): + row = self.useInspRowColumnRow.GetSelection()+1 + col = self.useInspRowColumnCol.GetSelection()+1 + + return f"inspexectray {col} {row}" + + def Serialize(self): + return { + 'col' : self.useInspRowColumnCol.GetSelection(), + 'row' : self.useInspRowColumnRow.GetSelection(), + } + + def Deserialize(self, init): + if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) + if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) + +####### Use Power +class UsePowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + outerSizer = wx.BoxSizer(wx.HORIZONTAL) + + usePowerSizer = wx.GridBagSizer(5,5) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBToggle, (0,1)) + self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOn, (0,2)) + self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOff, (0,3)) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerName = PowerPicker(dialog) + usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) + usePowerSizer.AddGrowableCol(3) + + outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) + + return outerSizer + + def MakeBindString(self): + if self.usePowerRBToggle.GetValue(): + method = "powexecname" + elif self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') + return '' + + return f"{method} {self.usePowerName.GetLabel()}" + + def Serialize(self): + if self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + method = "powexecname" + return { + 'method': method, + 'pname' : self.usePowerName.GetLabel(), + 'picon' : self.usePowerName.IconFilename + } + + def Deserialize(self, init): + method = init.get('method', '') + if method == 'powexectoggleon': + self.usePowerRBOn.SetValue(True) + elif method == 'powexectoggleoff': + self.usePowerRBOff.SetValue(True) + else: + self.usePowerRBToggle.SetValue(True) + if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) + +####### Use Power From Tray +class UsePowerFromTrayCmd(PowerBindCmd): + def BuildUI(self, dialog): + usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTrayTray = wx.Choice(dialog, -1, + choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', + 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) + self.usePowerFromTrayTray.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) + self.usePowerFromTraySlot.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return usePowerFromTraySizer + + def MakeBindString(self): + choice = self.usePowerFromTrayTray + tray = choice.GetSelection() + + choice = self.usePowerFromTraySlot + slot = choice.GetSelection()+1 + + mode = "slot" + mode2 = '' + if tray > 3: + mode = "tray" + mode2 = f" {tray - 3}" + elif tray == 3: + mode = "alt2slot" + elif tray == 2: + mode = "altslot" + + return f"powexec{mode} {slot}{mode2}" + + def Serialize(self): + return { + 'tray' : self.usePowerFromTrayTray.GetSelection(), + 'slot' : self.usePowerFromTraySlot.GetSelection(), + } + + def Deserialize(self, init): + if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) + if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) + +####### Window Color +class WindowColorCmd(PowerBindCmd): + def BuildUI(self, dialog): + windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) + borderSizer = wx.BoxSizer(wx.VERTICAL) + self.ColorBorder.SetSizer(borderSizer) + self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) + borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) + + windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) + + RGBASizer = wx.FlexGridSizer(3, 4, 5) + + RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) + self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) + self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + windowColorSizer.Add(RGBASizer) + + self.UpdateFromSlider() + + return windowColorSizer + + def MakeBindString(self): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + return f"windowcolor {Rval} {Gval} {Bval} {Aval}" + + def Serialize(self): + return { + 'Rval' : self.RSlider.GetValue(), + 'Gval' : self.GSlider.GetValue(), + 'Bval' : self.BSlider.GetValue(), + 'Aval' : self.ASlider.GetValue(), + } + + def Deserialize(self, init): + self.RSlider.SetValue(init['Rval']) + self.GSlider.SetValue(init['Gval']) + self.BSlider.SetValue(init['Bval']) + self.ASlider.SetValue(init['Aval']) + self.UpdateFromSlider() + + def UpdateFromSlider(self, _ = None): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RReadout.SetValue(Rval) + self.GReadout.SetValue(Gval) + self.BReadout.SetValue(Bval) + self.AReadout.SetValue(Aval) + self.ColorBorder.Refresh() + + def UpdateFromText(self, _ = None): + Rval = self.RReadout.GetValue() + Gval = self.GReadout.GetValue() + Bval = self.BReadout.GetValue() + Aval = self.AReadout.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RSlider.SetValue(Rval) + self.GSlider.SetValue(Gval) + self.BSlider.SetValue(Bval) + self.ASlider.SetValue(Aval) + self.ColorBorder.Refresh() + +####### Window Save / Load +class WindowSaveLoadCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) + self.CommandChoice.SetSelection(0) + sizer.Add(self.CommandChoice, 0, wx.ALL, 5) + + self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), + value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) + sizer.Add(self.FilePath, 0, wx.ALL, 5) + + return sizer + + def MakeBindString(self): + command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] + return f'{command} "{self.FilePath.GetValue()}"' + + def Serialize(self): + return { + 'command' : self.CommandChoice.GetSelection(), + 'filename' : self.FilePath.GetValue(), + } + + def Deserialize(self, init): + self.CommandChoice.SetSelection(init.get('command', 0)) + self.FilePath.SetValue(init.get('filename', '')) + +####### Window Toggle +class WindowToggleCmd(PowerBindCmd): + def BuildUI(self, dialog): + self.WindowNames = { + 'Actions' : 'actions', + 'Auction House' : 'ah', + 'Badge' : 'badge', + 'Channel Search' : 'chansearch', + 'Chat' : 'chat', + 'Custom Chat 1' : 'chat1', + 'Custom Chat 2' : 'chat2', + 'Custom Chat 3' : 'chat3', + 'Custom Chat 4' : 'chat4', + 'Clues' : 'clue', + 'Combat Numbers' : 'combatnumbers', + 'Contacts' : 'contact', + 'Contact Finder' : 'contactfinder', + 'Costumes' : 'costume', + 'Email' : 'email', + 'Enhancements' : 'enhancements', + 'Friends' : 'friend', + 'Group' : 'group', + 'Help' : 'helpwindow', + 'Incarnate' : 'incarnate', + 'Inspirations' : 'insp', + 'League' : 'league', + 'LFG' : 'lfg', + 'Map' : 'map', + 'Mission' : 'mission', + 'Nav / Compass' : 'nav', + 'Options' : 'options', + 'Pets' : 'pet', + 'Petition' : 'petition', + 'Power Tray' : 'powers', + 'Power List' : 'powerlist', + 'Quit' : 'quit', + 'Recipes' : 'recipe', + 'Salvage' : 'salvage', + 'Search' : 'search', + 'Supergroup' : 'sg', + 'Target' : 'target', + 'Team' : 'team', + 'Tray' : 'tray', + 'Tray1' : 'tray1', + 'Tray2' : 'tray2', + 'Tray3' : 'tray3', + 'Tray4' : 'tray4', + 'Tray5' : 'tray5', + 'Tray6' : 'tray6', + 'Tray7' : 'tray7', + 'Tray8' : 'tray8', + 'Vault' : 'vault', + } + + self.ShortToggleCommands = { + 'Auction House' : 'ah', + 'Chat' : 'chat', + 'Help' : 'helpwindow', + 'Map' : 'map', + 'Nav / Compass' : 'nav', + 'Power Tray' : 'powers', + 'Target' : 'target', + 'Tray' : 'tray', + } + + windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) + windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) + self.windowToggleTray.SetSelection(0) + windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.windowShowRB = wx.RadioButton(dialog, -1, "Show") + self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") + + windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) + + return windowToggleSizer + + def MakeBindString(self): + choice = self.windowToggleTray + index = choice.GetSelection() + windowdesc = choice.GetString(index) + windowname = self.WindowNames[windowdesc] + + if self.windowShowRB.GetValue(): + return 'show ' + windowname + elif self.windowHideRB.GetValue(): + return 'windowhide ' + windowname + else: + if shortcmd := self.ShortToggleCommands.get(windowdesc, None): + return shortcmd + else: + return 'toggle ' + windowname + + + def Serialize(self): + choice = self.windowToggleTray + if self.windowShowRB.GetValue(): + action = "Show" + elif self.windowHideRB.GetValue(): + action = "Hide" + else: + action = "Toggle" + return { + 'window': choice.GetString(choice.GetSelection()), + 'action': action, + } + + def Deserialize(self, init): + choice = self.windowToggleTray + if window := init.get('window', ''): + if isinstance(window, int): + choice.SetSelection(window) + else: + choice.SetSelection(choice.FindString(window)) + + if choice.GetSelection() == wx.NOT_FOUND: + choice.SetSelection(0) + + action = init.get('action', '') + if action == "Show": + self.windowShowRB.SetValue(True) + elif action == "Hide": + self.windowHideRB.SetValue(True) + else: + self.windowToggleRB.SetValue(True) + + +# Must always add to this list when adding a new command class above +menuStructure = { + 'Graphics / UI' : [ + 'Attribute Monitor', + 'Buff Display Settings', + 'Graphics Settings', + 'Window Color', + 'Window Save / Load', + 'Window Toggle', + ], + 'Inspirations' : [ + 'Use Inspiration By Name', + 'Use Inspiration From Row/Column', + ], + 'Powers' : [ + 'Auto Power', + 'Power Abort', + 'Power Unqueue', + 'Use Power', + 'Use Power From Tray', + ], + 'Social' : [ + 'Away From Keyboard', + 'Chat Command', + 'Chat Command (Global)', + 'Costume Change', + 'Emote', + 'Supergroup Mode', + ], + 'Targeting' : [ + 'Target Custom', + 'Target Enemy', + 'Target Frield', + 'Team/Pet Select', + 'Unselect', + ], + 'Misc' : [ + 'Load Binds Directory', + 'Movement Commands', + ], + # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, + # but I'm leaving it here to remind myself that we do that. + } + +# Must always add to this list when adding a new command class above +commandClasses = { + 'Auto Power' : AutoPowerCmd, + 'Away From Keyboard' : AFKCmd, + 'Attribute Monitor' : AttributeMonitorCmd, + 'Buff Display Settings' : BuffDisplayCmd, + 'Chat Command' : ChatCmd, + 'Chat Command (Global)' : ChatGlobalCmd, + 'Costume Change' : CostumeChangeCmd, + 'Custom Bind' : CustomBindCmd, + 'Emote' : EmoteCmd, + 'Graphics Settings' : GraphicsCmd, + 'Load Binds Directory' : LoadBindsDir, + 'Movement Commands' : MovementCmd, + 'Power Abort' : PowerAbortCmd, + 'Power Unqueue' : PowerUnqueueCmd, + 'Supergroup Mode' : SGModeCmd, + 'Target Custom' : TargetCustomCmd, + 'Target Enemy' : TargetEnemyCmd, + 'Target Friend' : TargetFriendCmd, + 'Team/Pet Select' : TeamPetSelectCmd, + 'Unselect' : UnselectCmd, + 'Use Inspiration By Name' : UseInspByNameCmd, + 'Use Inspiration From Row/Column' : UseInspRowColCmd, + 'Use Power' : UsePowerCmd, + 'Use Power From Tray' : UsePowerFromTrayCmd, + 'Window Color' : WindowColorCmd, + 'Window Save / Load' : WindowSaveLoadCmd, + 'Window Toggle' : WindowToggleCmd, +} +# use these when we rename a commandClass so that old Profiles will still load correctly. +# If we've also updated the class, we need to try to make sure the new class will still +# Deserialize the legacy data, or at least not crash. +deprecatedCommandClasses = { + 'SG Mode Toggle' : SGModeCmd, + 'Use Insp By Name' : UseInspByNameCmd, + 'Use Insp From Row/Column' : UseInspRowColCmd, +} +commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/PowerAbortCmd.py b/UI/PowerBinderCommand/PowerAbortCmd.py new file mode 100644 index 0000000..4c02ab7 --- /dev/null +++ b/UI/PowerBinderCommand/PowerAbortCmd.py @@ -0,0 +1,1800 @@ +import wx +import re +import UI +import UI.EmotePicker +from UI.ControlGroup import ControlGroup +from UI.PowerPicker import PowerPicker +from Help import HelpButton +import wx.adv +from wx.adv import BitmapComboBox, EditableListBox +from pathlib import PureWindowsPath +import GameData +import Profile +from Icon import GetIcon + +class PowerBinderDialog(wx.Dialog): + def __init__(self, parent, button, init = {}): + wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) + + self.Page = parent.Page + self.EditDialog = PowerBinderEditDialog(self) + self.Button = button + self.AddStepMenu = self.makeAddStepMenu() + + sizer = wx.BoxSizer(wx.VERTICAL); + self.mainSizer = sizer + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) + # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) + # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) + #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) + AddStepButton = wx.Button(self, -1, 'Add Step') + AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) + AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) + choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) + choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) + sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) + + rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) + + self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) + self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) + self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) + rearrangeCtrl.Add(self.RearrangeList, 1) + + rearrangeButtons = wx.BoxSizer(wx.VERTICAL) + self.DelButton = wx.Button(self, -1, "Delete") + self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) + self.EditButton = wx.Button(self, -1, "Edit") + self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) + self.EditButton.Disable() + upButton = wx.Button(self, -1, "\u25B2") + upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) + downButton = wx.Button(self, -1, "\u25BC") + downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) + rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) + rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) + + sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.BindStringDisplay = wx.TextCtrl(self, -1) + self.BindStringDisplay.Disable() + choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, + wx.ALIGN_CENTER_VERTICAL) + choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) + + sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) + + sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) + + # need to dig around and get the OK button since we show this dialog modelessly now. + okButton = self.FindWindow(self.GetAffirmativeId()) + okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) + + # Wrap everything in a vbox to add some padding + vbox = wx.BoxSizer(wx.VERTICAL); + vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); + + self.SetSizerAndFit(vbox); + self.Layout() + self.Fit() + self.SetFocus() + + # if we are loading from profile, ie, have "init", build the list from it + if init: self.LoadFromData(init) + + def LoadFromData(self, init): + for item in init: + for type, data in item.items(): + commandClass = commandClasses.get(type, None) + if not commandClass: + commandClass = deprecatedCommandClasses.get(type, None) + if not commandClass: + wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") + continue + newCommand = commandClass(self.EditDialog, data) + index = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.SetClientData(index, newCommand) + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) + self.EditDialog.mainSizer.Hide(newCommand.UI) + self.UpdateBindStringDisplay() + + def SaveToData(self): + data = [] + index = 0 + for _ in self.RearrangeList.GetItems(): + # check whether we have an object already attached to this choice + cmdObject = self.RearrangeList.GetClientData(index) + commandClassName = commandRevClasses[type(cmdObject)] + data.append({commandClassName: cmdObject.Serialize()}) + index = index + 1 + return data + + def OnAddStepButton(self, evt): + button = evt.EventObject + if not self.AddStepMenu: + self.AddStepMenu = self.makeAddStepMenu() + button.PopupMenu(self.AddStepMenu) + + + def OnOKButton(self, _): + if self.Button.tgtTxtCtrl: + bindString = self.MakeBindString() + if bindString != self.Button.tgtTxtCtrl.GetValue(): + self.Button.tgtTxtCtrl.SetValue(bindString) + wx.App.Get().Main.Profile.SetModified() + self.Close() + + def OnRearrangeDelete(self, _): + current = self.RearrangeList.GetSelection() + if current == wx.NOT_FOUND: return + + self.RearrangeList.Delete(current) + self.UpdateBindStringDisplay() + + def OnRearrangeUp(self, _): + self.RearrangeList.MoveCurrentUp() + self.UpdateBindStringDisplay() + + def OnRearrangeDown(self, _): + self.RearrangeList.MoveCurrentDown() + self.UpdateBindStringDisplay() + + def OnRearrangeEdit(self, _): + index = self.RearrangeList.GetSelection() + + # check whether we have an object already attached to this choice + cmdObject = None + try: + cmdObject = self.RearrangeList.GetClientData(index) + except Exception: + pass + + if cmdObject: + self.ShowEditDialogFor(cmdObject) + self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) + else: + print("cmdObject was None") + self.UpdateBindStringDisplay() + + # OnAddStepMenu creates a new step and adds it to the rearrangelist + def OnAddStepMenu(self, evt): + menuitem = self.AddStepMenu.FindItemById(evt.GetId()) + chosenName = menuitem.GetItemLabel() + + # make a new command object, attached to the parent dialog + newCommandClass = commandClasses[chosenName] + newCommand = newCommandClass(self.EditDialog) + + # show the edit dialog if this command needs it + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) + if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): + self.EditDialog.mainSizer.Remove(newCommand.UI) + return + + newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.Select(newBindIndex) + self.RearrangeList.SetClientData(newBindIndex, newCommand) + + self.OnListSelect() + self.UpdateBindStringDisplay() + + def OnListSelect(self, _ = None): + selected = self.RearrangeList.GetSelection() + + if selected != wx.NOT_FOUND: + selCommand = self.RearrangeList.GetClientData(selected) + if selCommand.UI: + self.EditButton.Enable() + else: + self.EditButton.Disable() + + def UpdateBindStringDisplay(self): + self.BindStringDisplay.SetValue(self.MakeBindString()) + self.BindStringDisplay.SetToolTip(self.MakeBindString()) + + def MakeBindString(self): + cmdBindStrings = [] + for index in range(self.RearrangeList.GetCount()): + c = self.RearrangeList.GetClientData(index) + if c: cmdBindStrings.append(c.MakeBindString()) + + bindstring = ('$$'.join(cmdBindStrings)) + return bindstring + + def ShowEditDialogFor(self, command): + if not command.UI: return + + self.EditDialog.mainSizer.Show(command.UI) + + self.EditDialog.Layout() + self.EditDialog.Fit() + + self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') + returnval = self.EditDialog.ShowModal() + + self.EditDialog.mainSizer.Hide(command.UI) + + return returnval + + def makeAddStepMenu(self): + + stepMenu = wx.Menu() + + for subname in menuStructure: + submenu = wx.Menu() + stepMenu.AppendSubMenu(submenu, subname) + for classname in menuStructure[subname]: + submenu.Append(wx.ID_ANY, classname) + + stepMenu.Append(wx.ID_ANY, 'Custom Bind') + + return stepMenu + +class PowerBinderButton(wx.BitmapButton): + + def __init__(self, parent, tgtTxtCtrl, init = {}): + wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) + self.Init = init + self.Dialog = None + self.DialogParent = parent + + self.tgtTxtCtrl = tgtTxtCtrl + self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) + self.SetToolTip("Launch PowerBinder") + + def PowerBinderEventHandler(self, _): + self.PowerBinderDialog().Show() + + def LoadFromData(self, data): + self.PowerBinderDialog().LoadFromData(data) + + def SaveToData(self): + return self.PowerBinderDialog().SaveToData() + + def PowerBinderDialog(self): + if not self.Dialog: + self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) + return self.Dialog + + +class PowerBinderEditDialog(wx.Dialog): + def __init__(self, parent): + wx.Dialog.__init__(self, parent, -1, "Edit Step", + style = wx.DEFAULT_DIALOG_STYLE) + + outerSizer = wx.BoxSizer(wx.VERTICAL) + + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + self.mainSizer.SetMinSize([500, 150]) + + self.Page = parent.Page + + self.mainSizer.Add( + self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), + 0, wx.EXPAND|wx.ALL, 10) + + outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) + + self.SetSizerAndFit(outerSizer) + self.Layout() + self.Fit() + +########### Power Binder Command Objects +class PowerBindCmd(): + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + commandClassName = commandRevClasses[type(self)] + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{commandClassName} - {short_bindstr}" + + +####### Away From Keyboard +class AFKCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) + +####### Attribute Monitor +class AttributeMonitorCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.Groups = {} + self.AttributeTable = { + 'Base' : { + 'Current Hit Points' : 'NT H', + 'Max Hit Points' : 'X H', + 'Current Endurance' : 'T E', + 'Max Endurance' : 'X EN', + 'Regeneration Rate' : 'N RAT', + 'Recovery Rate' : 'Y RA', + 'Endurance Consumption' : 'SU', + 'ToHit Bonus' : 'T B', + 'Accuracy Bonus' : 'CC', + 'Last Hit Chance' : 'T C', + 'Damage Bonus' : 'DA', + 'Healing Bonus' : 'NG B', + 'Recharge Time Bonus' : 'ME B', + 'Endurance Discount' : 'CE DIS', + 'Stealth Radius (PvP)' : 'PVP', + 'Stealth Radius (PvE)' : 'PVE', + 'Perception Radius' : 'RC', + 'Range Bonus' : 'GE B', + 'Threat Level' : 'AT L', + 'Experience to Next Level' : 'XT', + 'Experience Debt' : 'XP', + 'Influence / Infamy' : 'INF', + 'Inherent' : 'NH', + }, + 'Movement Speed' : { + 'Flying Speed' : 'FL', + 'Jumping Speed' : 'PI', + 'Max Jump Height' : 'X J', + 'Run Speed' : 'RU', + }, + 'Damage Resistance' : { + 'Smashing Resistance' : 'G R', + 'Lethal Resistance' : 'L R', + 'Fire Resistance' : 'RE R', + 'Cold Resistance' : 'COLD R', + 'Energy Resistance' : 'DamageType[4]', + 'Negative Energy Resistance' : 'GY R', + 'Psyonic Resistance' : 'NIC R', + 'Toxic Resistance' : 'XIC R', + }, + 'Defense' : { + 'Base Defense' : 'BAS', + 'Ranged Defense' : 'ED', + 'Melee Defense' : 'MEL', + 'AoE Defense' : '2', + 'Smashing Defense' : '3', + 'Lethal Defense' : '4', + 'Fire Defense' : '5', + 'Cold Defense' : '6', + 'Energy Defense' : '7', + 'Negative Energy Defense' : '8', + 'Psionic Defense' : '9', + 'Toxic Defense' : '1', + }, + 'Debuff Resistance' : { + 'Regeneration Resistance' : 'ON R', + 'Recovery Resistance' : 'RY R', + 'To Hit Resistance' : 'IT R', + 'Defense Resistance' : 'NSE RES', + }, + 'Status Effect Protection' : { + 'Hold Protection' : 'D P', + 'Immobilize Protection' : 'LIZE P', + 'Stun Protection' : 'N P', + 'Sleep Protection' : 'P P', + 'Knockback Protection' : 'K P', + 'Confuse Protection' : 'SE P', + 'Terrorize Protection' : 'ZE P', + 'Repel Protection' : 'EL P', + 'Teleport Protection' : 'T P', + }, + 'Status Effect Resistance' : { + 'Hold Resistance' : 'D R', + 'Immobilize Resistance' : 'LIZE R', + 'Stun Resistance' : 'N R', + 'Sleep Resistance' : 'P R', + 'Knockback Resistance' : 'K R', + 'Confuse Resistance' : 'SE R', + 'Terrorize Resistance' : 'ZE R', + 'Placate Resistance' : 'TE R', + 'Taunt Resistance' : 'NT R', + }, + 'Miscellaneous' : { + 'Level Shift' : 'L S', + }, + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.AttributeMenu = wx.Menu() + for group, controls in self.AttributeTable.items(): + submenu = wx.Menu() + self.AttributeMenu.AppendSubMenu(submenu, group) + for cb in controls: + submenu.Append(wx.ID_ANY, cb) + + self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) + + self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) + groupSizer.Add(self.editbox) + + newButton = self.editbox.GetNewButton() + newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) + + return groupSizer + + def MakeBindString(self): + map = {} + bindstrings = [] + for _, controls in self.AttributeTable.items(): + for cb, data in controls.items(): + map[cb] = data + + for string in self.editbox.GetStrings(): + if string: + bindstrings.append(f'monitorattribute {map[string]}') + + return '$$'.join(bindstrings) + + def Serialize(self): + return { + 'attributes' : self.editbox.GetStrings() + } + + def Deserialize(self, init): + self.editbox.SetStrings(init.get('attributes', [])) + + def OnNewButton(self, evt): + evt.GetEventObject().PopupMenu(self.AttributeMenu) + + def OnMenuItem(self, evt): + menuitem = evt.EventObject.FindItemById(evt.GetId()) + existingstrings = self.editbox.GetStrings() + existingstrings.append(menuitem.GetItemLabel()) + self.editbox.SetStrings(existingstrings) + +####### Auto Power +class AutoPowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) + autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.autoPowerName = PowerPicker(dialog) + autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) + + return autoPowerSizer + + def MakeBindString(self): + return f"powexecauto {self.autoPowerName.GetLabel()}" + + def Serialize(self): + return { + 'pname' : self.autoPowerName.GetLabel(), + 'picon' : self.autoPowerName.IconFilename + } + + def Deserialize(self, init): + if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) + +####### Buff Display Command +class BuffDisplayCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.buffDisplayMap = { + 'Status Window' : { + 'Hide Auto' : 1, + 'Hide Toggles' : 2, + 'No Blinking' : 4, + 'No Stacking' : 8, + 'Numeric Stacking' : 16, + 'Hide Buff Numbers' : 32, + 'Stop Sending Buffs' : 64, + }, + 'Group Window' : { + 'Hide Auto' : 256, + 'Hide Toggles' : 512, + 'No Blinking' : 1024, + 'No Stacking' : 2048, + 'Numeric Stacking' : 4096, + 'Hide Buff Numbers' : 8192, + 'Stop Sending Buffs' : 16384, + }, + 'Pet Window' : { + 'Hide Auto' : 65536, + 'Hide Toggles' : 131072, + 'No Blinking' : 262144, + 'No Stacking' : 524288, + 'Numeric Stacking' : 1048576, + 'Hide Buff Numbers' : 2097152, + 'Stop Sending Buffs' : 4194304, + }, + } + self.Groups = {} + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + for group, controls in self.buffDisplayMap.items(): + self.Groups[group] = ControlGroup(dialog, self.Page, label = group) + groupid = self.Groups[group].GetStaticBox().GetId() + for cb, data in controls.items(): + self.Groups[group].AddControl( + ctlType = 'checkbox', + ctlName = f"{groupid}_{group}_{cb}", + label = cb, + data = data, + ) + + groupSizer.Add(self.Groups[group]) + + return groupSizer + + def CalculateValue(self): + page = wx.App.Get().Main.Profile.CustomBinds + + total = 0 + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] + if checkbox.IsChecked(): + total = total + checkbox.Data + return total + + def MakeBindString(self): + return f"optionset buffsettings {self.CalculateValue()}" + + def Serialize(self): + return { 'value' : self.CalculateValue() } + + def Deserialize(self, init): + value = init.get('value', 0) + + value = value or 0 # in case we had for some reason 'None' stashed in the init values + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] + checkbox.SetValue( checkbox.Data & value ) + +####### Chat Command +class ChatCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.chatChannelMap = { # before __init__ + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + chatCommandSizer = wx.GridBagSizer(5, 5) + self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") + chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) + # row 1 + self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) + self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) + self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) + # row 2 + self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) + self.chatCommandDuration.SetRange(1, 20) + self.chatCommandDuration.SetValue(7) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandDuration, (2,1)) + self.chatCommandChatSize = wx.Choice(dialog, -1, + choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) + self.chatCommandChatSize.SetSelection(5) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) + self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) + self.chatCommandChannel.SetSelection(0) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChannel, (2,5)) + # row 3 + self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") + chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) + self.chatCommandMessage = wx.TextCtrl(dialog, -1) + self.chatCommandMessage.SetHint('Chat Command Text') + chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) + + return chatCommandSizer + + def MakeBindString(self): + duration = self.chatCommandDuration.GetValue() + + choice = self.chatCommandChatSize + index = choice.GetSelection() + size = choice.GetString(index) + + duration = f"" if duration != 7 else "" + size = f"" if size != "1" else "" + + bdcolor = fgcolor = bgcolor = '' + if self.chatCommandUseColorsCB.IsChecked(): + bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + + bdcolor = f"" + fgcolor = f"" + bgcolor = f"" + + beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' + text = self.chatCommandMessage.GetValue() + + choice = self.chatCommandChannel + index = choice.GetSelection() + channel = choice.GetString(index) + + return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" + + def Serialize(self): + return { + 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), + 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), + 'channel' : self.chatCommandChannel .GetSelection(), + 'size' : self.chatCommandChatSize.GetSelection(), + 'duration' : self.chatCommandDuration.GetValue(), + 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'text' : self.chatCommandMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) + if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) + if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) + if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) + if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) + if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) + if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) + if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) + if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) + + +####### Chat Command Global +class ChatGlobalCmd(PowerBindCmd): + def BuildUI(self, dialog): + chatCommandGlobalSizer = wx.GridBagSizer(5,5) + + self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") + chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) + + self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalChannel.SetHint("Channel") + chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) + + self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') + chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) + + chatCommandGlobalSizer.AddGrowableCol(1) + + return chatCommandGlobalSizer + + def MakeBindString(self): + useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() + channel = self.chatCommandGlobalChannel.GetValue() + message = self.chatCommandGlobalMessage.GetValue() + + preface = "beginchat /" if useBeginchat else "" + + return f'{preface}send "{channel}" {message}' + + def Serialize(self): + return { + 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), + 'channel' : self.chatCommandGlobalChannel.GetValue(), + 'message' : self.chatCommandGlobalMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) + if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) + if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) + +#######Costume Change +class CostumeChangeCmd(PowerBindCmd): + def BuildUI(self, dialog): + costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeCostume = wx.Choice(dialog, -1, + choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) + self.costumeChangeCostume.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeEmote = wx.Choice(dialog, -1, + choices = GameData.Emotes['costumechange']) + self.costumeChangeEmote.Insert("- None -", 0) + self.costumeChangeEmote.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return costumeChangeSizer + + def MakeBindString(self): + costumeNumber = self.costumeChangeCostume.GetSelection() + costumeEmote = self.costumeChangeEmote.GetSelection() + + if costumeEmote: # None, or 0 == "- None -" + ccCmd = 'cce' + emoteName = self.costumeChangeEmote.GetString(costumeEmote) + emoteName = " CC" + emoteName.replace(" ","") + else: + ccCmd = 'cc' + emoteName = '' + + return f"{ccCmd} {costumeNumber}{emoteName}" + + def Serialize(self): + return{ + 'costumeNumber': self.costumeChangeCostume.GetSelection(), + 'costumeEmote' : self.costumeChangeEmote.GetSelection(), + } + + def Deserialize(self, init): + if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) + if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) + +####### Movement Command +class MovementCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + self.plusbutton.SetValue(True) + + self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.commandchoice = wx.Choice(dialog, choices = [ + "forward", "left", "right", "backward", "up", "down", + "turnleft", "turnright", "first", "autorun", "clicktomove", + ],) + sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) + self.commandchoice.SetSelection(0) + + self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + pre = post = '' + if self.plusbutton.GetValue() : pre = "+" + elif self.plusplusbutton.GetValue() : pre = "++" + elif self.minusbutton.GetValue() : pre = "-" + elif self.zerobutton.GetValue() : post = " 0" + elif self.onebutton.GetValue() : post = " 1" + + command = self.commandchoice.GetString(self.commandchoice.GetSelection()) + + return f"{pre}{command}{post}" + + def Serialize(self): + mod = '' + if self.plusbutton.GetValue() : mod = "plus" + elif self.plusplusbutton.GetValue() : mod = "plusplus" + elif self.minusbutton.GetValue() : mod = "minus" + elif self.zerobutton.GetValue() : mod = "zero" + elif self.onebutton.GetValue() : mod = "one" + + return { + 'mod' : mod, + 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), + } + + def Deserialize(self, init): + mod = init.get('mod', 'plus') + + if mod == 'plus' : self.plusbutton.SetValue(True) + elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) + elif mod == 'minus' : self.minusbutton.SetValue(True) + elif mod == 'zero' : self.zerobutton.SetValue(True) + elif mod == 'one' : self.onebutton.SetValue(True) + + self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) + +####### Graphics Command +class GraphicsCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.FlexGridSizer(2) + + self.visscalecb = wx.CheckBox(dialog, label = "visscale") + sizer.Add(self.visscalecb) + self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) + sizer.Add(self.visscalesc) + + self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") + sizer.Add(self.dofweightcb) + self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) + sizer.Add(self.dofweightsc) + + self.fsaacb = wx.CheckBox(dialog, label = "fsaa") + sizer.Add(self.fsaacb) + self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) + self.fsaach.SetSelection(0) + sizer.Add(self.fsaach) + + self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") + sizer.Add(self.bloomscalecb) + self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) + self.bloomscalech.SetSelection(0) + sizer.Add(self.bloomscalech) + + self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") + sizer.Add(self.bloomweightcb) + self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) + sizer.Add(self.bloomweightsc) + + self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") + sizer.Add(self.lodbiascb) + self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) + sizer.Add(self.lodbiassc) + + self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") + sizer.Add(self.renderscalecb) + self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) + sizer.Add(self.renderscalesc) + + return sizer + + def MakeBindString(self): + # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. + bindstrings = [] + if self.visscalecb.IsChecked(): + bindstrings.append("visscale " + str(self.visscalesc.GetValue())) + if self.dofweightcb.IsChecked(): + bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) + if self.fsaacb.IsChecked(): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bindstrings.append("fsaa " + fsaavalue) + if self.bloomscalecb.IsChecked(): + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + bindstrings.append("bloomscale " + bloomscalevalue) + if self.bloomweightcb.IsChecked(): + bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) + if self.lodbiascb.IsChecked(): + bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) + if self.renderscalecb.IsChecked(): + bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) + + return '$$'.join(bindstrings) + + def Serialize(self): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + return { + 'visscalecb' : self.visscalecb.IsChecked(), + 'visscalesc' : self.visscalesc.GetValue(), + 'dofweightcb' : self.dofweightcb.IsChecked(), + 'dofweightsc' : self.dofweightsc.GetValue(), + 'fsaacb' : self.fsaacb.IsChecked(), + 'fsaach' : fsaavalue, + 'bloomscalecb' : self.bloomscalecb.IsChecked(), + 'bloomscalech' : bloomscalevalue, + 'bloomweightcb' : self.bloomweightcb.IsChecked(), + 'bloomweightsc' : self.bloomweightsc.GetValue(), + 'lodbiascb' : self.lodbiascb.IsChecked(), + 'lodbiassc' : self.lodbiassc.GetValue(), + 'renderscalecb' : self.renderscalecb.IsChecked(), + 'renderscalesc' : self.renderscalesc.GetValue(), + } + + def Deserialize(self, init): + self.visscalecb.SetValue(init.get('visscalecb', False)) + self.visscalesc.SetValue(init.get('visscalesc', 1.0)) + self.dofweightcb.SetValue(init.get('dofweightcb', False)) + self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) + self.fsaacb.SetValue(init.get('fsaacb', False)) + self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) + self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) + self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) + self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) + self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) + self.lodbiascb.SetValue(init.get('lodbiascb', False)) + self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) + self.renderscalecb.SetValue(init.get('renderscalecb', False)) + self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) + +####### Custom Bind +class CustomBindCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.customBindName = wx.TextCtrl(dialog, -1) + self.customBindName.SetHint('Custom Bind Text') + sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + return self.customBindName.GetValue() + + def Serialize(self): + return { 'customBindName': self.customBindName.GetValue() } + + def Deserialize(self,init): + if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) + +####### Emote +class EmoteCmd(PowerBindCmd): + def BuildUI(self, dialog): + emoteSizer = wx.BoxSizer(wx.HORIZONTAL) + self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") + emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + self.emoteName = wx.Button(dialog, -1, "...") + self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) + emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) + + return emoteSizer + + def MakeBindString(self): + displayedEmoteName = self.emoteName.GetLabel() + actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] + + return actualEmotePayload + + def Serialize(self): + return {'emoteName': self.emoteName.GetLabel()} + + def Deserialize(self, init): + if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) + +####### Load Binds Directory +class LoadBindsDir(PowerBindCmd): + def BuildUI(self, dialog): + mainSizer = wx.BoxSizer(wx.VERTICAL) + + lbSizer = wx.BoxSizer(wx.HORIZONTAL) + lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") + lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + profiles = Profile.GetAllProfileBindsDirs() + + self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) + lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") + self.lbResetCB.SetValue(True) + + mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + return mainSizer + + def MakeBindString(self): + + # If the specified binds directory disappeared between runs, we'd crash, so handle that. + if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' + + config = wx.ConfigBase.Get() + if config.Exists('GameBindPath'): + bindpath = config.Read('GameBindPath') + else: + bindpath = config.Read('BindPath') + + reset = "" + if self.lbResetCB.GetValue(): + reset = "keybind_reset$$" + + resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' + return reset + 'bindloadfile ' + str(resetfilepath) + + def Serialize(self): + return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), + 'ResetKeybinds' : self.lbResetCB.GetValue(), + } + + def Deserialize(self, init): + if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) + self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) + +####### Power Abort +class PowerAbortCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecabort' + +####### Power Unqueue +class PowerUnqueueCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecunqueue' + +####### SG Mode +class SGModeCmd(PowerBindCmd): + def BuildUI(self, dialog): + sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) + sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") + self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") + + sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) + + return sgmodeSizer + + def MakeBindString(self): + if self.sgmodeOnRB.GetValue(): + return 'sgmodeset 1' + elif self.sgmodeOffRB.GetValue(): + return 'sgmodeset 0' + else: + return 'sgmode' + + def Serialize(self): + if self.sgmodeOnRB.GetValue(): + val = "On" + elif self.sgmodeOffRB.GetValue(): + val = "Off" + else: + val = "Toggle" + + return {"value" : val} + + def Deserialize(self, init): + val = init.get('value', '') + if val == "On": + self.sgmodeOnRB.SetValue(True) + elif val == "Off": + self.sgmodeOffRB.SetValue(True) + else: + self.sgmodeToggleRB.SetValue(True) + +####### Target Custom +class TargetCustomCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetCustomSizer = wx.GridBagSizer(5,5) + targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), + flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) + self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetCustomModeChoice.SetSelection(0) + targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) + self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) + self.targetCustomOptionalName.SetHint("Optional name to match") + targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) + self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") + targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) + self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") + targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) + self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") + targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) + self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") + targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) + self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") + targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) + self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") + targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) + self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") + targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) + self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") + targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) + + targetCustomSizer.AddGrowableCol(2) + + return targetCustomSizer + + def MakeBindString(self): + choice = self.targetCustomModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + targetCommand = "targetcustom" + mode.lower() + + enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" + friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" + defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" + alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" + mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" + notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" + base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" + notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" + + name = self.targetCustomOptionalName.GetValue() + + return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" + + def Serialize(self): + return { + 'mode' : self.targetCustomModeChoice.GetSelection(), + 'enemy' : self.targetCustomCBEnemies. IsChecked(), + 'friend' : self.targetCustomCBFriends. IsChecked(), + 'defeated' : self.targetCustomCBDefeated. IsChecked(), + 'alive' : self.targetCustomCBAlive. IsChecked(), + 'mypet' : self.targetCustomCBMyPets. IsChecked(), + 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), + 'base' : self.targetCustomCBBaseItems. IsChecked(), + 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), + 'name' : self.targetCustomOptionalName.GetValue(), + } + + def Deserialize(self, init): + if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) + if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) + if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) + if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) + if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) + if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) + if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) + if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) + if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) + if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) + + +####### Target Enemy +class TargetEnemyCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) + targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetEnemyModeChoice.SetSelection(0) + targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetEnemySizer + + def MakeBindString(self): + choice = self.targetEnemyModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetenemy" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetEnemyModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) + +####### Target Friend +class TargetFriendCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) + targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetFriendModeChoice.SetSelection(0) + targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetFriendSizer + + def MakeBindString(self): + choice = self.targetFriendModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetfriend" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetFriendModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) + +####### Team/Pet Select +class TeamPetSelectCmd(PowerBindCmd): + def BuildUI(self, dialog): + teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], + style=wx.ALIGN_CENTER_VERTICAL) + self.teamPetSelectNumber.SetSelection(0) + teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) + + return teamPetSelectSizer + + def MakeBindString(self): + teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' + targetNumber = self.teamPetSelectNumber.GetSelection()+1 + + return f"{teamOrPet}select {targetNumber}" + + def Serialize(self): + return { + 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', + 'targetNum': self.teamPetSelectNumber.GetSelection(), + } + + def Deserialize(self, init): + ToP = init.get('teamOrPet', '') + if ToP == 'pet': + self.teamPetSelectPetRB.SetValue(True) + else: + self.teamPetSelectTeamRB.SetValue(True) + if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) + +####### Unselect +class UnselectCmd(PowerBindCmd): + def MakeBindString(self): + return 'unselect' + +####### Use Insp By Name +class UseInspByNameCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) + for _, types in GameData.Inspirations.items(): + for _, info in types.items(): + for insp in info['tiers']: + name = re.sub(' ', '', str(insp)) + icon = GetIcon(f'Inspirations/{name}') + self.useInspByNameModeChoice.Append(insp, icon) + self.useInspByNameModeChoice.SetSelection(0) + useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) + + return useInspByNameSizer + + def MakeBindString(self): + choice = self.useInspByNameModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "inspexecname " + mode.lower() + + def GetAllInsps(self): + Insplist = [] + for _, info in GameData.Inspirations.items(): + for insp in info['tiers']: + Insplist.append(insp) + Insplist.append("---") + Insplist.pop(-1) # snip the terminal "---" + + return Insplist + + def Serialize(self): + return { 'insp' : self.useInspByNameModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) + +####### Use Insp From Row / Column +class UseInspRowColCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnRow.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) + self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnCol.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) + + return useInspRowColumnSizer + + def MakeBindString(self): + row = self.useInspRowColumnRow.GetSelection()+1 + col = self.useInspRowColumnCol.GetSelection()+1 + + return f"inspexectray {col} {row}" + + def Serialize(self): + return { + 'col' : self.useInspRowColumnCol.GetSelection(), + 'row' : self.useInspRowColumnRow.GetSelection(), + } + + def Deserialize(self, init): + if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) + if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) + +####### Use Power +class UsePowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + outerSizer = wx.BoxSizer(wx.HORIZONTAL) + + usePowerSizer = wx.GridBagSizer(5,5) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBToggle, (0,1)) + self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOn, (0,2)) + self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOff, (0,3)) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerName = PowerPicker(dialog) + usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) + usePowerSizer.AddGrowableCol(3) + + outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) + + return outerSizer + + def MakeBindString(self): + if self.usePowerRBToggle.GetValue(): + method = "powexecname" + elif self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') + return '' + + return f"{method} {self.usePowerName.GetLabel()}" + + def Serialize(self): + if self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + method = "powexecname" + return { + 'method': method, + 'pname' : self.usePowerName.GetLabel(), + 'picon' : self.usePowerName.IconFilename + } + + def Deserialize(self, init): + method = init.get('method', '') + if method == 'powexectoggleon': + self.usePowerRBOn.SetValue(True) + elif method == 'powexectoggleoff': + self.usePowerRBOff.SetValue(True) + else: + self.usePowerRBToggle.SetValue(True) + if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) + +####### Use Power From Tray +class UsePowerFromTrayCmd(PowerBindCmd): + def BuildUI(self, dialog): + usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTrayTray = wx.Choice(dialog, -1, + choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', + 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) + self.usePowerFromTrayTray.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) + self.usePowerFromTraySlot.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return usePowerFromTraySizer + + def MakeBindString(self): + choice = self.usePowerFromTrayTray + tray = choice.GetSelection() + + choice = self.usePowerFromTraySlot + slot = choice.GetSelection()+1 + + mode = "slot" + mode2 = '' + if tray > 3: + mode = "tray" + mode2 = f" {tray - 3}" + elif tray == 3: + mode = "alt2slot" + elif tray == 2: + mode = "altslot" + + return f"powexec{mode} {slot}{mode2}" + + def Serialize(self): + return { + 'tray' : self.usePowerFromTrayTray.GetSelection(), + 'slot' : self.usePowerFromTraySlot.GetSelection(), + } + + def Deserialize(self, init): + if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) + if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) + +####### Window Color +class WindowColorCmd(PowerBindCmd): + def BuildUI(self, dialog): + windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) + borderSizer = wx.BoxSizer(wx.VERTICAL) + self.ColorBorder.SetSizer(borderSizer) + self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) + borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) + + windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) + + RGBASizer = wx.FlexGridSizer(3, 4, 5) + + RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) + self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) + self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + windowColorSizer.Add(RGBASizer) + + self.UpdateFromSlider() + + return windowColorSizer + + def MakeBindString(self): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + return f"windowcolor {Rval} {Gval} {Bval} {Aval}" + + def Serialize(self): + return { + 'Rval' : self.RSlider.GetValue(), + 'Gval' : self.GSlider.GetValue(), + 'Bval' : self.BSlider.GetValue(), + 'Aval' : self.ASlider.GetValue(), + } + + def Deserialize(self, init): + self.RSlider.SetValue(init['Rval']) + self.GSlider.SetValue(init['Gval']) + self.BSlider.SetValue(init['Bval']) + self.ASlider.SetValue(init['Aval']) + self.UpdateFromSlider() + + def UpdateFromSlider(self, _ = None): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RReadout.SetValue(Rval) + self.GReadout.SetValue(Gval) + self.BReadout.SetValue(Bval) + self.AReadout.SetValue(Aval) + self.ColorBorder.Refresh() + + def UpdateFromText(self, _ = None): + Rval = self.RReadout.GetValue() + Gval = self.GReadout.GetValue() + Bval = self.BReadout.GetValue() + Aval = self.AReadout.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RSlider.SetValue(Rval) + self.GSlider.SetValue(Gval) + self.BSlider.SetValue(Bval) + self.ASlider.SetValue(Aval) + self.ColorBorder.Refresh() + +####### Window Save / Load +class WindowSaveLoadCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) + self.CommandChoice.SetSelection(0) + sizer.Add(self.CommandChoice, 0, wx.ALL, 5) + + self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), + value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) + sizer.Add(self.FilePath, 0, wx.ALL, 5) + + return sizer + + def MakeBindString(self): + command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] + return f'{command} "{self.FilePath.GetValue()}"' + + def Serialize(self): + return { + 'command' : self.CommandChoice.GetSelection(), + 'filename' : self.FilePath.GetValue(), + } + + def Deserialize(self, init): + self.CommandChoice.SetSelection(init.get('command', 0)) + self.FilePath.SetValue(init.get('filename', '')) + +####### Window Toggle +class WindowToggleCmd(PowerBindCmd): + def BuildUI(self, dialog): + self.WindowNames = { + 'Actions' : 'actions', + 'Auction House' : 'ah', + 'Badge' : 'badge', + 'Channel Search' : 'chansearch', + 'Chat' : 'chat', + 'Custom Chat 1' : 'chat1', + 'Custom Chat 2' : 'chat2', + 'Custom Chat 3' : 'chat3', + 'Custom Chat 4' : 'chat4', + 'Clues' : 'clue', + 'Combat Numbers' : 'combatnumbers', + 'Contacts' : 'contact', + 'Contact Finder' : 'contactfinder', + 'Costumes' : 'costume', + 'Email' : 'email', + 'Enhancements' : 'enhancements', + 'Friends' : 'friend', + 'Group' : 'group', + 'Help' : 'helpwindow', + 'Incarnate' : 'incarnate', + 'Inspirations' : 'insp', + 'League' : 'league', + 'LFG' : 'lfg', + 'Map' : 'map', + 'Mission' : 'mission', + 'Nav / Compass' : 'nav', + 'Options' : 'options', + 'Pets' : 'pet', + 'Petition' : 'petition', + 'Power Tray' : 'powers', + 'Power List' : 'powerlist', + 'Quit' : 'quit', + 'Recipes' : 'recipe', + 'Salvage' : 'salvage', + 'Search' : 'search', + 'Supergroup' : 'sg', + 'Target' : 'target', + 'Team' : 'team', + 'Tray' : 'tray', + 'Tray1' : 'tray1', + 'Tray2' : 'tray2', + 'Tray3' : 'tray3', + 'Tray4' : 'tray4', + 'Tray5' : 'tray5', + 'Tray6' : 'tray6', + 'Tray7' : 'tray7', + 'Tray8' : 'tray8', + 'Vault' : 'vault', + } + + self.ShortToggleCommands = { + 'Auction House' : 'ah', + 'Chat' : 'chat', + 'Help' : 'helpwindow', + 'Map' : 'map', + 'Nav / Compass' : 'nav', + 'Power Tray' : 'powers', + 'Target' : 'target', + 'Tray' : 'tray', + } + + windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) + windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) + self.windowToggleTray.SetSelection(0) + windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.windowShowRB = wx.RadioButton(dialog, -1, "Show") + self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") + + windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) + + return windowToggleSizer + + def MakeBindString(self): + choice = self.windowToggleTray + index = choice.GetSelection() + windowdesc = choice.GetString(index) + windowname = self.WindowNames[windowdesc] + + if self.windowShowRB.GetValue(): + return 'show ' + windowname + elif self.windowHideRB.GetValue(): + return 'windowhide ' + windowname + else: + if shortcmd := self.ShortToggleCommands.get(windowdesc, None): + return shortcmd + else: + return 'toggle ' + windowname + + + def Serialize(self): + choice = self.windowToggleTray + if self.windowShowRB.GetValue(): + action = "Show" + elif self.windowHideRB.GetValue(): + action = "Hide" + else: + action = "Toggle" + return { + 'window': choice.GetString(choice.GetSelection()), + 'action': action, + } + + def Deserialize(self, init): + choice = self.windowToggleTray + if window := init.get('window', ''): + if isinstance(window, int): + choice.SetSelection(window) + else: + choice.SetSelection(choice.FindString(window)) + + if choice.GetSelection() == wx.NOT_FOUND: + choice.SetSelection(0) + + action = init.get('action', '') + if action == "Show": + self.windowShowRB.SetValue(True) + elif action == "Hide": + self.windowHideRB.SetValue(True) + else: + self.windowToggleRB.SetValue(True) + + +# Must always add to this list when adding a new command class above +menuStructure = { + 'Graphics / UI' : [ + 'Attribute Monitor', + 'Buff Display Settings', + 'Graphics Settings', + 'Window Color', + 'Window Save / Load', + 'Window Toggle', + ], + 'Inspirations' : [ + 'Use Inspiration By Name', + 'Use Inspiration From Row/Column', + ], + 'Powers' : [ + 'Auto Power', + 'Power Abort', + 'Power Unqueue', + 'Use Power', + 'Use Power From Tray', + ], + 'Social' : [ + 'Away From Keyboard', + 'Chat Command', + 'Chat Command (Global)', + 'Costume Change', + 'Emote', + 'Supergroup Mode', + ], + 'Targeting' : [ + 'Target Custom', + 'Target Enemy', + 'Target Frield', + 'Team/Pet Select', + 'Unselect', + ], + 'Misc' : [ + 'Load Binds Directory', + 'Movement Commands', + ], + # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, + # but I'm leaving it here to remind myself that we do that. + } + +# Must always add to this list when adding a new command class above +commandClasses = { + 'Auto Power' : AutoPowerCmd, + 'Away From Keyboard' : AFKCmd, + 'Attribute Monitor' : AttributeMonitorCmd, + 'Buff Display Settings' : BuffDisplayCmd, + 'Chat Command' : ChatCmd, + 'Chat Command (Global)' : ChatGlobalCmd, + 'Costume Change' : CostumeChangeCmd, + 'Custom Bind' : CustomBindCmd, + 'Emote' : EmoteCmd, + 'Graphics Settings' : GraphicsCmd, + 'Load Binds Directory' : LoadBindsDir, + 'Movement Commands' : MovementCmd, + 'Power Abort' : PowerAbortCmd, + 'Power Unqueue' : PowerUnqueueCmd, + 'Supergroup Mode' : SGModeCmd, + 'Target Custom' : TargetCustomCmd, + 'Target Enemy' : TargetEnemyCmd, + 'Target Friend' : TargetFriendCmd, + 'Team/Pet Select' : TeamPetSelectCmd, + 'Unselect' : UnselectCmd, + 'Use Inspiration By Name' : UseInspByNameCmd, + 'Use Inspiration From Row/Column' : UseInspRowColCmd, + 'Use Power' : UsePowerCmd, + 'Use Power From Tray' : UsePowerFromTrayCmd, + 'Window Color' : WindowColorCmd, + 'Window Save / Load' : WindowSaveLoadCmd, + 'Window Toggle' : WindowToggleCmd, +} +# use these when we rename a commandClass so that old Profiles will still load correctly. +# If we've also updated the class, we need to try to make sure the new class will still +# Deserialize the legacy data, or at least not crash. +deprecatedCommandClasses = { + 'SG Mode Toggle' : SGModeCmd, + 'Use Insp By Name' : UseInspByNameCmd, + 'Use Insp From Row/Column' : UseInspRowColCmd, +} +commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/PowerUnqueueCmd.py b/UI/PowerBinderCommand/PowerUnqueueCmd.py new file mode 100644 index 0000000..4c02ab7 --- /dev/null +++ b/UI/PowerBinderCommand/PowerUnqueueCmd.py @@ -0,0 +1,1800 @@ +import wx +import re +import UI +import UI.EmotePicker +from UI.ControlGroup import ControlGroup +from UI.PowerPicker import PowerPicker +from Help import HelpButton +import wx.adv +from wx.adv import BitmapComboBox, EditableListBox +from pathlib import PureWindowsPath +import GameData +import Profile +from Icon import GetIcon + +class PowerBinderDialog(wx.Dialog): + def __init__(self, parent, button, init = {}): + wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) + + self.Page = parent.Page + self.EditDialog = PowerBinderEditDialog(self) + self.Button = button + self.AddStepMenu = self.makeAddStepMenu() + + sizer = wx.BoxSizer(wx.VERTICAL); + self.mainSizer = sizer + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) + # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) + # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) + #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) + AddStepButton = wx.Button(self, -1, 'Add Step') + AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) + AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) + choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) + choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) + sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) + + rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) + + self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) + self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) + self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) + rearrangeCtrl.Add(self.RearrangeList, 1) + + rearrangeButtons = wx.BoxSizer(wx.VERTICAL) + self.DelButton = wx.Button(self, -1, "Delete") + self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) + self.EditButton = wx.Button(self, -1, "Edit") + self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) + self.EditButton.Disable() + upButton = wx.Button(self, -1, "\u25B2") + upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) + downButton = wx.Button(self, -1, "\u25BC") + downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) + rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) + rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) + + sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.BindStringDisplay = wx.TextCtrl(self, -1) + self.BindStringDisplay.Disable() + choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, + wx.ALIGN_CENTER_VERTICAL) + choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) + + sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) + + sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) + + # need to dig around and get the OK button since we show this dialog modelessly now. + okButton = self.FindWindow(self.GetAffirmativeId()) + okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) + + # Wrap everything in a vbox to add some padding + vbox = wx.BoxSizer(wx.VERTICAL); + vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); + + self.SetSizerAndFit(vbox); + self.Layout() + self.Fit() + self.SetFocus() + + # if we are loading from profile, ie, have "init", build the list from it + if init: self.LoadFromData(init) + + def LoadFromData(self, init): + for item in init: + for type, data in item.items(): + commandClass = commandClasses.get(type, None) + if not commandClass: + commandClass = deprecatedCommandClasses.get(type, None) + if not commandClass: + wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") + continue + newCommand = commandClass(self.EditDialog, data) + index = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.SetClientData(index, newCommand) + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) + self.EditDialog.mainSizer.Hide(newCommand.UI) + self.UpdateBindStringDisplay() + + def SaveToData(self): + data = [] + index = 0 + for _ in self.RearrangeList.GetItems(): + # check whether we have an object already attached to this choice + cmdObject = self.RearrangeList.GetClientData(index) + commandClassName = commandRevClasses[type(cmdObject)] + data.append({commandClassName: cmdObject.Serialize()}) + index = index + 1 + return data + + def OnAddStepButton(self, evt): + button = evt.EventObject + if not self.AddStepMenu: + self.AddStepMenu = self.makeAddStepMenu() + button.PopupMenu(self.AddStepMenu) + + + def OnOKButton(self, _): + if self.Button.tgtTxtCtrl: + bindString = self.MakeBindString() + if bindString != self.Button.tgtTxtCtrl.GetValue(): + self.Button.tgtTxtCtrl.SetValue(bindString) + wx.App.Get().Main.Profile.SetModified() + self.Close() + + def OnRearrangeDelete(self, _): + current = self.RearrangeList.GetSelection() + if current == wx.NOT_FOUND: return + + self.RearrangeList.Delete(current) + self.UpdateBindStringDisplay() + + def OnRearrangeUp(self, _): + self.RearrangeList.MoveCurrentUp() + self.UpdateBindStringDisplay() + + def OnRearrangeDown(self, _): + self.RearrangeList.MoveCurrentDown() + self.UpdateBindStringDisplay() + + def OnRearrangeEdit(self, _): + index = self.RearrangeList.GetSelection() + + # check whether we have an object already attached to this choice + cmdObject = None + try: + cmdObject = self.RearrangeList.GetClientData(index) + except Exception: + pass + + if cmdObject: + self.ShowEditDialogFor(cmdObject) + self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) + else: + print("cmdObject was None") + self.UpdateBindStringDisplay() + + # OnAddStepMenu creates a new step and adds it to the rearrangelist + def OnAddStepMenu(self, evt): + menuitem = self.AddStepMenu.FindItemById(evt.GetId()) + chosenName = menuitem.GetItemLabel() + + # make a new command object, attached to the parent dialog + newCommandClass = commandClasses[chosenName] + newCommand = newCommandClass(self.EditDialog) + + # show the edit dialog if this command needs it + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) + if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): + self.EditDialog.mainSizer.Remove(newCommand.UI) + return + + newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.Select(newBindIndex) + self.RearrangeList.SetClientData(newBindIndex, newCommand) + + self.OnListSelect() + self.UpdateBindStringDisplay() + + def OnListSelect(self, _ = None): + selected = self.RearrangeList.GetSelection() + + if selected != wx.NOT_FOUND: + selCommand = self.RearrangeList.GetClientData(selected) + if selCommand.UI: + self.EditButton.Enable() + else: + self.EditButton.Disable() + + def UpdateBindStringDisplay(self): + self.BindStringDisplay.SetValue(self.MakeBindString()) + self.BindStringDisplay.SetToolTip(self.MakeBindString()) + + def MakeBindString(self): + cmdBindStrings = [] + for index in range(self.RearrangeList.GetCount()): + c = self.RearrangeList.GetClientData(index) + if c: cmdBindStrings.append(c.MakeBindString()) + + bindstring = ('$$'.join(cmdBindStrings)) + return bindstring + + def ShowEditDialogFor(self, command): + if not command.UI: return + + self.EditDialog.mainSizer.Show(command.UI) + + self.EditDialog.Layout() + self.EditDialog.Fit() + + self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') + returnval = self.EditDialog.ShowModal() + + self.EditDialog.mainSizer.Hide(command.UI) + + return returnval + + def makeAddStepMenu(self): + + stepMenu = wx.Menu() + + for subname in menuStructure: + submenu = wx.Menu() + stepMenu.AppendSubMenu(submenu, subname) + for classname in menuStructure[subname]: + submenu.Append(wx.ID_ANY, classname) + + stepMenu.Append(wx.ID_ANY, 'Custom Bind') + + return stepMenu + +class PowerBinderButton(wx.BitmapButton): + + def __init__(self, parent, tgtTxtCtrl, init = {}): + wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) + self.Init = init + self.Dialog = None + self.DialogParent = parent + + self.tgtTxtCtrl = tgtTxtCtrl + self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) + self.SetToolTip("Launch PowerBinder") + + def PowerBinderEventHandler(self, _): + self.PowerBinderDialog().Show() + + def LoadFromData(self, data): + self.PowerBinderDialog().LoadFromData(data) + + def SaveToData(self): + return self.PowerBinderDialog().SaveToData() + + def PowerBinderDialog(self): + if not self.Dialog: + self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) + return self.Dialog + + +class PowerBinderEditDialog(wx.Dialog): + def __init__(self, parent): + wx.Dialog.__init__(self, parent, -1, "Edit Step", + style = wx.DEFAULT_DIALOG_STYLE) + + outerSizer = wx.BoxSizer(wx.VERTICAL) + + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + self.mainSizer.SetMinSize([500, 150]) + + self.Page = parent.Page + + self.mainSizer.Add( + self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), + 0, wx.EXPAND|wx.ALL, 10) + + outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) + + self.SetSizerAndFit(outerSizer) + self.Layout() + self.Fit() + +########### Power Binder Command Objects +class PowerBindCmd(): + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + commandClassName = commandRevClasses[type(self)] + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{commandClassName} - {short_bindstr}" + + +####### Away From Keyboard +class AFKCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) + +####### Attribute Monitor +class AttributeMonitorCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.Groups = {} + self.AttributeTable = { + 'Base' : { + 'Current Hit Points' : 'NT H', + 'Max Hit Points' : 'X H', + 'Current Endurance' : 'T E', + 'Max Endurance' : 'X EN', + 'Regeneration Rate' : 'N RAT', + 'Recovery Rate' : 'Y RA', + 'Endurance Consumption' : 'SU', + 'ToHit Bonus' : 'T B', + 'Accuracy Bonus' : 'CC', + 'Last Hit Chance' : 'T C', + 'Damage Bonus' : 'DA', + 'Healing Bonus' : 'NG B', + 'Recharge Time Bonus' : 'ME B', + 'Endurance Discount' : 'CE DIS', + 'Stealth Radius (PvP)' : 'PVP', + 'Stealth Radius (PvE)' : 'PVE', + 'Perception Radius' : 'RC', + 'Range Bonus' : 'GE B', + 'Threat Level' : 'AT L', + 'Experience to Next Level' : 'XT', + 'Experience Debt' : 'XP', + 'Influence / Infamy' : 'INF', + 'Inherent' : 'NH', + }, + 'Movement Speed' : { + 'Flying Speed' : 'FL', + 'Jumping Speed' : 'PI', + 'Max Jump Height' : 'X J', + 'Run Speed' : 'RU', + }, + 'Damage Resistance' : { + 'Smashing Resistance' : 'G R', + 'Lethal Resistance' : 'L R', + 'Fire Resistance' : 'RE R', + 'Cold Resistance' : 'COLD R', + 'Energy Resistance' : 'DamageType[4]', + 'Negative Energy Resistance' : 'GY R', + 'Psyonic Resistance' : 'NIC R', + 'Toxic Resistance' : 'XIC R', + }, + 'Defense' : { + 'Base Defense' : 'BAS', + 'Ranged Defense' : 'ED', + 'Melee Defense' : 'MEL', + 'AoE Defense' : '2', + 'Smashing Defense' : '3', + 'Lethal Defense' : '4', + 'Fire Defense' : '5', + 'Cold Defense' : '6', + 'Energy Defense' : '7', + 'Negative Energy Defense' : '8', + 'Psionic Defense' : '9', + 'Toxic Defense' : '1', + }, + 'Debuff Resistance' : { + 'Regeneration Resistance' : 'ON R', + 'Recovery Resistance' : 'RY R', + 'To Hit Resistance' : 'IT R', + 'Defense Resistance' : 'NSE RES', + }, + 'Status Effect Protection' : { + 'Hold Protection' : 'D P', + 'Immobilize Protection' : 'LIZE P', + 'Stun Protection' : 'N P', + 'Sleep Protection' : 'P P', + 'Knockback Protection' : 'K P', + 'Confuse Protection' : 'SE P', + 'Terrorize Protection' : 'ZE P', + 'Repel Protection' : 'EL P', + 'Teleport Protection' : 'T P', + }, + 'Status Effect Resistance' : { + 'Hold Resistance' : 'D R', + 'Immobilize Resistance' : 'LIZE R', + 'Stun Resistance' : 'N R', + 'Sleep Resistance' : 'P R', + 'Knockback Resistance' : 'K R', + 'Confuse Resistance' : 'SE R', + 'Terrorize Resistance' : 'ZE R', + 'Placate Resistance' : 'TE R', + 'Taunt Resistance' : 'NT R', + }, + 'Miscellaneous' : { + 'Level Shift' : 'L S', + }, + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.AttributeMenu = wx.Menu() + for group, controls in self.AttributeTable.items(): + submenu = wx.Menu() + self.AttributeMenu.AppendSubMenu(submenu, group) + for cb in controls: + submenu.Append(wx.ID_ANY, cb) + + self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) + + self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) + groupSizer.Add(self.editbox) + + newButton = self.editbox.GetNewButton() + newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) + + return groupSizer + + def MakeBindString(self): + map = {} + bindstrings = [] + for _, controls in self.AttributeTable.items(): + for cb, data in controls.items(): + map[cb] = data + + for string in self.editbox.GetStrings(): + if string: + bindstrings.append(f'monitorattribute {map[string]}') + + return '$$'.join(bindstrings) + + def Serialize(self): + return { + 'attributes' : self.editbox.GetStrings() + } + + def Deserialize(self, init): + self.editbox.SetStrings(init.get('attributes', [])) + + def OnNewButton(self, evt): + evt.GetEventObject().PopupMenu(self.AttributeMenu) + + def OnMenuItem(self, evt): + menuitem = evt.EventObject.FindItemById(evt.GetId()) + existingstrings = self.editbox.GetStrings() + existingstrings.append(menuitem.GetItemLabel()) + self.editbox.SetStrings(existingstrings) + +####### Auto Power +class AutoPowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) + autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.autoPowerName = PowerPicker(dialog) + autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) + + return autoPowerSizer + + def MakeBindString(self): + return f"powexecauto {self.autoPowerName.GetLabel()}" + + def Serialize(self): + return { + 'pname' : self.autoPowerName.GetLabel(), + 'picon' : self.autoPowerName.IconFilename + } + + def Deserialize(self, init): + if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) + +####### Buff Display Command +class BuffDisplayCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.buffDisplayMap = { + 'Status Window' : { + 'Hide Auto' : 1, + 'Hide Toggles' : 2, + 'No Blinking' : 4, + 'No Stacking' : 8, + 'Numeric Stacking' : 16, + 'Hide Buff Numbers' : 32, + 'Stop Sending Buffs' : 64, + }, + 'Group Window' : { + 'Hide Auto' : 256, + 'Hide Toggles' : 512, + 'No Blinking' : 1024, + 'No Stacking' : 2048, + 'Numeric Stacking' : 4096, + 'Hide Buff Numbers' : 8192, + 'Stop Sending Buffs' : 16384, + }, + 'Pet Window' : { + 'Hide Auto' : 65536, + 'Hide Toggles' : 131072, + 'No Blinking' : 262144, + 'No Stacking' : 524288, + 'Numeric Stacking' : 1048576, + 'Hide Buff Numbers' : 2097152, + 'Stop Sending Buffs' : 4194304, + }, + } + self.Groups = {} + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + for group, controls in self.buffDisplayMap.items(): + self.Groups[group] = ControlGroup(dialog, self.Page, label = group) + groupid = self.Groups[group].GetStaticBox().GetId() + for cb, data in controls.items(): + self.Groups[group].AddControl( + ctlType = 'checkbox', + ctlName = f"{groupid}_{group}_{cb}", + label = cb, + data = data, + ) + + groupSizer.Add(self.Groups[group]) + + return groupSizer + + def CalculateValue(self): + page = wx.App.Get().Main.Profile.CustomBinds + + total = 0 + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] + if checkbox.IsChecked(): + total = total + checkbox.Data + return total + + def MakeBindString(self): + return f"optionset buffsettings {self.CalculateValue()}" + + def Serialize(self): + return { 'value' : self.CalculateValue() } + + def Deserialize(self, init): + value = init.get('value', 0) + + value = value or 0 # in case we had for some reason 'None' stashed in the init values + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] + checkbox.SetValue( checkbox.Data & value ) + +####### Chat Command +class ChatCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.chatChannelMap = { # before __init__ + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + chatCommandSizer = wx.GridBagSizer(5, 5) + self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") + chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) + # row 1 + self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) + self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) + self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) + # row 2 + self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) + self.chatCommandDuration.SetRange(1, 20) + self.chatCommandDuration.SetValue(7) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandDuration, (2,1)) + self.chatCommandChatSize = wx.Choice(dialog, -1, + choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) + self.chatCommandChatSize.SetSelection(5) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) + self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) + self.chatCommandChannel.SetSelection(0) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChannel, (2,5)) + # row 3 + self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") + chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) + self.chatCommandMessage = wx.TextCtrl(dialog, -1) + self.chatCommandMessage.SetHint('Chat Command Text') + chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) + + return chatCommandSizer + + def MakeBindString(self): + duration = self.chatCommandDuration.GetValue() + + choice = self.chatCommandChatSize + index = choice.GetSelection() + size = choice.GetString(index) + + duration = f"" if duration != 7 else "" + size = f"" if size != "1" else "" + + bdcolor = fgcolor = bgcolor = '' + if self.chatCommandUseColorsCB.IsChecked(): + bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + + bdcolor = f"" + fgcolor = f"" + bgcolor = f"" + + beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' + text = self.chatCommandMessage.GetValue() + + choice = self.chatCommandChannel + index = choice.GetSelection() + channel = choice.GetString(index) + + return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" + + def Serialize(self): + return { + 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), + 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), + 'channel' : self.chatCommandChannel .GetSelection(), + 'size' : self.chatCommandChatSize.GetSelection(), + 'duration' : self.chatCommandDuration.GetValue(), + 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'text' : self.chatCommandMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) + if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) + if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) + if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) + if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) + if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) + if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) + if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) + if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) + + +####### Chat Command Global +class ChatGlobalCmd(PowerBindCmd): + def BuildUI(self, dialog): + chatCommandGlobalSizer = wx.GridBagSizer(5,5) + + self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") + chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) + + self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalChannel.SetHint("Channel") + chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) + + self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') + chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) + + chatCommandGlobalSizer.AddGrowableCol(1) + + return chatCommandGlobalSizer + + def MakeBindString(self): + useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() + channel = self.chatCommandGlobalChannel.GetValue() + message = self.chatCommandGlobalMessage.GetValue() + + preface = "beginchat /" if useBeginchat else "" + + return f'{preface}send "{channel}" {message}' + + def Serialize(self): + return { + 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), + 'channel' : self.chatCommandGlobalChannel.GetValue(), + 'message' : self.chatCommandGlobalMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) + if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) + if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) + +#######Costume Change +class CostumeChangeCmd(PowerBindCmd): + def BuildUI(self, dialog): + costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeCostume = wx.Choice(dialog, -1, + choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) + self.costumeChangeCostume.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeEmote = wx.Choice(dialog, -1, + choices = GameData.Emotes['costumechange']) + self.costumeChangeEmote.Insert("- None -", 0) + self.costumeChangeEmote.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return costumeChangeSizer + + def MakeBindString(self): + costumeNumber = self.costumeChangeCostume.GetSelection() + costumeEmote = self.costumeChangeEmote.GetSelection() + + if costumeEmote: # None, or 0 == "- None -" + ccCmd = 'cce' + emoteName = self.costumeChangeEmote.GetString(costumeEmote) + emoteName = " CC" + emoteName.replace(" ","") + else: + ccCmd = 'cc' + emoteName = '' + + return f"{ccCmd} {costumeNumber}{emoteName}" + + def Serialize(self): + return{ + 'costumeNumber': self.costumeChangeCostume.GetSelection(), + 'costumeEmote' : self.costumeChangeEmote.GetSelection(), + } + + def Deserialize(self, init): + if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) + if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) + +####### Movement Command +class MovementCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + self.plusbutton.SetValue(True) + + self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.commandchoice = wx.Choice(dialog, choices = [ + "forward", "left", "right", "backward", "up", "down", + "turnleft", "turnright", "first", "autorun", "clicktomove", + ],) + sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) + self.commandchoice.SetSelection(0) + + self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + pre = post = '' + if self.plusbutton.GetValue() : pre = "+" + elif self.plusplusbutton.GetValue() : pre = "++" + elif self.minusbutton.GetValue() : pre = "-" + elif self.zerobutton.GetValue() : post = " 0" + elif self.onebutton.GetValue() : post = " 1" + + command = self.commandchoice.GetString(self.commandchoice.GetSelection()) + + return f"{pre}{command}{post}" + + def Serialize(self): + mod = '' + if self.plusbutton.GetValue() : mod = "plus" + elif self.plusplusbutton.GetValue() : mod = "plusplus" + elif self.minusbutton.GetValue() : mod = "minus" + elif self.zerobutton.GetValue() : mod = "zero" + elif self.onebutton.GetValue() : mod = "one" + + return { + 'mod' : mod, + 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), + } + + def Deserialize(self, init): + mod = init.get('mod', 'plus') + + if mod == 'plus' : self.plusbutton.SetValue(True) + elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) + elif mod == 'minus' : self.minusbutton.SetValue(True) + elif mod == 'zero' : self.zerobutton.SetValue(True) + elif mod == 'one' : self.onebutton.SetValue(True) + + self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) + +####### Graphics Command +class GraphicsCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.FlexGridSizer(2) + + self.visscalecb = wx.CheckBox(dialog, label = "visscale") + sizer.Add(self.visscalecb) + self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) + sizer.Add(self.visscalesc) + + self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") + sizer.Add(self.dofweightcb) + self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) + sizer.Add(self.dofweightsc) + + self.fsaacb = wx.CheckBox(dialog, label = "fsaa") + sizer.Add(self.fsaacb) + self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) + self.fsaach.SetSelection(0) + sizer.Add(self.fsaach) + + self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") + sizer.Add(self.bloomscalecb) + self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) + self.bloomscalech.SetSelection(0) + sizer.Add(self.bloomscalech) + + self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") + sizer.Add(self.bloomweightcb) + self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) + sizer.Add(self.bloomweightsc) + + self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") + sizer.Add(self.lodbiascb) + self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) + sizer.Add(self.lodbiassc) + + self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") + sizer.Add(self.renderscalecb) + self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) + sizer.Add(self.renderscalesc) + + return sizer + + def MakeBindString(self): + # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. + bindstrings = [] + if self.visscalecb.IsChecked(): + bindstrings.append("visscale " + str(self.visscalesc.GetValue())) + if self.dofweightcb.IsChecked(): + bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) + if self.fsaacb.IsChecked(): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bindstrings.append("fsaa " + fsaavalue) + if self.bloomscalecb.IsChecked(): + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + bindstrings.append("bloomscale " + bloomscalevalue) + if self.bloomweightcb.IsChecked(): + bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) + if self.lodbiascb.IsChecked(): + bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) + if self.renderscalecb.IsChecked(): + bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) + + return '$$'.join(bindstrings) + + def Serialize(self): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + return { + 'visscalecb' : self.visscalecb.IsChecked(), + 'visscalesc' : self.visscalesc.GetValue(), + 'dofweightcb' : self.dofweightcb.IsChecked(), + 'dofweightsc' : self.dofweightsc.GetValue(), + 'fsaacb' : self.fsaacb.IsChecked(), + 'fsaach' : fsaavalue, + 'bloomscalecb' : self.bloomscalecb.IsChecked(), + 'bloomscalech' : bloomscalevalue, + 'bloomweightcb' : self.bloomweightcb.IsChecked(), + 'bloomweightsc' : self.bloomweightsc.GetValue(), + 'lodbiascb' : self.lodbiascb.IsChecked(), + 'lodbiassc' : self.lodbiassc.GetValue(), + 'renderscalecb' : self.renderscalecb.IsChecked(), + 'renderscalesc' : self.renderscalesc.GetValue(), + } + + def Deserialize(self, init): + self.visscalecb.SetValue(init.get('visscalecb', False)) + self.visscalesc.SetValue(init.get('visscalesc', 1.0)) + self.dofweightcb.SetValue(init.get('dofweightcb', False)) + self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) + self.fsaacb.SetValue(init.get('fsaacb', False)) + self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) + self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) + self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) + self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) + self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) + self.lodbiascb.SetValue(init.get('lodbiascb', False)) + self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) + self.renderscalecb.SetValue(init.get('renderscalecb', False)) + self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) + +####### Custom Bind +class CustomBindCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.customBindName = wx.TextCtrl(dialog, -1) + self.customBindName.SetHint('Custom Bind Text') + sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + return self.customBindName.GetValue() + + def Serialize(self): + return { 'customBindName': self.customBindName.GetValue() } + + def Deserialize(self,init): + if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) + +####### Emote +class EmoteCmd(PowerBindCmd): + def BuildUI(self, dialog): + emoteSizer = wx.BoxSizer(wx.HORIZONTAL) + self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") + emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + self.emoteName = wx.Button(dialog, -1, "...") + self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) + emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) + + return emoteSizer + + def MakeBindString(self): + displayedEmoteName = self.emoteName.GetLabel() + actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] + + return actualEmotePayload + + def Serialize(self): + return {'emoteName': self.emoteName.GetLabel()} + + def Deserialize(self, init): + if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) + +####### Load Binds Directory +class LoadBindsDir(PowerBindCmd): + def BuildUI(self, dialog): + mainSizer = wx.BoxSizer(wx.VERTICAL) + + lbSizer = wx.BoxSizer(wx.HORIZONTAL) + lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") + lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + profiles = Profile.GetAllProfileBindsDirs() + + self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) + lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") + self.lbResetCB.SetValue(True) + + mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + return mainSizer + + def MakeBindString(self): + + # If the specified binds directory disappeared between runs, we'd crash, so handle that. + if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' + + config = wx.ConfigBase.Get() + if config.Exists('GameBindPath'): + bindpath = config.Read('GameBindPath') + else: + bindpath = config.Read('BindPath') + + reset = "" + if self.lbResetCB.GetValue(): + reset = "keybind_reset$$" + + resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' + return reset + 'bindloadfile ' + str(resetfilepath) + + def Serialize(self): + return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), + 'ResetKeybinds' : self.lbResetCB.GetValue(), + } + + def Deserialize(self, init): + if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) + self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) + +####### Power Abort +class PowerAbortCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecabort' + +####### Power Unqueue +class PowerUnqueueCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecunqueue' + +####### SG Mode +class SGModeCmd(PowerBindCmd): + def BuildUI(self, dialog): + sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) + sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") + self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") + + sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) + + return sgmodeSizer + + def MakeBindString(self): + if self.sgmodeOnRB.GetValue(): + return 'sgmodeset 1' + elif self.sgmodeOffRB.GetValue(): + return 'sgmodeset 0' + else: + return 'sgmode' + + def Serialize(self): + if self.sgmodeOnRB.GetValue(): + val = "On" + elif self.sgmodeOffRB.GetValue(): + val = "Off" + else: + val = "Toggle" + + return {"value" : val} + + def Deserialize(self, init): + val = init.get('value', '') + if val == "On": + self.sgmodeOnRB.SetValue(True) + elif val == "Off": + self.sgmodeOffRB.SetValue(True) + else: + self.sgmodeToggleRB.SetValue(True) + +####### Target Custom +class TargetCustomCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetCustomSizer = wx.GridBagSizer(5,5) + targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), + flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) + self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetCustomModeChoice.SetSelection(0) + targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) + self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) + self.targetCustomOptionalName.SetHint("Optional name to match") + targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) + self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") + targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) + self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") + targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) + self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") + targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) + self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") + targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) + self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") + targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) + self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") + targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) + self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") + targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) + self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") + targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) + + targetCustomSizer.AddGrowableCol(2) + + return targetCustomSizer + + def MakeBindString(self): + choice = self.targetCustomModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + targetCommand = "targetcustom" + mode.lower() + + enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" + friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" + defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" + alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" + mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" + notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" + base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" + notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" + + name = self.targetCustomOptionalName.GetValue() + + return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" + + def Serialize(self): + return { + 'mode' : self.targetCustomModeChoice.GetSelection(), + 'enemy' : self.targetCustomCBEnemies. IsChecked(), + 'friend' : self.targetCustomCBFriends. IsChecked(), + 'defeated' : self.targetCustomCBDefeated. IsChecked(), + 'alive' : self.targetCustomCBAlive. IsChecked(), + 'mypet' : self.targetCustomCBMyPets. IsChecked(), + 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), + 'base' : self.targetCustomCBBaseItems. IsChecked(), + 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), + 'name' : self.targetCustomOptionalName.GetValue(), + } + + def Deserialize(self, init): + if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) + if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) + if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) + if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) + if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) + if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) + if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) + if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) + if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) + if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) + + +####### Target Enemy +class TargetEnemyCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) + targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetEnemyModeChoice.SetSelection(0) + targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetEnemySizer + + def MakeBindString(self): + choice = self.targetEnemyModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetenemy" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetEnemyModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) + +####### Target Friend +class TargetFriendCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) + targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetFriendModeChoice.SetSelection(0) + targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetFriendSizer + + def MakeBindString(self): + choice = self.targetFriendModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetfriend" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetFriendModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) + +####### Team/Pet Select +class TeamPetSelectCmd(PowerBindCmd): + def BuildUI(self, dialog): + teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], + style=wx.ALIGN_CENTER_VERTICAL) + self.teamPetSelectNumber.SetSelection(0) + teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) + + return teamPetSelectSizer + + def MakeBindString(self): + teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' + targetNumber = self.teamPetSelectNumber.GetSelection()+1 + + return f"{teamOrPet}select {targetNumber}" + + def Serialize(self): + return { + 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', + 'targetNum': self.teamPetSelectNumber.GetSelection(), + } + + def Deserialize(self, init): + ToP = init.get('teamOrPet', '') + if ToP == 'pet': + self.teamPetSelectPetRB.SetValue(True) + else: + self.teamPetSelectTeamRB.SetValue(True) + if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) + +####### Unselect +class UnselectCmd(PowerBindCmd): + def MakeBindString(self): + return 'unselect' + +####### Use Insp By Name +class UseInspByNameCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) + for _, types in GameData.Inspirations.items(): + for _, info in types.items(): + for insp in info['tiers']: + name = re.sub(' ', '', str(insp)) + icon = GetIcon(f'Inspirations/{name}') + self.useInspByNameModeChoice.Append(insp, icon) + self.useInspByNameModeChoice.SetSelection(0) + useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) + + return useInspByNameSizer + + def MakeBindString(self): + choice = self.useInspByNameModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "inspexecname " + mode.lower() + + def GetAllInsps(self): + Insplist = [] + for _, info in GameData.Inspirations.items(): + for insp in info['tiers']: + Insplist.append(insp) + Insplist.append("---") + Insplist.pop(-1) # snip the terminal "---" + + return Insplist + + def Serialize(self): + return { 'insp' : self.useInspByNameModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) + +####### Use Insp From Row / Column +class UseInspRowColCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnRow.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) + self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnCol.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) + + return useInspRowColumnSizer + + def MakeBindString(self): + row = self.useInspRowColumnRow.GetSelection()+1 + col = self.useInspRowColumnCol.GetSelection()+1 + + return f"inspexectray {col} {row}" + + def Serialize(self): + return { + 'col' : self.useInspRowColumnCol.GetSelection(), + 'row' : self.useInspRowColumnRow.GetSelection(), + } + + def Deserialize(self, init): + if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) + if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) + +####### Use Power +class UsePowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + outerSizer = wx.BoxSizer(wx.HORIZONTAL) + + usePowerSizer = wx.GridBagSizer(5,5) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBToggle, (0,1)) + self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOn, (0,2)) + self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOff, (0,3)) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerName = PowerPicker(dialog) + usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) + usePowerSizer.AddGrowableCol(3) + + outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) + + return outerSizer + + def MakeBindString(self): + if self.usePowerRBToggle.GetValue(): + method = "powexecname" + elif self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') + return '' + + return f"{method} {self.usePowerName.GetLabel()}" + + def Serialize(self): + if self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + method = "powexecname" + return { + 'method': method, + 'pname' : self.usePowerName.GetLabel(), + 'picon' : self.usePowerName.IconFilename + } + + def Deserialize(self, init): + method = init.get('method', '') + if method == 'powexectoggleon': + self.usePowerRBOn.SetValue(True) + elif method == 'powexectoggleoff': + self.usePowerRBOff.SetValue(True) + else: + self.usePowerRBToggle.SetValue(True) + if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) + +####### Use Power From Tray +class UsePowerFromTrayCmd(PowerBindCmd): + def BuildUI(self, dialog): + usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTrayTray = wx.Choice(dialog, -1, + choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', + 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) + self.usePowerFromTrayTray.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) + self.usePowerFromTraySlot.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return usePowerFromTraySizer + + def MakeBindString(self): + choice = self.usePowerFromTrayTray + tray = choice.GetSelection() + + choice = self.usePowerFromTraySlot + slot = choice.GetSelection()+1 + + mode = "slot" + mode2 = '' + if tray > 3: + mode = "tray" + mode2 = f" {tray - 3}" + elif tray == 3: + mode = "alt2slot" + elif tray == 2: + mode = "altslot" + + return f"powexec{mode} {slot}{mode2}" + + def Serialize(self): + return { + 'tray' : self.usePowerFromTrayTray.GetSelection(), + 'slot' : self.usePowerFromTraySlot.GetSelection(), + } + + def Deserialize(self, init): + if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) + if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) + +####### Window Color +class WindowColorCmd(PowerBindCmd): + def BuildUI(self, dialog): + windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) + borderSizer = wx.BoxSizer(wx.VERTICAL) + self.ColorBorder.SetSizer(borderSizer) + self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) + borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) + + windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) + + RGBASizer = wx.FlexGridSizer(3, 4, 5) + + RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) + self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) + self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + windowColorSizer.Add(RGBASizer) + + self.UpdateFromSlider() + + return windowColorSizer + + def MakeBindString(self): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + return f"windowcolor {Rval} {Gval} {Bval} {Aval}" + + def Serialize(self): + return { + 'Rval' : self.RSlider.GetValue(), + 'Gval' : self.GSlider.GetValue(), + 'Bval' : self.BSlider.GetValue(), + 'Aval' : self.ASlider.GetValue(), + } + + def Deserialize(self, init): + self.RSlider.SetValue(init['Rval']) + self.GSlider.SetValue(init['Gval']) + self.BSlider.SetValue(init['Bval']) + self.ASlider.SetValue(init['Aval']) + self.UpdateFromSlider() + + def UpdateFromSlider(self, _ = None): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RReadout.SetValue(Rval) + self.GReadout.SetValue(Gval) + self.BReadout.SetValue(Bval) + self.AReadout.SetValue(Aval) + self.ColorBorder.Refresh() + + def UpdateFromText(self, _ = None): + Rval = self.RReadout.GetValue() + Gval = self.GReadout.GetValue() + Bval = self.BReadout.GetValue() + Aval = self.AReadout.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RSlider.SetValue(Rval) + self.GSlider.SetValue(Gval) + self.BSlider.SetValue(Bval) + self.ASlider.SetValue(Aval) + self.ColorBorder.Refresh() + +####### Window Save / Load +class WindowSaveLoadCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) + self.CommandChoice.SetSelection(0) + sizer.Add(self.CommandChoice, 0, wx.ALL, 5) + + self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), + value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) + sizer.Add(self.FilePath, 0, wx.ALL, 5) + + return sizer + + def MakeBindString(self): + command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] + return f'{command} "{self.FilePath.GetValue()}"' + + def Serialize(self): + return { + 'command' : self.CommandChoice.GetSelection(), + 'filename' : self.FilePath.GetValue(), + } + + def Deserialize(self, init): + self.CommandChoice.SetSelection(init.get('command', 0)) + self.FilePath.SetValue(init.get('filename', '')) + +####### Window Toggle +class WindowToggleCmd(PowerBindCmd): + def BuildUI(self, dialog): + self.WindowNames = { + 'Actions' : 'actions', + 'Auction House' : 'ah', + 'Badge' : 'badge', + 'Channel Search' : 'chansearch', + 'Chat' : 'chat', + 'Custom Chat 1' : 'chat1', + 'Custom Chat 2' : 'chat2', + 'Custom Chat 3' : 'chat3', + 'Custom Chat 4' : 'chat4', + 'Clues' : 'clue', + 'Combat Numbers' : 'combatnumbers', + 'Contacts' : 'contact', + 'Contact Finder' : 'contactfinder', + 'Costumes' : 'costume', + 'Email' : 'email', + 'Enhancements' : 'enhancements', + 'Friends' : 'friend', + 'Group' : 'group', + 'Help' : 'helpwindow', + 'Incarnate' : 'incarnate', + 'Inspirations' : 'insp', + 'League' : 'league', + 'LFG' : 'lfg', + 'Map' : 'map', + 'Mission' : 'mission', + 'Nav / Compass' : 'nav', + 'Options' : 'options', + 'Pets' : 'pet', + 'Petition' : 'petition', + 'Power Tray' : 'powers', + 'Power List' : 'powerlist', + 'Quit' : 'quit', + 'Recipes' : 'recipe', + 'Salvage' : 'salvage', + 'Search' : 'search', + 'Supergroup' : 'sg', + 'Target' : 'target', + 'Team' : 'team', + 'Tray' : 'tray', + 'Tray1' : 'tray1', + 'Tray2' : 'tray2', + 'Tray3' : 'tray3', + 'Tray4' : 'tray4', + 'Tray5' : 'tray5', + 'Tray6' : 'tray6', + 'Tray7' : 'tray7', + 'Tray8' : 'tray8', + 'Vault' : 'vault', + } + + self.ShortToggleCommands = { + 'Auction House' : 'ah', + 'Chat' : 'chat', + 'Help' : 'helpwindow', + 'Map' : 'map', + 'Nav / Compass' : 'nav', + 'Power Tray' : 'powers', + 'Target' : 'target', + 'Tray' : 'tray', + } + + windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) + windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) + self.windowToggleTray.SetSelection(0) + windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.windowShowRB = wx.RadioButton(dialog, -1, "Show") + self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") + + windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) + + return windowToggleSizer + + def MakeBindString(self): + choice = self.windowToggleTray + index = choice.GetSelection() + windowdesc = choice.GetString(index) + windowname = self.WindowNames[windowdesc] + + if self.windowShowRB.GetValue(): + return 'show ' + windowname + elif self.windowHideRB.GetValue(): + return 'windowhide ' + windowname + else: + if shortcmd := self.ShortToggleCommands.get(windowdesc, None): + return shortcmd + else: + return 'toggle ' + windowname + + + def Serialize(self): + choice = self.windowToggleTray + if self.windowShowRB.GetValue(): + action = "Show" + elif self.windowHideRB.GetValue(): + action = "Hide" + else: + action = "Toggle" + return { + 'window': choice.GetString(choice.GetSelection()), + 'action': action, + } + + def Deserialize(self, init): + choice = self.windowToggleTray + if window := init.get('window', ''): + if isinstance(window, int): + choice.SetSelection(window) + else: + choice.SetSelection(choice.FindString(window)) + + if choice.GetSelection() == wx.NOT_FOUND: + choice.SetSelection(0) + + action = init.get('action', '') + if action == "Show": + self.windowShowRB.SetValue(True) + elif action == "Hide": + self.windowHideRB.SetValue(True) + else: + self.windowToggleRB.SetValue(True) + + +# Must always add to this list when adding a new command class above +menuStructure = { + 'Graphics / UI' : [ + 'Attribute Monitor', + 'Buff Display Settings', + 'Graphics Settings', + 'Window Color', + 'Window Save / Load', + 'Window Toggle', + ], + 'Inspirations' : [ + 'Use Inspiration By Name', + 'Use Inspiration From Row/Column', + ], + 'Powers' : [ + 'Auto Power', + 'Power Abort', + 'Power Unqueue', + 'Use Power', + 'Use Power From Tray', + ], + 'Social' : [ + 'Away From Keyboard', + 'Chat Command', + 'Chat Command (Global)', + 'Costume Change', + 'Emote', + 'Supergroup Mode', + ], + 'Targeting' : [ + 'Target Custom', + 'Target Enemy', + 'Target Frield', + 'Team/Pet Select', + 'Unselect', + ], + 'Misc' : [ + 'Load Binds Directory', + 'Movement Commands', + ], + # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, + # but I'm leaving it here to remind myself that we do that. + } + +# Must always add to this list when adding a new command class above +commandClasses = { + 'Auto Power' : AutoPowerCmd, + 'Away From Keyboard' : AFKCmd, + 'Attribute Monitor' : AttributeMonitorCmd, + 'Buff Display Settings' : BuffDisplayCmd, + 'Chat Command' : ChatCmd, + 'Chat Command (Global)' : ChatGlobalCmd, + 'Costume Change' : CostumeChangeCmd, + 'Custom Bind' : CustomBindCmd, + 'Emote' : EmoteCmd, + 'Graphics Settings' : GraphicsCmd, + 'Load Binds Directory' : LoadBindsDir, + 'Movement Commands' : MovementCmd, + 'Power Abort' : PowerAbortCmd, + 'Power Unqueue' : PowerUnqueueCmd, + 'Supergroup Mode' : SGModeCmd, + 'Target Custom' : TargetCustomCmd, + 'Target Enemy' : TargetEnemyCmd, + 'Target Friend' : TargetFriendCmd, + 'Team/Pet Select' : TeamPetSelectCmd, + 'Unselect' : UnselectCmd, + 'Use Inspiration By Name' : UseInspByNameCmd, + 'Use Inspiration From Row/Column' : UseInspRowColCmd, + 'Use Power' : UsePowerCmd, + 'Use Power From Tray' : UsePowerFromTrayCmd, + 'Window Color' : WindowColorCmd, + 'Window Save / Load' : WindowSaveLoadCmd, + 'Window Toggle' : WindowToggleCmd, +} +# use these when we rename a commandClass so that old Profiles will still load correctly. +# If we've also updated the class, we need to try to make sure the new class will still +# Deserialize the legacy data, or at least not crash. +deprecatedCommandClasses = { + 'SG Mode Toggle' : SGModeCmd, + 'Use Insp By Name' : UseInspByNameCmd, + 'Use Insp From Row/Column' : UseInspRowColCmd, +} +commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/SGModeCmd.py b/UI/PowerBinderCommand/SGModeCmd.py new file mode 100644 index 0000000..4c02ab7 --- /dev/null +++ b/UI/PowerBinderCommand/SGModeCmd.py @@ -0,0 +1,1800 @@ +import wx +import re +import UI +import UI.EmotePicker +from UI.ControlGroup import ControlGroup +from UI.PowerPicker import PowerPicker +from Help import HelpButton +import wx.adv +from wx.adv import BitmapComboBox, EditableListBox +from pathlib import PureWindowsPath +import GameData +import Profile +from Icon import GetIcon + +class PowerBinderDialog(wx.Dialog): + def __init__(self, parent, button, init = {}): + wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) + + self.Page = parent.Page + self.EditDialog = PowerBinderEditDialog(self) + self.Button = button + self.AddStepMenu = self.makeAddStepMenu() + + sizer = wx.BoxSizer(wx.VERTICAL); + self.mainSizer = sizer + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) + # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) + # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) + #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) + AddStepButton = wx.Button(self, -1, 'Add Step') + AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) + AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) + choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) + choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) + sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) + + rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) + + self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) + self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) + self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) + rearrangeCtrl.Add(self.RearrangeList, 1) + + rearrangeButtons = wx.BoxSizer(wx.VERTICAL) + self.DelButton = wx.Button(self, -1, "Delete") + self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) + self.EditButton = wx.Button(self, -1, "Edit") + self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) + self.EditButton.Disable() + upButton = wx.Button(self, -1, "\u25B2") + upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) + downButton = wx.Button(self, -1, "\u25BC") + downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) + rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) + rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) + + sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.BindStringDisplay = wx.TextCtrl(self, -1) + self.BindStringDisplay.Disable() + choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, + wx.ALIGN_CENTER_VERTICAL) + choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) + + sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) + + sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) + + # need to dig around and get the OK button since we show this dialog modelessly now. + okButton = self.FindWindow(self.GetAffirmativeId()) + okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) + + # Wrap everything in a vbox to add some padding + vbox = wx.BoxSizer(wx.VERTICAL); + vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); + + self.SetSizerAndFit(vbox); + self.Layout() + self.Fit() + self.SetFocus() + + # if we are loading from profile, ie, have "init", build the list from it + if init: self.LoadFromData(init) + + def LoadFromData(self, init): + for item in init: + for type, data in item.items(): + commandClass = commandClasses.get(type, None) + if not commandClass: + commandClass = deprecatedCommandClasses.get(type, None) + if not commandClass: + wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") + continue + newCommand = commandClass(self.EditDialog, data) + index = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.SetClientData(index, newCommand) + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) + self.EditDialog.mainSizer.Hide(newCommand.UI) + self.UpdateBindStringDisplay() + + def SaveToData(self): + data = [] + index = 0 + for _ in self.RearrangeList.GetItems(): + # check whether we have an object already attached to this choice + cmdObject = self.RearrangeList.GetClientData(index) + commandClassName = commandRevClasses[type(cmdObject)] + data.append({commandClassName: cmdObject.Serialize()}) + index = index + 1 + return data + + def OnAddStepButton(self, evt): + button = evt.EventObject + if not self.AddStepMenu: + self.AddStepMenu = self.makeAddStepMenu() + button.PopupMenu(self.AddStepMenu) + + + def OnOKButton(self, _): + if self.Button.tgtTxtCtrl: + bindString = self.MakeBindString() + if bindString != self.Button.tgtTxtCtrl.GetValue(): + self.Button.tgtTxtCtrl.SetValue(bindString) + wx.App.Get().Main.Profile.SetModified() + self.Close() + + def OnRearrangeDelete(self, _): + current = self.RearrangeList.GetSelection() + if current == wx.NOT_FOUND: return + + self.RearrangeList.Delete(current) + self.UpdateBindStringDisplay() + + def OnRearrangeUp(self, _): + self.RearrangeList.MoveCurrentUp() + self.UpdateBindStringDisplay() + + def OnRearrangeDown(self, _): + self.RearrangeList.MoveCurrentDown() + self.UpdateBindStringDisplay() + + def OnRearrangeEdit(self, _): + index = self.RearrangeList.GetSelection() + + # check whether we have an object already attached to this choice + cmdObject = None + try: + cmdObject = self.RearrangeList.GetClientData(index) + except Exception: + pass + + if cmdObject: + self.ShowEditDialogFor(cmdObject) + self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) + else: + print("cmdObject was None") + self.UpdateBindStringDisplay() + + # OnAddStepMenu creates a new step and adds it to the rearrangelist + def OnAddStepMenu(self, evt): + menuitem = self.AddStepMenu.FindItemById(evt.GetId()) + chosenName = menuitem.GetItemLabel() + + # make a new command object, attached to the parent dialog + newCommandClass = commandClasses[chosenName] + newCommand = newCommandClass(self.EditDialog) + + # show the edit dialog if this command needs it + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) + if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): + self.EditDialog.mainSizer.Remove(newCommand.UI) + return + + newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.Select(newBindIndex) + self.RearrangeList.SetClientData(newBindIndex, newCommand) + + self.OnListSelect() + self.UpdateBindStringDisplay() + + def OnListSelect(self, _ = None): + selected = self.RearrangeList.GetSelection() + + if selected != wx.NOT_FOUND: + selCommand = self.RearrangeList.GetClientData(selected) + if selCommand.UI: + self.EditButton.Enable() + else: + self.EditButton.Disable() + + def UpdateBindStringDisplay(self): + self.BindStringDisplay.SetValue(self.MakeBindString()) + self.BindStringDisplay.SetToolTip(self.MakeBindString()) + + def MakeBindString(self): + cmdBindStrings = [] + for index in range(self.RearrangeList.GetCount()): + c = self.RearrangeList.GetClientData(index) + if c: cmdBindStrings.append(c.MakeBindString()) + + bindstring = ('$$'.join(cmdBindStrings)) + return bindstring + + def ShowEditDialogFor(self, command): + if not command.UI: return + + self.EditDialog.mainSizer.Show(command.UI) + + self.EditDialog.Layout() + self.EditDialog.Fit() + + self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') + returnval = self.EditDialog.ShowModal() + + self.EditDialog.mainSizer.Hide(command.UI) + + return returnval + + def makeAddStepMenu(self): + + stepMenu = wx.Menu() + + for subname in menuStructure: + submenu = wx.Menu() + stepMenu.AppendSubMenu(submenu, subname) + for classname in menuStructure[subname]: + submenu.Append(wx.ID_ANY, classname) + + stepMenu.Append(wx.ID_ANY, 'Custom Bind') + + return stepMenu + +class PowerBinderButton(wx.BitmapButton): + + def __init__(self, parent, tgtTxtCtrl, init = {}): + wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) + self.Init = init + self.Dialog = None + self.DialogParent = parent + + self.tgtTxtCtrl = tgtTxtCtrl + self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) + self.SetToolTip("Launch PowerBinder") + + def PowerBinderEventHandler(self, _): + self.PowerBinderDialog().Show() + + def LoadFromData(self, data): + self.PowerBinderDialog().LoadFromData(data) + + def SaveToData(self): + return self.PowerBinderDialog().SaveToData() + + def PowerBinderDialog(self): + if not self.Dialog: + self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) + return self.Dialog + + +class PowerBinderEditDialog(wx.Dialog): + def __init__(self, parent): + wx.Dialog.__init__(self, parent, -1, "Edit Step", + style = wx.DEFAULT_DIALOG_STYLE) + + outerSizer = wx.BoxSizer(wx.VERTICAL) + + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + self.mainSizer.SetMinSize([500, 150]) + + self.Page = parent.Page + + self.mainSizer.Add( + self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), + 0, wx.EXPAND|wx.ALL, 10) + + outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) + + self.SetSizerAndFit(outerSizer) + self.Layout() + self.Fit() + +########### Power Binder Command Objects +class PowerBindCmd(): + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + commandClassName = commandRevClasses[type(self)] + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{commandClassName} - {short_bindstr}" + + +####### Away From Keyboard +class AFKCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) + +####### Attribute Monitor +class AttributeMonitorCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.Groups = {} + self.AttributeTable = { + 'Base' : { + 'Current Hit Points' : 'NT H', + 'Max Hit Points' : 'X H', + 'Current Endurance' : 'T E', + 'Max Endurance' : 'X EN', + 'Regeneration Rate' : 'N RAT', + 'Recovery Rate' : 'Y RA', + 'Endurance Consumption' : 'SU', + 'ToHit Bonus' : 'T B', + 'Accuracy Bonus' : 'CC', + 'Last Hit Chance' : 'T C', + 'Damage Bonus' : 'DA', + 'Healing Bonus' : 'NG B', + 'Recharge Time Bonus' : 'ME B', + 'Endurance Discount' : 'CE DIS', + 'Stealth Radius (PvP)' : 'PVP', + 'Stealth Radius (PvE)' : 'PVE', + 'Perception Radius' : 'RC', + 'Range Bonus' : 'GE B', + 'Threat Level' : 'AT L', + 'Experience to Next Level' : 'XT', + 'Experience Debt' : 'XP', + 'Influence / Infamy' : 'INF', + 'Inherent' : 'NH', + }, + 'Movement Speed' : { + 'Flying Speed' : 'FL', + 'Jumping Speed' : 'PI', + 'Max Jump Height' : 'X J', + 'Run Speed' : 'RU', + }, + 'Damage Resistance' : { + 'Smashing Resistance' : 'G R', + 'Lethal Resistance' : 'L R', + 'Fire Resistance' : 'RE R', + 'Cold Resistance' : 'COLD R', + 'Energy Resistance' : 'DamageType[4]', + 'Negative Energy Resistance' : 'GY R', + 'Psyonic Resistance' : 'NIC R', + 'Toxic Resistance' : 'XIC R', + }, + 'Defense' : { + 'Base Defense' : 'BAS', + 'Ranged Defense' : 'ED', + 'Melee Defense' : 'MEL', + 'AoE Defense' : '2', + 'Smashing Defense' : '3', + 'Lethal Defense' : '4', + 'Fire Defense' : '5', + 'Cold Defense' : '6', + 'Energy Defense' : '7', + 'Negative Energy Defense' : '8', + 'Psionic Defense' : '9', + 'Toxic Defense' : '1', + }, + 'Debuff Resistance' : { + 'Regeneration Resistance' : 'ON R', + 'Recovery Resistance' : 'RY R', + 'To Hit Resistance' : 'IT R', + 'Defense Resistance' : 'NSE RES', + }, + 'Status Effect Protection' : { + 'Hold Protection' : 'D P', + 'Immobilize Protection' : 'LIZE P', + 'Stun Protection' : 'N P', + 'Sleep Protection' : 'P P', + 'Knockback Protection' : 'K P', + 'Confuse Protection' : 'SE P', + 'Terrorize Protection' : 'ZE P', + 'Repel Protection' : 'EL P', + 'Teleport Protection' : 'T P', + }, + 'Status Effect Resistance' : { + 'Hold Resistance' : 'D R', + 'Immobilize Resistance' : 'LIZE R', + 'Stun Resistance' : 'N R', + 'Sleep Resistance' : 'P R', + 'Knockback Resistance' : 'K R', + 'Confuse Resistance' : 'SE R', + 'Terrorize Resistance' : 'ZE R', + 'Placate Resistance' : 'TE R', + 'Taunt Resistance' : 'NT R', + }, + 'Miscellaneous' : { + 'Level Shift' : 'L S', + }, + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.AttributeMenu = wx.Menu() + for group, controls in self.AttributeTable.items(): + submenu = wx.Menu() + self.AttributeMenu.AppendSubMenu(submenu, group) + for cb in controls: + submenu.Append(wx.ID_ANY, cb) + + self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) + + self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) + groupSizer.Add(self.editbox) + + newButton = self.editbox.GetNewButton() + newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) + + return groupSizer + + def MakeBindString(self): + map = {} + bindstrings = [] + for _, controls in self.AttributeTable.items(): + for cb, data in controls.items(): + map[cb] = data + + for string in self.editbox.GetStrings(): + if string: + bindstrings.append(f'monitorattribute {map[string]}') + + return '$$'.join(bindstrings) + + def Serialize(self): + return { + 'attributes' : self.editbox.GetStrings() + } + + def Deserialize(self, init): + self.editbox.SetStrings(init.get('attributes', [])) + + def OnNewButton(self, evt): + evt.GetEventObject().PopupMenu(self.AttributeMenu) + + def OnMenuItem(self, evt): + menuitem = evt.EventObject.FindItemById(evt.GetId()) + existingstrings = self.editbox.GetStrings() + existingstrings.append(menuitem.GetItemLabel()) + self.editbox.SetStrings(existingstrings) + +####### Auto Power +class AutoPowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) + autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.autoPowerName = PowerPicker(dialog) + autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) + + return autoPowerSizer + + def MakeBindString(self): + return f"powexecauto {self.autoPowerName.GetLabel()}" + + def Serialize(self): + return { + 'pname' : self.autoPowerName.GetLabel(), + 'picon' : self.autoPowerName.IconFilename + } + + def Deserialize(self, init): + if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) + +####### Buff Display Command +class BuffDisplayCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.buffDisplayMap = { + 'Status Window' : { + 'Hide Auto' : 1, + 'Hide Toggles' : 2, + 'No Blinking' : 4, + 'No Stacking' : 8, + 'Numeric Stacking' : 16, + 'Hide Buff Numbers' : 32, + 'Stop Sending Buffs' : 64, + }, + 'Group Window' : { + 'Hide Auto' : 256, + 'Hide Toggles' : 512, + 'No Blinking' : 1024, + 'No Stacking' : 2048, + 'Numeric Stacking' : 4096, + 'Hide Buff Numbers' : 8192, + 'Stop Sending Buffs' : 16384, + }, + 'Pet Window' : { + 'Hide Auto' : 65536, + 'Hide Toggles' : 131072, + 'No Blinking' : 262144, + 'No Stacking' : 524288, + 'Numeric Stacking' : 1048576, + 'Hide Buff Numbers' : 2097152, + 'Stop Sending Buffs' : 4194304, + }, + } + self.Groups = {} + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + for group, controls in self.buffDisplayMap.items(): + self.Groups[group] = ControlGroup(dialog, self.Page, label = group) + groupid = self.Groups[group].GetStaticBox().GetId() + for cb, data in controls.items(): + self.Groups[group].AddControl( + ctlType = 'checkbox', + ctlName = f"{groupid}_{group}_{cb}", + label = cb, + data = data, + ) + + groupSizer.Add(self.Groups[group]) + + return groupSizer + + def CalculateValue(self): + page = wx.App.Get().Main.Profile.CustomBinds + + total = 0 + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] + if checkbox.IsChecked(): + total = total + checkbox.Data + return total + + def MakeBindString(self): + return f"optionset buffsettings {self.CalculateValue()}" + + def Serialize(self): + return { 'value' : self.CalculateValue() } + + def Deserialize(self, init): + value = init.get('value', 0) + + value = value or 0 # in case we had for some reason 'None' stashed in the init values + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] + checkbox.SetValue( checkbox.Data & value ) + +####### Chat Command +class ChatCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.chatChannelMap = { # before __init__ + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + chatCommandSizer = wx.GridBagSizer(5, 5) + self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") + chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) + # row 1 + self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) + self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) + self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) + # row 2 + self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) + self.chatCommandDuration.SetRange(1, 20) + self.chatCommandDuration.SetValue(7) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandDuration, (2,1)) + self.chatCommandChatSize = wx.Choice(dialog, -1, + choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) + self.chatCommandChatSize.SetSelection(5) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) + self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) + self.chatCommandChannel.SetSelection(0) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChannel, (2,5)) + # row 3 + self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") + chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) + self.chatCommandMessage = wx.TextCtrl(dialog, -1) + self.chatCommandMessage.SetHint('Chat Command Text') + chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) + + return chatCommandSizer + + def MakeBindString(self): + duration = self.chatCommandDuration.GetValue() + + choice = self.chatCommandChatSize + index = choice.GetSelection() + size = choice.GetString(index) + + duration = f"" if duration != 7 else "" + size = f"" if size != "1" else "" + + bdcolor = fgcolor = bgcolor = '' + if self.chatCommandUseColorsCB.IsChecked(): + bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + + bdcolor = f"" + fgcolor = f"" + bgcolor = f"" + + beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' + text = self.chatCommandMessage.GetValue() + + choice = self.chatCommandChannel + index = choice.GetSelection() + channel = choice.GetString(index) + + return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" + + def Serialize(self): + return { + 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), + 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), + 'channel' : self.chatCommandChannel .GetSelection(), + 'size' : self.chatCommandChatSize.GetSelection(), + 'duration' : self.chatCommandDuration.GetValue(), + 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'text' : self.chatCommandMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) + if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) + if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) + if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) + if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) + if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) + if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) + if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) + if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) + + +####### Chat Command Global +class ChatGlobalCmd(PowerBindCmd): + def BuildUI(self, dialog): + chatCommandGlobalSizer = wx.GridBagSizer(5,5) + + self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") + chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) + + self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalChannel.SetHint("Channel") + chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) + + self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') + chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) + + chatCommandGlobalSizer.AddGrowableCol(1) + + return chatCommandGlobalSizer + + def MakeBindString(self): + useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() + channel = self.chatCommandGlobalChannel.GetValue() + message = self.chatCommandGlobalMessage.GetValue() + + preface = "beginchat /" if useBeginchat else "" + + return f'{preface}send "{channel}" {message}' + + def Serialize(self): + return { + 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), + 'channel' : self.chatCommandGlobalChannel.GetValue(), + 'message' : self.chatCommandGlobalMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) + if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) + if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) + +#######Costume Change +class CostumeChangeCmd(PowerBindCmd): + def BuildUI(self, dialog): + costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeCostume = wx.Choice(dialog, -1, + choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) + self.costumeChangeCostume.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeEmote = wx.Choice(dialog, -1, + choices = GameData.Emotes['costumechange']) + self.costumeChangeEmote.Insert("- None -", 0) + self.costumeChangeEmote.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return costumeChangeSizer + + def MakeBindString(self): + costumeNumber = self.costumeChangeCostume.GetSelection() + costumeEmote = self.costumeChangeEmote.GetSelection() + + if costumeEmote: # None, or 0 == "- None -" + ccCmd = 'cce' + emoteName = self.costumeChangeEmote.GetString(costumeEmote) + emoteName = " CC" + emoteName.replace(" ","") + else: + ccCmd = 'cc' + emoteName = '' + + return f"{ccCmd} {costumeNumber}{emoteName}" + + def Serialize(self): + return{ + 'costumeNumber': self.costumeChangeCostume.GetSelection(), + 'costumeEmote' : self.costumeChangeEmote.GetSelection(), + } + + def Deserialize(self, init): + if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) + if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) + +####### Movement Command +class MovementCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + self.plusbutton.SetValue(True) + + self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.commandchoice = wx.Choice(dialog, choices = [ + "forward", "left", "right", "backward", "up", "down", + "turnleft", "turnright", "first", "autorun", "clicktomove", + ],) + sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) + self.commandchoice.SetSelection(0) + + self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + pre = post = '' + if self.plusbutton.GetValue() : pre = "+" + elif self.plusplusbutton.GetValue() : pre = "++" + elif self.minusbutton.GetValue() : pre = "-" + elif self.zerobutton.GetValue() : post = " 0" + elif self.onebutton.GetValue() : post = " 1" + + command = self.commandchoice.GetString(self.commandchoice.GetSelection()) + + return f"{pre}{command}{post}" + + def Serialize(self): + mod = '' + if self.plusbutton.GetValue() : mod = "plus" + elif self.plusplusbutton.GetValue() : mod = "plusplus" + elif self.minusbutton.GetValue() : mod = "minus" + elif self.zerobutton.GetValue() : mod = "zero" + elif self.onebutton.GetValue() : mod = "one" + + return { + 'mod' : mod, + 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), + } + + def Deserialize(self, init): + mod = init.get('mod', 'plus') + + if mod == 'plus' : self.plusbutton.SetValue(True) + elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) + elif mod == 'minus' : self.minusbutton.SetValue(True) + elif mod == 'zero' : self.zerobutton.SetValue(True) + elif mod == 'one' : self.onebutton.SetValue(True) + + self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) + +####### Graphics Command +class GraphicsCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.FlexGridSizer(2) + + self.visscalecb = wx.CheckBox(dialog, label = "visscale") + sizer.Add(self.visscalecb) + self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) + sizer.Add(self.visscalesc) + + self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") + sizer.Add(self.dofweightcb) + self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) + sizer.Add(self.dofweightsc) + + self.fsaacb = wx.CheckBox(dialog, label = "fsaa") + sizer.Add(self.fsaacb) + self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) + self.fsaach.SetSelection(0) + sizer.Add(self.fsaach) + + self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") + sizer.Add(self.bloomscalecb) + self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) + self.bloomscalech.SetSelection(0) + sizer.Add(self.bloomscalech) + + self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") + sizer.Add(self.bloomweightcb) + self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) + sizer.Add(self.bloomweightsc) + + self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") + sizer.Add(self.lodbiascb) + self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) + sizer.Add(self.lodbiassc) + + self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") + sizer.Add(self.renderscalecb) + self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) + sizer.Add(self.renderscalesc) + + return sizer + + def MakeBindString(self): + # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. + bindstrings = [] + if self.visscalecb.IsChecked(): + bindstrings.append("visscale " + str(self.visscalesc.GetValue())) + if self.dofweightcb.IsChecked(): + bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) + if self.fsaacb.IsChecked(): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bindstrings.append("fsaa " + fsaavalue) + if self.bloomscalecb.IsChecked(): + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + bindstrings.append("bloomscale " + bloomscalevalue) + if self.bloomweightcb.IsChecked(): + bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) + if self.lodbiascb.IsChecked(): + bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) + if self.renderscalecb.IsChecked(): + bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) + + return '$$'.join(bindstrings) + + def Serialize(self): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + return { + 'visscalecb' : self.visscalecb.IsChecked(), + 'visscalesc' : self.visscalesc.GetValue(), + 'dofweightcb' : self.dofweightcb.IsChecked(), + 'dofweightsc' : self.dofweightsc.GetValue(), + 'fsaacb' : self.fsaacb.IsChecked(), + 'fsaach' : fsaavalue, + 'bloomscalecb' : self.bloomscalecb.IsChecked(), + 'bloomscalech' : bloomscalevalue, + 'bloomweightcb' : self.bloomweightcb.IsChecked(), + 'bloomweightsc' : self.bloomweightsc.GetValue(), + 'lodbiascb' : self.lodbiascb.IsChecked(), + 'lodbiassc' : self.lodbiassc.GetValue(), + 'renderscalecb' : self.renderscalecb.IsChecked(), + 'renderscalesc' : self.renderscalesc.GetValue(), + } + + def Deserialize(self, init): + self.visscalecb.SetValue(init.get('visscalecb', False)) + self.visscalesc.SetValue(init.get('visscalesc', 1.0)) + self.dofweightcb.SetValue(init.get('dofweightcb', False)) + self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) + self.fsaacb.SetValue(init.get('fsaacb', False)) + self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) + self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) + self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) + self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) + self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) + self.lodbiascb.SetValue(init.get('lodbiascb', False)) + self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) + self.renderscalecb.SetValue(init.get('renderscalecb', False)) + self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) + +####### Custom Bind +class CustomBindCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.customBindName = wx.TextCtrl(dialog, -1) + self.customBindName.SetHint('Custom Bind Text') + sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + return self.customBindName.GetValue() + + def Serialize(self): + return { 'customBindName': self.customBindName.GetValue() } + + def Deserialize(self,init): + if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) + +####### Emote +class EmoteCmd(PowerBindCmd): + def BuildUI(self, dialog): + emoteSizer = wx.BoxSizer(wx.HORIZONTAL) + self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") + emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + self.emoteName = wx.Button(dialog, -1, "...") + self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) + emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) + + return emoteSizer + + def MakeBindString(self): + displayedEmoteName = self.emoteName.GetLabel() + actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] + + return actualEmotePayload + + def Serialize(self): + return {'emoteName': self.emoteName.GetLabel()} + + def Deserialize(self, init): + if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) + +####### Load Binds Directory +class LoadBindsDir(PowerBindCmd): + def BuildUI(self, dialog): + mainSizer = wx.BoxSizer(wx.VERTICAL) + + lbSizer = wx.BoxSizer(wx.HORIZONTAL) + lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") + lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + profiles = Profile.GetAllProfileBindsDirs() + + self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) + lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") + self.lbResetCB.SetValue(True) + + mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + return mainSizer + + def MakeBindString(self): + + # If the specified binds directory disappeared between runs, we'd crash, so handle that. + if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' + + config = wx.ConfigBase.Get() + if config.Exists('GameBindPath'): + bindpath = config.Read('GameBindPath') + else: + bindpath = config.Read('BindPath') + + reset = "" + if self.lbResetCB.GetValue(): + reset = "keybind_reset$$" + + resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' + return reset + 'bindloadfile ' + str(resetfilepath) + + def Serialize(self): + return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), + 'ResetKeybinds' : self.lbResetCB.GetValue(), + } + + def Deserialize(self, init): + if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) + self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) + +####### Power Abort +class PowerAbortCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecabort' + +####### Power Unqueue +class PowerUnqueueCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecunqueue' + +####### SG Mode +class SGModeCmd(PowerBindCmd): + def BuildUI(self, dialog): + sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) + sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") + self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") + + sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) + + return sgmodeSizer + + def MakeBindString(self): + if self.sgmodeOnRB.GetValue(): + return 'sgmodeset 1' + elif self.sgmodeOffRB.GetValue(): + return 'sgmodeset 0' + else: + return 'sgmode' + + def Serialize(self): + if self.sgmodeOnRB.GetValue(): + val = "On" + elif self.sgmodeOffRB.GetValue(): + val = "Off" + else: + val = "Toggle" + + return {"value" : val} + + def Deserialize(self, init): + val = init.get('value', '') + if val == "On": + self.sgmodeOnRB.SetValue(True) + elif val == "Off": + self.sgmodeOffRB.SetValue(True) + else: + self.sgmodeToggleRB.SetValue(True) + +####### Target Custom +class TargetCustomCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetCustomSizer = wx.GridBagSizer(5,5) + targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), + flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) + self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetCustomModeChoice.SetSelection(0) + targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) + self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) + self.targetCustomOptionalName.SetHint("Optional name to match") + targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) + self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") + targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) + self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") + targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) + self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") + targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) + self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") + targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) + self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") + targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) + self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") + targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) + self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") + targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) + self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") + targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) + + targetCustomSizer.AddGrowableCol(2) + + return targetCustomSizer + + def MakeBindString(self): + choice = self.targetCustomModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + targetCommand = "targetcustom" + mode.lower() + + enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" + friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" + defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" + alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" + mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" + notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" + base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" + notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" + + name = self.targetCustomOptionalName.GetValue() + + return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" + + def Serialize(self): + return { + 'mode' : self.targetCustomModeChoice.GetSelection(), + 'enemy' : self.targetCustomCBEnemies. IsChecked(), + 'friend' : self.targetCustomCBFriends. IsChecked(), + 'defeated' : self.targetCustomCBDefeated. IsChecked(), + 'alive' : self.targetCustomCBAlive. IsChecked(), + 'mypet' : self.targetCustomCBMyPets. IsChecked(), + 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), + 'base' : self.targetCustomCBBaseItems. IsChecked(), + 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), + 'name' : self.targetCustomOptionalName.GetValue(), + } + + def Deserialize(self, init): + if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) + if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) + if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) + if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) + if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) + if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) + if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) + if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) + if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) + if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) + + +####### Target Enemy +class TargetEnemyCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) + targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetEnemyModeChoice.SetSelection(0) + targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetEnemySizer + + def MakeBindString(self): + choice = self.targetEnemyModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetenemy" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetEnemyModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) + +####### Target Friend +class TargetFriendCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) + targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetFriendModeChoice.SetSelection(0) + targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetFriendSizer + + def MakeBindString(self): + choice = self.targetFriendModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetfriend" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetFriendModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) + +####### Team/Pet Select +class TeamPetSelectCmd(PowerBindCmd): + def BuildUI(self, dialog): + teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], + style=wx.ALIGN_CENTER_VERTICAL) + self.teamPetSelectNumber.SetSelection(0) + teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) + + return teamPetSelectSizer + + def MakeBindString(self): + teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' + targetNumber = self.teamPetSelectNumber.GetSelection()+1 + + return f"{teamOrPet}select {targetNumber}" + + def Serialize(self): + return { + 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', + 'targetNum': self.teamPetSelectNumber.GetSelection(), + } + + def Deserialize(self, init): + ToP = init.get('teamOrPet', '') + if ToP == 'pet': + self.teamPetSelectPetRB.SetValue(True) + else: + self.teamPetSelectTeamRB.SetValue(True) + if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) + +####### Unselect +class UnselectCmd(PowerBindCmd): + def MakeBindString(self): + return 'unselect' + +####### Use Insp By Name +class UseInspByNameCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) + for _, types in GameData.Inspirations.items(): + for _, info in types.items(): + for insp in info['tiers']: + name = re.sub(' ', '', str(insp)) + icon = GetIcon(f'Inspirations/{name}') + self.useInspByNameModeChoice.Append(insp, icon) + self.useInspByNameModeChoice.SetSelection(0) + useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) + + return useInspByNameSizer + + def MakeBindString(self): + choice = self.useInspByNameModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "inspexecname " + mode.lower() + + def GetAllInsps(self): + Insplist = [] + for _, info in GameData.Inspirations.items(): + for insp in info['tiers']: + Insplist.append(insp) + Insplist.append("---") + Insplist.pop(-1) # snip the terminal "---" + + return Insplist + + def Serialize(self): + return { 'insp' : self.useInspByNameModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) + +####### Use Insp From Row / Column +class UseInspRowColCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnRow.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) + self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnCol.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) + + return useInspRowColumnSizer + + def MakeBindString(self): + row = self.useInspRowColumnRow.GetSelection()+1 + col = self.useInspRowColumnCol.GetSelection()+1 + + return f"inspexectray {col} {row}" + + def Serialize(self): + return { + 'col' : self.useInspRowColumnCol.GetSelection(), + 'row' : self.useInspRowColumnRow.GetSelection(), + } + + def Deserialize(self, init): + if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) + if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) + +####### Use Power +class UsePowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + outerSizer = wx.BoxSizer(wx.HORIZONTAL) + + usePowerSizer = wx.GridBagSizer(5,5) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBToggle, (0,1)) + self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOn, (0,2)) + self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOff, (0,3)) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerName = PowerPicker(dialog) + usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) + usePowerSizer.AddGrowableCol(3) + + outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) + + return outerSizer + + def MakeBindString(self): + if self.usePowerRBToggle.GetValue(): + method = "powexecname" + elif self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') + return '' + + return f"{method} {self.usePowerName.GetLabel()}" + + def Serialize(self): + if self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + method = "powexecname" + return { + 'method': method, + 'pname' : self.usePowerName.GetLabel(), + 'picon' : self.usePowerName.IconFilename + } + + def Deserialize(self, init): + method = init.get('method', '') + if method == 'powexectoggleon': + self.usePowerRBOn.SetValue(True) + elif method == 'powexectoggleoff': + self.usePowerRBOff.SetValue(True) + else: + self.usePowerRBToggle.SetValue(True) + if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) + +####### Use Power From Tray +class UsePowerFromTrayCmd(PowerBindCmd): + def BuildUI(self, dialog): + usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTrayTray = wx.Choice(dialog, -1, + choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', + 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) + self.usePowerFromTrayTray.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) + self.usePowerFromTraySlot.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return usePowerFromTraySizer + + def MakeBindString(self): + choice = self.usePowerFromTrayTray + tray = choice.GetSelection() + + choice = self.usePowerFromTraySlot + slot = choice.GetSelection()+1 + + mode = "slot" + mode2 = '' + if tray > 3: + mode = "tray" + mode2 = f" {tray - 3}" + elif tray == 3: + mode = "alt2slot" + elif tray == 2: + mode = "altslot" + + return f"powexec{mode} {slot}{mode2}" + + def Serialize(self): + return { + 'tray' : self.usePowerFromTrayTray.GetSelection(), + 'slot' : self.usePowerFromTraySlot.GetSelection(), + } + + def Deserialize(self, init): + if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) + if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) + +####### Window Color +class WindowColorCmd(PowerBindCmd): + def BuildUI(self, dialog): + windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) + borderSizer = wx.BoxSizer(wx.VERTICAL) + self.ColorBorder.SetSizer(borderSizer) + self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) + borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) + + windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) + + RGBASizer = wx.FlexGridSizer(3, 4, 5) + + RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) + self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) + self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + windowColorSizer.Add(RGBASizer) + + self.UpdateFromSlider() + + return windowColorSizer + + def MakeBindString(self): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + return f"windowcolor {Rval} {Gval} {Bval} {Aval}" + + def Serialize(self): + return { + 'Rval' : self.RSlider.GetValue(), + 'Gval' : self.GSlider.GetValue(), + 'Bval' : self.BSlider.GetValue(), + 'Aval' : self.ASlider.GetValue(), + } + + def Deserialize(self, init): + self.RSlider.SetValue(init['Rval']) + self.GSlider.SetValue(init['Gval']) + self.BSlider.SetValue(init['Bval']) + self.ASlider.SetValue(init['Aval']) + self.UpdateFromSlider() + + def UpdateFromSlider(self, _ = None): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RReadout.SetValue(Rval) + self.GReadout.SetValue(Gval) + self.BReadout.SetValue(Bval) + self.AReadout.SetValue(Aval) + self.ColorBorder.Refresh() + + def UpdateFromText(self, _ = None): + Rval = self.RReadout.GetValue() + Gval = self.GReadout.GetValue() + Bval = self.BReadout.GetValue() + Aval = self.AReadout.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RSlider.SetValue(Rval) + self.GSlider.SetValue(Gval) + self.BSlider.SetValue(Bval) + self.ASlider.SetValue(Aval) + self.ColorBorder.Refresh() + +####### Window Save / Load +class WindowSaveLoadCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) + self.CommandChoice.SetSelection(0) + sizer.Add(self.CommandChoice, 0, wx.ALL, 5) + + self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), + value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) + sizer.Add(self.FilePath, 0, wx.ALL, 5) + + return sizer + + def MakeBindString(self): + command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] + return f'{command} "{self.FilePath.GetValue()}"' + + def Serialize(self): + return { + 'command' : self.CommandChoice.GetSelection(), + 'filename' : self.FilePath.GetValue(), + } + + def Deserialize(self, init): + self.CommandChoice.SetSelection(init.get('command', 0)) + self.FilePath.SetValue(init.get('filename', '')) + +####### Window Toggle +class WindowToggleCmd(PowerBindCmd): + def BuildUI(self, dialog): + self.WindowNames = { + 'Actions' : 'actions', + 'Auction House' : 'ah', + 'Badge' : 'badge', + 'Channel Search' : 'chansearch', + 'Chat' : 'chat', + 'Custom Chat 1' : 'chat1', + 'Custom Chat 2' : 'chat2', + 'Custom Chat 3' : 'chat3', + 'Custom Chat 4' : 'chat4', + 'Clues' : 'clue', + 'Combat Numbers' : 'combatnumbers', + 'Contacts' : 'contact', + 'Contact Finder' : 'contactfinder', + 'Costumes' : 'costume', + 'Email' : 'email', + 'Enhancements' : 'enhancements', + 'Friends' : 'friend', + 'Group' : 'group', + 'Help' : 'helpwindow', + 'Incarnate' : 'incarnate', + 'Inspirations' : 'insp', + 'League' : 'league', + 'LFG' : 'lfg', + 'Map' : 'map', + 'Mission' : 'mission', + 'Nav / Compass' : 'nav', + 'Options' : 'options', + 'Pets' : 'pet', + 'Petition' : 'petition', + 'Power Tray' : 'powers', + 'Power List' : 'powerlist', + 'Quit' : 'quit', + 'Recipes' : 'recipe', + 'Salvage' : 'salvage', + 'Search' : 'search', + 'Supergroup' : 'sg', + 'Target' : 'target', + 'Team' : 'team', + 'Tray' : 'tray', + 'Tray1' : 'tray1', + 'Tray2' : 'tray2', + 'Tray3' : 'tray3', + 'Tray4' : 'tray4', + 'Tray5' : 'tray5', + 'Tray6' : 'tray6', + 'Tray7' : 'tray7', + 'Tray8' : 'tray8', + 'Vault' : 'vault', + } + + self.ShortToggleCommands = { + 'Auction House' : 'ah', + 'Chat' : 'chat', + 'Help' : 'helpwindow', + 'Map' : 'map', + 'Nav / Compass' : 'nav', + 'Power Tray' : 'powers', + 'Target' : 'target', + 'Tray' : 'tray', + } + + windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) + windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) + self.windowToggleTray.SetSelection(0) + windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.windowShowRB = wx.RadioButton(dialog, -1, "Show") + self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") + + windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) + + return windowToggleSizer + + def MakeBindString(self): + choice = self.windowToggleTray + index = choice.GetSelection() + windowdesc = choice.GetString(index) + windowname = self.WindowNames[windowdesc] + + if self.windowShowRB.GetValue(): + return 'show ' + windowname + elif self.windowHideRB.GetValue(): + return 'windowhide ' + windowname + else: + if shortcmd := self.ShortToggleCommands.get(windowdesc, None): + return shortcmd + else: + return 'toggle ' + windowname + + + def Serialize(self): + choice = self.windowToggleTray + if self.windowShowRB.GetValue(): + action = "Show" + elif self.windowHideRB.GetValue(): + action = "Hide" + else: + action = "Toggle" + return { + 'window': choice.GetString(choice.GetSelection()), + 'action': action, + } + + def Deserialize(self, init): + choice = self.windowToggleTray + if window := init.get('window', ''): + if isinstance(window, int): + choice.SetSelection(window) + else: + choice.SetSelection(choice.FindString(window)) + + if choice.GetSelection() == wx.NOT_FOUND: + choice.SetSelection(0) + + action = init.get('action', '') + if action == "Show": + self.windowShowRB.SetValue(True) + elif action == "Hide": + self.windowHideRB.SetValue(True) + else: + self.windowToggleRB.SetValue(True) + + +# Must always add to this list when adding a new command class above +menuStructure = { + 'Graphics / UI' : [ + 'Attribute Monitor', + 'Buff Display Settings', + 'Graphics Settings', + 'Window Color', + 'Window Save / Load', + 'Window Toggle', + ], + 'Inspirations' : [ + 'Use Inspiration By Name', + 'Use Inspiration From Row/Column', + ], + 'Powers' : [ + 'Auto Power', + 'Power Abort', + 'Power Unqueue', + 'Use Power', + 'Use Power From Tray', + ], + 'Social' : [ + 'Away From Keyboard', + 'Chat Command', + 'Chat Command (Global)', + 'Costume Change', + 'Emote', + 'Supergroup Mode', + ], + 'Targeting' : [ + 'Target Custom', + 'Target Enemy', + 'Target Frield', + 'Team/Pet Select', + 'Unselect', + ], + 'Misc' : [ + 'Load Binds Directory', + 'Movement Commands', + ], + # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, + # but I'm leaving it here to remind myself that we do that. + } + +# Must always add to this list when adding a new command class above +commandClasses = { + 'Auto Power' : AutoPowerCmd, + 'Away From Keyboard' : AFKCmd, + 'Attribute Monitor' : AttributeMonitorCmd, + 'Buff Display Settings' : BuffDisplayCmd, + 'Chat Command' : ChatCmd, + 'Chat Command (Global)' : ChatGlobalCmd, + 'Costume Change' : CostumeChangeCmd, + 'Custom Bind' : CustomBindCmd, + 'Emote' : EmoteCmd, + 'Graphics Settings' : GraphicsCmd, + 'Load Binds Directory' : LoadBindsDir, + 'Movement Commands' : MovementCmd, + 'Power Abort' : PowerAbortCmd, + 'Power Unqueue' : PowerUnqueueCmd, + 'Supergroup Mode' : SGModeCmd, + 'Target Custom' : TargetCustomCmd, + 'Target Enemy' : TargetEnemyCmd, + 'Target Friend' : TargetFriendCmd, + 'Team/Pet Select' : TeamPetSelectCmd, + 'Unselect' : UnselectCmd, + 'Use Inspiration By Name' : UseInspByNameCmd, + 'Use Inspiration From Row/Column' : UseInspRowColCmd, + 'Use Power' : UsePowerCmd, + 'Use Power From Tray' : UsePowerFromTrayCmd, + 'Window Color' : WindowColorCmd, + 'Window Save / Load' : WindowSaveLoadCmd, + 'Window Toggle' : WindowToggleCmd, +} +# use these when we rename a commandClass so that old Profiles will still load correctly. +# If we've also updated the class, we need to try to make sure the new class will still +# Deserialize the legacy data, or at least not crash. +deprecatedCommandClasses = { + 'SG Mode Toggle' : SGModeCmd, + 'Use Insp By Name' : UseInspByNameCmd, + 'Use Insp From Row/Column' : UseInspRowColCmd, +} +commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/TargetCustomCmd.py b/UI/PowerBinderCommand/TargetCustomCmd.py new file mode 100644 index 0000000..4c02ab7 --- /dev/null +++ b/UI/PowerBinderCommand/TargetCustomCmd.py @@ -0,0 +1,1800 @@ +import wx +import re +import UI +import UI.EmotePicker +from UI.ControlGroup import ControlGroup +from UI.PowerPicker import PowerPicker +from Help import HelpButton +import wx.adv +from wx.adv import BitmapComboBox, EditableListBox +from pathlib import PureWindowsPath +import GameData +import Profile +from Icon import GetIcon + +class PowerBinderDialog(wx.Dialog): + def __init__(self, parent, button, init = {}): + wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) + + self.Page = parent.Page + self.EditDialog = PowerBinderEditDialog(self) + self.Button = button + self.AddStepMenu = self.makeAddStepMenu() + + sizer = wx.BoxSizer(wx.VERTICAL); + self.mainSizer = sizer + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) + # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) + # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) + #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) + AddStepButton = wx.Button(self, -1, 'Add Step') + AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) + AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) + choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) + choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) + sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) + + rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) + + self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) + self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) + self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) + rearrangeCtrl.Add(self.RearrangeList, 1) + + rearrangeButtons = wx.BoxSizer(wx.VERTICAL) + self.DelButton = wx.Button(self, -1, "Delete") + self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) + self.EditButton = wx.Button(self, -1, "Edit") + self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) + self.EditButton.Disable() + upButton = wx.Button(self, -1, "\u25B2") + upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) + downButton = wx.Button(self, -1, "\u25BC") + downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) + rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) + rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) + + sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.BindStringDisplay = wx.TextCtrl(self, -1) + self.BindStringDisplay.Disable() + choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, + wx.ALIGN_CENTER_VERTICAL) + choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) + + sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) + + sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) + + # need to dig around and get the OK button since we show this dialog modelessly now. + okButton = self.FindWindow(self.GetAffirmativeId()) + okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) + + # Wrap everything in a vbox to add some padding + vbox = wx.BoxSizer(wx.VERTICAL); + vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); + + self.SetSizerAndFit(vbox); + self.Layout() + self.Fit() + self.SetFocus() + + # if we are loading from profile, ie, have "init", build the list from it + if init: self.LoadFromData(init) + + def LoadFromData(self, init): + for item in init: + for type, data in item.items(): + commandClass = commandClasses.get(type, None) + if not commandClass: + commandClass = deprecatedCommandClasses.get(type, None) + if not commandClass: + wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") + continue + newCommand = commandClass(self.EditDialog, data) + index = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.SetClientData(index, newCommand) + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) + self.EditDialog.mainSizer.Hide(newCommand.UI) + self.UpdateBindStringDisplay() + + def SaveToData(self): + data = [] + index = 0 + for _ in self.RearrangeList.GetItems(): + # check whether we have an object already attached to this choice + cmdObject = self.RearrangeList.GetClientData(index) + commandClassName = commandRevClasses[type(cmdObject)] + data.append({commandClassName: cmdObject.Serialize()}) + index = index + 1 + return data + + def OnAddStepButton(self, evt): + button = evt.EventObject + if not self.AddStepMenu: + self.AddStepMenu = self.makeAddStepMenu() + button.PopupMenu(self.AddStepMenu) + + + def OnOKButton(self, _): + if self.Button.tgtTxtCtrl: + bindString = self.MakeBindString() + if bindString != self.Button.tgtTxtCtrl.GetValue(): + self.Button.tgtTxtCtrl.SetValue(bindString) + wx.App.Get().Main.Profile.SetModified() + self.Close() + + def OnRearrangeDelete(self, _): + current = self.RearrangeList.GetSelection() + if current == wx.NOT_FOUND: return + + self.RearrangeList.Delete(current) + self.UpdateBindStringDisplay() + + def OnRearrangeUp(self, _): + self.RearrangeList.MoveCurrentUp() + self.UpdateBindStringDisplay() + + def OnRearrangeDown(self, _): + self.RearrangeList.MoveCurrentDown() + self.UpdateBindStringDisplay() + + def OnRearrangeEdit(self, _): + index = self.RearrangeList.GetSelection() + + # check whether we have an object already attached to this choice + cmdObject = None + try: + cmdObject = self.RearrangeList.GetClientData(index) + except Exception: + pass + + if cmdObject: + self.ShowEditDialogFor(cmdObject) + self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) + else: + print("cmdObject was None") + self.UpdateBindStringDisplay() + + # OnAddStepMenu creates a new step and adds it to the rearrangelist + def OnAddStepMenu(self, evt): + menuitem = self.AddStepMenu.FindItemById(evt.GetId()) + chosenName = menuitem.GetItemLabel() + + # make a new command object, attached to the parent dialog + newCommandClass = commandClasses[chosenName] + newCommand = newCommandClass(self.EditDialog) + + # show the edit dialog if this command needs it + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) + if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): + self.EditDialog.mainSizer.Remove(newCommand.UI) + return + + newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.Select(newBindIndex) + self.RearrangeList.SetClientData(newBindIndex, newCommand) + + self.OnListSelect() + self.UpdateBindStringDisplay() + + def OnListSelect(self, _ = None): + selected = self.RearrangeList.GetSelection() + + if selected != wx.NOT_FOUND: + selCommand = self.RearrangeList.GetClientData(selected) + if selCommand.UI: + self.EditButton.Enable() + else: + self.EditButton.Disable() + + def UpdateBindStringDisplay(self): + self.BindStringDisplay.SetValue(self.MakeBindString()) + self.BindStringDisplay.SetToolTip(self.MakeBindString()) + + def MakeBindString(self): + cmdBindStrings = [] + for index in range(self.RearrangeList.GetCount()): + c = self.RearrangeList.GetClientData(index) + if c: cmdBindStrings.append(c.MakeBindString()) + + bindstring = ('$$'.join(cmdBindStrings)) + return bindstring + + def ShowEditDialogFor(self, command): + if not command.UI: return + + self.EditDialog.mainSizer.Show(command.UI) + + self.EditDialog.Layout() + self.EditDialog.Fit() + + self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') + returnval = self.EditDialog.ShowModal() + + self.EditDialog.mainSizer.Hide(command.UI) + + return returnval + + def makeAddStepMenu(self): + + stepMenu = wx.Menu() + + for subname in menuStructure: + submenu = wx.Menu() + stepMenu.AppendSubMenu(submenu, subname) + for classname in menuStructure[subname]: + submenu.Append(wx.ID_ANY, classname) + + stepMenu.Append(wx.ID_ANY, 'Custom Bind') + + return stepMenu + +class PowerBinderButton(wx.BitmapButton): + + def __init__(self, parent, tgtTxtCtrl, init = {}): + wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) + self.Init = init + self.Dialog = None + self.DialogParent = parent + + self.tgtTxtCtrl = tgtTxtCtrl + self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) + self.SetToolTip("Launch PowerBinder") + + def PowerBinderEventHandler(self, _): + self.PowerBinderDialog().Show() + + def LoadFromData(self, data): + self.PowerBinderDialog().LoadFromData(data) + + def SaveToData(self): + return self.PowerBinderDialog().SaveToData() + + def PowerBinderDialog(self): + if not self.Dialog: + self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) + return self.Dialog + + +class PowerBinderEditDialog(wx.Dialog): + def __init__(self, parent): + wx.Dialog.__init__(self, parent, -1, "Edit Step", + style = wx.DEFAULT_DIALOG_STYLE) + + outerSizer = wx.BoxSizer(wx.VERTICAL) + + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + self.mainSizer.SetMinSize([500, 150]) + + self.Page = parent.Page + + self.mainSizer.Add( + self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), + 0, wx.EXPAND|wx.ALL, 10) + + outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) + + self.SetSizerAndFit(outerSizer) + self.Layout() + self.Fit() + +########### Power Binder Command Objects +class PowerBindCmd(): + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + commandClassName = commandRevClasses[type(self)] + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{commandClassName} - {short_bindstr}" + + +####### Away From Keyboard +class AFKCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) + +####### Attribute Monitor +class AttributeMonitorCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.Groups = {} + self.AttributeTable = { + 'Base' : { + 'Current Hit Points' : 'NT H', + 'Max Hit Points' : 'X H', + 'Current Endurance' : 'T E', + 'Max Endurance' : 'X EN', + 'Regeneration Rate' : 'N RAT', + 'Recovery Rate' : 'Y RA', + 'Endurance Consumption' : 'SU', + 'ToHit Bonus' : 'T B', + 'Accuracy Bonus' : 'CC', + 'Last Hit Chance' : 'T C', + 'Damage Bonus' : 'DA', + 'Healing Bonus' : 'NG B', + 'Recharge Time Bonus' : 'ME B', + 'Endurance Discount' : 'CE DIS', + 'Stealth Radius (PvP)' : 'PVP', + 'Stealth Radius (PvE)' : 'PVE', + 'Perception Radius' : 'RC', + 'Range Bonus' : 'GE B', + 'Threat Level' : 'AT L', + 'Experience to Next Level' : 'XT', + 'Experience Debt' : 'XP', + 'Influence / Infamy' : 'INF', + 'Inherent' : 'NH', + }, + 'Movement Speed' : { + 'Flying Speed' : 'FL', + 'Jumping Speed' : 'PI', + 'Max Jump Height' : 'X J', + 'Run Speed' : 'RU', + }, + 'Damage Resistance' : { + 'Smashing Resistance' : 'G R', + 'Lethal Resistance' : 'L R', + 'Fire Resistance' : 'RE R', + 'Cold Resistance' : 'COLD R', + 'Energy Resistance' : 'DamageType[4]', + 'Negative Energy Resistance' : 'GY R', + 'Psyonic Resistance' : 'NIC R', + 'Toxic Resistance' : 'XIC R', + }, + 'Defense' : { + 'Base Defense' : 'BAS', + 'Ranged Defense' : 'ED', + 'Melee Defense' : 'MEL', + 'AoE Defense' : '2', + 'Smashing Defense' : '3', + 'Lethal Defense' : '4', + 'Fire Defense' : '5', + 'Cold Defense' : '6', + 'Energy Defense' : '7', + 'Negative Energy Defense' : '8', + 'Psionic Defense' : '9', + 'Toxic Defense' : '1', + }, + 'Debuff Resistance' : { + 'Regeneration Resistance' : 'ON R', + 'Recovery Resistance' : 'RY R', + 'To Hit Resistance' : 'IT R', + 'Defense Resistance' : 'NSE RES', + }, + 'Status Effect Protection' : { + 'Hold Protection' : 'D P', + 'Immobilize Protection' : 'LIZE P', + 'Stun Protection' : 'N P', + 'Sleep Protection' : 'P P', + 'Knockback Protection' : 'K P', + 'Confuse Protection' : 'SE P', + 'Terrorize Protection' : 'ZE P', + 'Repel Protection' : 'EL P', + 'Teleport Protection' : 'T P', + }, + 'Status Effect Resistance' : { + 'Hold Resistance' : 'D R', + 'Immobilize Resistance' : 'LIZE R', + 'Stun Resistance' : 'N R', + 'Sleep Resistance' : 'P R', + 'Knockback Resistance' : 'K R', + 'Confuse Resistance' : 'SE R', + 'Terrorize Resistance' : 'ZE R', + 'Placate Resistance' : 'TE R', + 'Taunt Resistance' : 'NT R', + }, + 'Miscellaneous' : { + 'Level Shift' : 'L S', + }, + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.AttributeMenu = wx.Menu() + for group, controls in self.AttributeTable.items(): + submenu = wx.Menu() + self.AttributeMenu.AppendSubMenu(submenu, group) + for cb in controls: + submenu.Append(wx.ID_ANY, cb) + + self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) + + self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) + groupSizer.Add(self.editbox) + + newButton = self.editbox.GetNewButton() + newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) + + return groupSizer + + def MakeBindString(self): + map = {} + bindstrings = [] + for _, controls in self.AttributeTable.items(): + for cb, data in controls.items(): + map[cb] = data + + for string in self.editbox.GetStrings(): + if string: + bindstrings.append(f'monitorattribute {map[string]}') + + return '$$'.join(bindstrings) + + def Serialize(self): + return { + 'attributes' : self.editbox.GetStrings() + } + + def Deserialize(self, init): + self.editbox.SetStrings(init.get('attributes', [])) + + def OnNewButton(self, evt): + evt.GetEventObject().PopupMenu(self.AttributeMenu) + + def OnMenuItem(self, evt): + menuitem = evt.EventObject.FindItemById(evt.GetId()) + existingstrings = self.editbox.GetStrings() + existingstrings.append(menuitem.GetItemLabel()) + self.editbox.SetStrings(existingstrings) + +####### Auto Power +class AutoPowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) + autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.autoPowerName = PowerPicker(dialog) + autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) + + return autoPowerSizer + + def MakeBindString(self): + return f"powexecauto {self.autoPowerName.GetLabel()}" + + def Serialize(self): + return { + 'pname' : self.autoPowerName.GetLabel(), + 'picon' : self.autoPowerName.IconFilename + } + + def Deserialize(self, init): + if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) + +####### Buff Display Command +class BuffDisplayCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.buffDisplayMap = { + 'Status Window' : { + 'Hide Auto' : 1, + 'Hide Toggles' : 2, + 'No Blinking' : 4, + 'No Stacking' : 8, + 'Numeric Stacking' : 16, + 'Hide Buff Numbers' : 32, + 'Stop Sending Buffs' : 64, + }, + 'Group Window' : { + 'Hide Auto' : 256, + 'Hide Toggles' : 512, + 'No Blinking' : 1024, + 'No Stacking' : 2048, + 'Numeric Stacking' : 4096, + 'Hide Buff Numbers' : 8192, + 'Stop Sending Buffs' : 16384, + }, + 'Pet Window' : { + 'Hide Auto' : 65536, + 'Hide Toggles' : 131072, + 'No Blinking' : 262144, + 'No Stacking' : 524288, + 'Numeric Stacking' : 1048576, + 'Hide Buff Numbers' : 2097152, + 'Stop Sending Buffs' : 4194304, + }, + } + self.Groups = {} + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + for group, controls in self.buffDisplayMap.items(): + self.Groups[group] = ControlGroup(dialog, self.Page, label = group) + groupid = self.Groups[group].GetStaticBox().GetId() + for cb, data in controls.items(): + self.Groups[group].AddControl( + ctlType = 'checkbox', + ctlName = f"{groupid}_{group}_{cb}", + label = cb, + data = data, + ) + + groupSizer.Add(self.Groups[group]) + + return groupSizer + + def CalculateValue(self): + page = wx.App.Get().Main.Profile.CustomBinds + + total = 0 + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] + if checkbox.IsChecked(): + total = total + checkbox.Data + return total + + def MakeBindString(self): + return f"optionset buffsettings {self.CalculateValue()}" + + def Serialize(self): + return { 'value' : self.CalculateValue() } + + def Deserialize(self, init): + value = init.get('value', 0) + + value = value or 0 # in case we had for some reason 'None' stashed in the init values + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] + checkbox.SetValue( checkbox.Data & value ) + +####### Chat Command +class ChatCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.chatChannelMap = { # before __init__ + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + chatCommandSizer = wx.GridBagSizer(5, 5) + self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") + chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) + # row 1 + self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) + self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) + self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) + # row 2 + self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) + self.chatCommandDuration.SetRange(1, 20) + self.chatCommandDuration.SetValue(7) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandDuration, (2,1)) + self.chatCommandChatSize = wx.Choice(dialog, -1, + choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) + self.chatCommandChatSize.SetSelection(5) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) + self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) + self.chatCommandChannel.SetSelection(0) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChannel, (2,5)) + # row 3 + self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") + chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) + self.chatCommandMessage = wx.TextCtrl(dialog, -1) + self.chatCommandMessage.SetHint('Chat Command Text') + chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) + + return chatCommandSizer + + def MakeBindString(self): + duration = self.chatCommandDuration.GetValue() + + choice = self.chatCommandChatSize + index = choice.GetSelection() + size = choice.GetString(index) + + duration = f"" if duration != 7 else "" + size = f"" if size != "1" else "" + + bdcolor = fgcolor = bgcolor = '' + if self.chatCommandUseColorsCB.IsChecked(): + bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + + bdcolor = f"" + fgcolor = f"" + bgcolor = f"" + + beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' + text = self.chatCommandMessage.GetValue() + + choice = self.chatCommandChannel + index = choice.GetSelection() + channel = choice.GetString(index) + + return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" + + def Serialize(self): + return { + 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), + 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), + 'channel' : self.chatCommandChannel .GetSelection(), + 'size' : self.chatCommandChatSize.GetSelection(), + 'duration' : self.chatCommandDuration.GetValue(), + 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'text' : self.chatCommandMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) + if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) + if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) + if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) + if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) + if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) + if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) + if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) + if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) + + +####### Chat Command Global +class ChatGlobalCmd(PowerBindCmd): + def BuildUI(self, dialog): + chatCommandGlobalSizer = wx.GridBagSizer(5,5) + + self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") + chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) + + self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalChannel.SetHint("Channel") + chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) + + self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') + chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) + + chatCommandGlobalSizer.AddGrowableCol(1) + + return chatCommandGlobalSizer + + def MakeBindString(self): + useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() + channel = self.chatCommandGlobalChannel.GetValue() + message = self.chatCommandGlobalMessage.GetValue() + + preface = "beginchat /" if useBeginchat else "" + + return f'{preface}send "{channel}" {message}' + + def Serialize(self): + return { + 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), + 'channel' : self.chatCommandGlobalChannel.GetValue(), + 'message' : self.chatCommandGlobalMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) + if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) + if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) + +#######Costume Change +class CostumeChangeCmd(PowerBindCmd): + def BuildUI(self, dialog): + costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeCostume = wx.Choice(dialog, -1, + choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) + self.costumeChangeCostume.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeEmote = wx.Choice(dialog, -1, + choices = GameData.Emotes['costumechange']) + self.costumeChangeEmote.Insert("- None -", 0) + self.costumeChangeEmote.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return costumeChangeSizer + + def MakeBindString(self): + costumeNumber = self.costumeChangeCostume.GetSelection() + costumeEmote = self.costumeChangeEmote.GetSelection() + + if costumeEmote: # None, or 0 == "- None -" + ccCmd = 'cce' + emoteName = self.costumeChangeEmote.GetString(costumeEmote) + emoteName = " CC" + emoteName.replace(" ","") + else: + ccCmd = 'cc' + emoteName = '' + + return f"{ccCmd} {costumeNumber}{emoteName}" + + def Serialize(self): + return{ + 'costumeNumber': self.costumeChangeCostume.GetSelection(), + 'costumeEmote' : self.costumeChangeEmote.GetSelection(), + } + + def Deserialize(self, init): + if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) + if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) + +####### Movement Command +class MovementCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + self.plusbutton.SetValue(True) + + self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.commandchoice = wx.Choice(dialog, choices = [ + "forward", "left", "right", "backward", "up", "down", + "turnleft", "turnright", "first", "autorun", "clicktomove", + ],) + sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) + self.commandchoice.SetSelection(0) + + self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + pre = post = '' + if self.plusbutton.GetValue() : pre = "+" + elif self.plusplusbutton.GetValue() : pre = "++" + elif self.minusbutton.GetValue() : pre = "-" + elif self.zerobutton.GetValue() : post = " 0" + elif self.onebutton.GetValue() : post = " 1" + + command = self.commandchoice.GetString(self.commandchoice.GetSelection()) + + return f"{pre}{command}{post}" + + def Serialize(self): + mod = '' + if self.plusbutton.GetValue() : mod = "plus" + elif self.plusplusbutton.GetValue() : mod = "plusplus" + elif self.minusbutton.GetValue() : mod = "minus" + elif self.zerobutton.GetValue() : mod = "zero" + elif self.onebutton.GetValue() : mod = "one" + + return { + 'mod' : mod, + 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), + } + + def Deserialize(self, init): + mod = init.get('mod', 'plus') + + if mod == 'plus' : self.plusbutton.SetValue(True) + elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) + elif mod == 'minus' : self.minusbutton.SetValue(True) + elif mod == 'zero' : self.zerobutton.SetValue(True) + elif mod == 'one' : self.onebutton.SetValue(True) + + self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) + +####### Graphics Command +class GraphicsCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.FlexGridSizer(2) + + self.visscalecb = wx.CheckBox(dialog, label = "visscale") + sizer.Add(self.visscalecb) + self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) + sizer.Add(self.visscalesc) + + self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") + sizer.Add(self.dofweightcb) + self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) + sizer.Add(self.dofweightsc) + + self.fsaacb = wx.CheckBox(dialog, label = "fsaa") + sizer.Add(self.fsaacb) + self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) + self.fsaach.SetSelection(0) + sizer.Add(self.fsaach) + + self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") + sizer.Add(self.bloomscalecb) + self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) + self.bloomscalech.SetSelection(0) + sizer.Add(self.bloomscalech) + + self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") + sizer.Add(self.bloomweightcb) + self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) + sizer.Add(self.bloomweightsc) + + self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") + sizer.Add(self.lodbiascb) + self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) + sizer.Add(self.lodbiassc) + + self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") + sizer.Add(self.renderscalecb) + self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) + sizer.Add(self.renderscalesc) + + return sizer + + def MakeBindString(self): + # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. + bindstrings = [] + if self.visscalecb.IsChecked(): + bindstrings.append("visscale " + str(self.visscalesc.GetValue())) + if self.dofweightcb.IsChecked(): + bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) + if self.fsaacb.IsChecked(): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bindstrings.append("fsaa " + fsaavalue) + if self.bloomscalecb.IsChecked(): + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + bindstrings.append("bloomscale " + bloomscalevalue) + if self.bloomweightcb.IsChecked(): + bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) + if self.lodbiascb.IsChecked(): + bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) + if self.renderscalecb.IsChecked(): + bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) + + return '$$'.join(bindstrings) + + def Serialize(self): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + return { + 'visscalecb' : self.visscalecb.IsChecked(), + 'visscalesc' : self.visscalesc.GetValue(), + 'dofweightcb' : self.dofweightcb.IsChecked(), + 'dofweightsc' : self.dofweightsc.GetValue(), + 'fsaacb' : self.fsaacb.IsChecked(), + 'fsaach' : fsaavalue, + 'bloomscalecb' : self.bloomscalecb.IsChecked(), + 'bloomscalech' : bloomscalevalue, + 'bloomweightcb' : self.bloomweightcb.IsChecked(), + 'bloomweightsc' : self.bloomweightsc.GetValue(), + 'lodbiascb' : self.lodbiascb.IsChecked(), + 'lodbiassc' : self.lodbiassc.GetValue(), + 'renderscalecb' : self.renderscalecb.IsChecked(), + 'renderscalesc' : self.renderscalesc.GetValue(), + } + + def Deserialize(self, init): + self.visscalecb.SetValue(init.get('visscalecb', False)) + self.visscalesc.SetValue(init.get('visscalesc', 1.0)) + self.dofweightcb.SetValue(init.get('dofweightcb', False)) + self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) + self.fsaacb.SetValue(init.get('fsaacb', False)) + self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) + self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) + self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) + self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) + self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) + self.lodbiascb.SetValue(init.get('lodbiascb', False)) + self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) + self.renderscalecb.SetValue(init.get('renderscalecb', False)) + self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) + +####### Custom Bind +class CustomBindCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.customBindName = wx.TextCtrl(dialog, -1) + self.customBindName.SetHint('Custom Bind Text') + sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + return self.customBindName.GetValue() + + def Serialize(self): + return { 'customBindName': self.customBindName.GetValue() } + + def Deserialize(self,init): + if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) + +####### Emote +class EmoteCmd(PowerBindCmd): + def BuildUI(self, dialog): + emoteSizer = wx.BoxSizer(wx.HORIZONTAL) + self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") + emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + self.emoteName = wx.Button(dialog, -1, "...") + self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) + emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) + + return emoteSizer + + def MakeBindString(self): + displayedEmoteName = self.emoteName.GetLabel() + actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] + + return actualEmotePayload + + def Serialize(self): + return {'emoteName': self.emoteName.GetLabel()} + + def Deserialize(self, init): + if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) + +####### Load Binds Directory +class LoadBindsDir(PowerBindCmd): + def BuildUI(self, dialog): + mainSizer = wx.BoxSizer(wx.VERTICAL) + + lbSizer = wx.BoxSizer(wx.HORIZONTAL) + lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") + lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + profiles = Profile.GetAllProfileBindsDirs() + + self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) + lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") + self.lbResetCB.SetValue(True) + + mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + return mainSizer + + def MakeBindString(self): + + # If the specified binds directory disappeared between runs, we'd crash, so handle that. + if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' + + config = wx.ConfigBase.Get() + if config.Exists('GameBindPath'): + bindpath = config.Read('GameBindPath') + else: + bindpath = config.Read('BindPath') + + reset = "" + if self.lbResetCB.GetValue(): + reset = "keybind_reset$$" + + resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' + return reset + 'bindloadfile ' + str(resetfilepath) + + def Serialize(self): + return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), + 'ResetKeybinds' : self.lbResetCB.GetValue(), + } + + def Deserialize(self, init): + if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) + self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) + +####### Power Abort +class PowerAbortCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecabort' + +####### Power Unqueue +class PowerUnqueueCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecunqueue' + +####### SG Mode +class SGModeCmd(PowerBindCmd): + def BuildUI(self, dialog): + sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) + sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") + self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") + + sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) + + return sgmodeSizer + + def MakeBindString(self): + if self.sgmodeOnRB.GetValue(): + return 'sgmodeset 1' + elif self.sgmodeOffRB.GetValue(): + return 'sgmodeset 0' + else: + return 'sgmode' + + def Serialize(self): + if self.sgmodeOnRB.GetValue(): + val = "On" + elif self.sgmodeOffRB.GetValue(): + val = "Off" + else: + val = "Toggle" + + return {"value" : val} + + def Deserialize(self, init): + val = init.get('value', '') + if val == "On": + self.sgmodeOnRB.SetValue(True) + elif val == "Off": + self.sgmodeOffRB.SetValue(True) + else: + self.sgmodeToggleRB.SetValue(True) + +####### Target Custom +class TargetCustomCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetCustomSizer = wx.GridBagSizer(5,5) + targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), + flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) + self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetCustomModeChoice.SetSelection(0) + targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) + self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) + self.targetCustomOptionalName.SetHint("Optional name to match") + targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) + self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") + targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) + self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") + targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) + self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") + targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) + self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") + targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) + self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") + targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) + self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") + targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) + self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") + targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) + self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") + targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) + + targetCustomSizer.AddGrowableCol(2) + + return targetCustomSizer + + def MakeBindString(self): + choice = self.targetCustomModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + targetCommand = "targetcustom" + mode.lower() + + enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" + friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" + defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" + alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" + mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" + notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" + base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" + notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" + + name = self.targetCustomOptionalName.GetValue() + + return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" + + def Serialize(self): + return { + 'mode' : self.targetCustomModeChoice.GetSelection(), + 'enemy' : self.targetCustomCBEnemies. IsChecked(), + 'friend' : self.targetCustomCBFriends. IsChecked(), + 'defeated' : self.targetCustomCBDefeated. IsChecked(), + 'alive' : self.targetCustomCBAlive. IsChecked(), + 'mypet' : self.targetCustomCBMyPets. IsChecked(), + 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), + 'base' : self.targetCustomCBBaseItems. IsChecked(), + 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), + 'name' : self.targetCustomOptionalName.GetValue(), + } + + def Deserialize(self, init): + if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) + if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) + if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) + if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) + if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) + if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) + if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) + if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) + if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) + if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) + + +####### Target Enemy +class TargetEnemyCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) + targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetEnemyModeChoice.SetSelection(0) + targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetEnemySizer + + def MakeBindString(self): + choice = self.targetEnemyModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetenemy" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetEnemyModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) + +####### Target Friend +class TargetFriendCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) + targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetFriendModeChoice.SetSelection(0) + targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetFriendSizer + + def MakeBindString(self): + choice = self.targetFriendModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetfriend" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetFriendModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) + +####### Team/Pet Select +class TeamPetSelectCmd(PowerBindCmd): + def BuildUI(self, dialog): + teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], + style=wx.ALIGN_CENTER_VERTICAL) + self.teamPetSelectNumber.SetSelection(0) + teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) + + return teamPetSelectSizer + + def MakeBindString(self): + teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' + targetNumber = self.teamPetSelectNumber.GetSelection()+1 + + return f"{teamOrPet}select {targetNumber}" + + def Serialize(self): + return { + 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', + 'targetNum': self.teamPetSelectNumber.GetSelection(), + } + + def Deserialize(self, init): + ToP = init.get('teamOrPet', '') + if ToP == 'pet': + self.teamPetSelectPetRB.SetValue(True) + else: + self.teamPetSelectTeamRB.SetValue(True) + if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) + +####### Unselect +class UnselectCmd(PowerBindCmd): + def MakeBindString(self): + return 'unselect' + +####### Use Insp By Name +class UseInspByNameCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) + for _, types in GameData.Inspirations.items(): + for _, info in types.items(): + for insp in info['tiers']: + name = re.sub(' ', '', str(insp)) + icon = GetIcon(f'Inspirations/{name}') + self.useInspByNameModeChoice.Append(insp, icon) + self.useInspByNameModeChoice.SetSelection(0) + useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) + + return useInspByNameSizer + + def MakeBindString(self): + choice = self.useInspByNameModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "inspexecname " + mode.lower() + + def GetAllInsps(self): + Insplist = [] + for _, info in GameData.Inspirations.items(): + for insp in info['tiers']: + Insplist.append(insp) + Insplist.append("---") + Insplist.pop(-1) # snip the terminal "---" + + return Insplist + + def Serialize(self): + return { 'insp' : self.useInspByNameModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) + +####### Use Insp From Row / Column +class UseInspRowColCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnRow.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) + self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnCol.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) + + return useInspRowColumnSizer + + def MakeBindString(self): + row = self.useInspRowColumnRow.GetSelection()+1 + col = self.useInspRowColumnCol.GetSelection()+1 + + return f"inspexectray {col} {row}" + + def Serialize(self): + return { + 'col' : self.useInspRowColumnCol.GetSelection(), + 'row' : self.useInspRowColumnRow.GetSelection(), + } + + def Deserialize(self, init): + if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) + if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) + +####### Use Power +class UsePowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + outerSizer = wx.BoxSizer(wx.HORIZONTAL) + + usePowerSizer = wx.GridBagSizer(5,5) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBToggle, (0,1)) + self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOn, (0,2)) + self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOff, (0,3)) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerName = PowerPicker(dialog) + usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) + usePowerSizer.AddGrowableCol(3) + + outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) + + return outerSizer + + def MakeBindString(self): + if self.usePowerRBToggle.GetValue(): + method = "powexecname" + elif self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') + return '' + + return f"{method} {self.usePowerName.GetLabel()}" + + def Serialize(self): + if self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + method = "powexecname" + return { + 'method': method, + 'pname' : self.usePowerName.GetLabel(), + 'picon' : self.usePowerName.IconFilename + } + + def Deserialize(self, init): + method = init.get('method', '') + if method == 'powexectoggleon': + self.usePowerRBOn.SetValue(True) + elif method == 'powexectoggleoff': + self.usePowerRBOff.SetValue(True) + else: + self.usePowerRBToggle.SetValue(True) + if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) + +####### Use Power From Tray +class UsePowerFromTrayCmd(PowerBindCmd): + def BuildUI(self, dialog): + usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTrayTray = wx.Choice(dialog, -1, + choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', + 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) + self.usePowerFromTrayTray.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) + self.usePowerFromTraySlot.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return usePowerFromTraySizer + + def MakeBindString(self): + choice = self.usePowerFromTrayTray + tray = choice.GetSelection() + + choice = self.usePowerFromTraySlot + slot = choice.GetSelection()+1 + + mode = "slot" + mode2 = '' + if tray > 3: + mode = "tray" + mode2 = f" {tray - 3}" + elif tray == 3: + mode = "alt2slot" + elif tray == 2: + mode = "altslot" + + return f"powexec{mode} {slot}{mode2}" + + def Serialize(self): + return { + 'tray' : self.usePowerFromTrayTray.GetSelection(), + 'slot' : self.usePowerFromTraySlot.GetSelection(), + } + + def Deserialize(self, init): + if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) + if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) + +####### Window Color +class WindowColorCmd(PowerBindCmd): + def BuildUI(self, dialog): + windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) + borderSizer = wx.BoxSizer(wx.VERTICAL) + self.ColorBorder.SetSizer(borderSizer) + self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) + borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) + + windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) + + RGBASizer = wx.FlexGridSizer(3, 4, 5) + + RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) + self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) + self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + windowColorSizer.Add(RGBASizer) + + self.UpdateFromSlider() + + return windowColorSizer + + def MakeBindString(self): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + return f"windowcolor {Rval} {Gval} {Bval} {Aval}" + + def Serialize(self): + return { + 'Rval' : self.RSlider.GetValue(), + 'Gval' : self.GSlider.GetValue(), + 'Bval' : self.BSlider.GetValue(), + 'Aval' : self.ASlider.GetValue(), + } + + def Deserialize(self, init): + self.RSlider.SetValue(init['Rval']) + self.GSlider.SetValue(init['Gval']) + self.BSlider.SetValue(init['Bval']) + self.ASlider.SetValue(init['Aval']) + self.UpdateFromSlider() + + def UpdateFromSlider(self, _ = None): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RReadout.SetValue(Rval) + self.GReadout.SetValue(Gval) + self.BReadout.SetValue(Bval) + self.AReadout.SetValue(Aval) + self.ColorBorder.Refresh() + + def UpdateFromText(self, _ = None): + Rval = self.RReadout.GetValue() + Gval = self.GReadout.GetValue() + Bval = self.BReadout.GetValue() + Aval = self.AReadout.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RSlider.SetValue(Rval) + self.GSlider.SetValue(Gval) + self.BSlider.SetValue(Bval) + self.ASlider.SetValue(Aval) + self.ColorBorder.Refresh() + +####### Window Save / Load +class WindowSaveLoadCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) + self.CommandChoice.SetSelection(0) + sizer.Add(self.CommandChoice, 0, wx.ALL, 5) + + self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), + value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) + sizer.Add(self.FilePath, 0, wx.ALL, 5) + + return sizer + + def MakeBindString(self): + command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] + return f'{command} "{self.FilePath.GetValue()}"' + + def Serialize(self): + return { + 'command' : self.CommandChoice.GetSelection(), + 'filename' : self.FilePath.GetValue(), + } + + def Deserialize(self, init): + self.CommandChoice.SetSelection(init.get('command', 0)) + self.FilePath.SetValue(init.get('filename', '')) + +####### Window Toggle +class WindowToggleCmd(PowerBindCmd): + def BuildUI(self, dialog): + self.WindowNames = { + 'Actions' : 'actions', + 'Auction House' : 'ah', + 'Badge' : 'badge', + 'Channel Search' : 'chansearch', + 'Chat' : 'chat', + 'Custom Chat 1' : 'chat1', + 'Custom Chat 2' : 'chat2', + 'Custom Chat 3' : 'chat3', + 'Custom Chat 4' : 'chat4', + 'Clues' : 'clue', + 'Combat Numbers' : 'combatnumbers', + 'Contacts' : 'contact', + 'Contact Finder' : 'contactfinder', + 'Costumes' : 'costume', + 'Email' : 'email', + 'Enhancements' : 'enhancements', + 'Friends' : 'friend', + 'Group' : 'group', + 'Help' : 'helpwindow', + 'Incarnate' : 'incarnate', + 'Inspirations' : 'insp', + 'League' : 'league', + 'LFG' : 'lfg', + 'Map' : 'map', + 'Mission' : 'mission', + 'Nav / Compass' : 'nav', + 'Options' : 'options', + 'Pets' : 'pet', + 'Petition' : 'petition', + 'Power Tray' : 'powers', + 'Power List' : 'powerlist', + 'Quit' : 'quit', + 'Recipes' : 'recipe', + 'Salvage' : 'salvage', + 'Search' : 'search', + 'Supergroup' : 'sg', + 'Target' : 'target', + 'Team' : 'team', + 'Tray' : 'tray', + 'Tray1' : 'tray1', + 'Tray2' : 'tray2', + 'Tray3' : 'tray3', + 'Tray4' : 'tray4', + 'Tray5' : 'tray5', + 'Tray6' : 'tray6', + 'Tray7' : 'tray7', + 'Tray8' : 'tray8', + 'Vault' : 'vault', + } + + self.ShortToggleCommands = { + 'Auction House' : 'ah', + 'Chat' : 'chat', + 'Help' : 'helpwindow', + 'Map' : 'map', + 'Nav / Compass' : 'nav', + 'Power Tray' : 'powers', + 'Target' : 'target', + 'Tray' : 'tray', + } + + windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) + windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) + self.windowToggleTray.SetSelection(0) + windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.windowShowRB = wx.RadioButton(dialog, -1, "Show") + self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") + + windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) + + return windowToggleSizer + + def MakeBindString(self): + choice = self.windowToggleTray + index = choice.GetSelection() + windowdesc = choice.GetString(index) + windowname = self.WindowNames[windowdesc] + + if self.windowShowRB.GetValue(): + return 'show ' + windowname + elif self.windowHideRB.GetValue(): + return 'windowhide ' + windowname + else: + if shortcmd := self.ShortToggleCommands.get(windowdesc, None): + return shortcmd + else: + return 'toggle ' + windowname + + + def Serialize(self): + choice = self.windowToggleTray + if self.windowShowRB.GetValue(): + action = "Show" + elif self.windowHideRB.GetValue(): + action = "Hide" + else: + action = "Toggle" + return { + 'window': choice.GetString(choice.GetSelection()), + 'action': action, + } + + def Deserialize(self, init): + choice = self.windowToggleTray + if window := init.get('window', ''): + if isinstance(window, int): + choice.SetSelection(window) + else: + choice.SetSelection(choice.FindString(window)) + + if choice.GetSelection() == wx.NOT_FOUND: + choice.SetSelection(0) + + action = init.get('action', '') + if action == "Show": + self.windowShowRB.SetValue(True) + elif action == "Hide": + self.windowHideRB.SetValue(True) + else: + self.windowToggleRB.SetValue(True) + + +# Must always add to this list when adding a new command class above +menuStructure = { + 'Graphics / UI' : [ + 'Attribute Monitor', + 'Buff Display Settings', + 'Graphics Settings', + 'Window Color', + 'Window Save / Load', + 'Window Toggle', + ], + 'Inspirations' : [ + 'Use Inspiration By Name', + 'Use Inspiration From Row/Column', + ], + 'Powers' : [ + 'Auto Power', + 'Power Abort', + 'Power Unqueue', + 'Use Power', + 'Use Power From Tray', + ], + 'Social' : [ + 'Away From Keyboard', + 'Chat Command', + 'Chat Command (Global)', + 'Costume Change', + 'Emote', + 'Supergroup Mode', + ], + 'Targeting' : [ + 'Target Custom', + 'Target Enemy', + 'Target Frield', + 'Team/Pet Select', + 'Unselect', + ], + 'Misc' : [ + 'Load Binds Directory', + 'Movement Commands', + ], + # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, + # but I'm leaving it here to remind myself that we do that. + } + +# Must always add to this list when adding a new command class above +commandClasses = { + 'Auto Power' : AutoPowerCmd, + 'Away From Keyboard' : AFKCmd, + 'Attribute Monitor' : AttributeMonitorCmd, + 'Buff Display Settings' : BuffDisplayCmd, + 'Chat Command' : ChatCmd, + 'Chat Command (Global)' : ChatGlobalCmd, + 'Costume Change' : CostumeChangeCmd, + 'Custom Bind' : CustomBindCmd, + 'Emote' : EmoteCmd, + 'Graphics Settings' : GraphicsCmd, + 'Load Binds Directory' : LoadBindsDir, + 'Movement Commands' : MovementCmd, + 'Power Abort' : PowerAbortCmd, + 'Power Unqueue' : PowerUnqueueCmd, + 'Supergroup Mode' : SGModeCmd, + 'Target Custom' : TargetCustomCmd, + 'Target Enemy' : TargetEnemyCmd, + 'Target Friend' : TargetFriendCmd, + 'Team/Pet Select' : TeamPetSelectCmd, + 'Unselect' : UnselectCmd, + 'Use Inspiration By Name' : UseInspByNameCmd, + 'Use Inspiration From Row/Column' : UseInspRowColCmd, + 'Use Power' : UsePowerCmd, + 'Use Power From Tray' : UsePowerFromTrayCmd, + 'Window Color' : WindowColorCmd, + 'Window Save / Load' : WindowSaveLoadCmd, + 'Window Toggle' : WindowToggleCmd, +} +# use these when we rename a commandClass so that old Profiles will still load correctly. +# If we've also updated the class, we need to try to make sure the new class will still +# Deserialize the legacy data, or at least not crash. +deprecatedCommandClasses = { + 'SG Mode Toggle' : SGModeCmd, + 'Use Insp By Name' : UseInspByNameCmd, + 'Use Insp From Row/Column' : UseInspRowColCmd, +} +commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/TargetEnemyCmd.py b/UI/PowerBinderCommand/TargetEnemyCmd.py new file mode 100644 index 0000000..4c02ab7 --- /dev/null +++ b/UI/PowerBinderCommand/TargetEnemyCmd.py @@ -0,0 +1,1800 @@ +import wx +import re +import UI +import UI.EmotePicker +from UI.ControlGroup import ControlGroup +from UI.PowerPicker import PowerPicker +from Help import HelpButton +import wx.adv +from wx.adv import BitmapComboBox, EditableListBox +from pathlib import PureWindowsPath +import GameData +import Profile +from Icon import GetIcon + +class PowerBinderDialog(wx.Dialog): + def __init__(self, parent, button, init = {}): + wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) + + self.Page = parent.Page + self.EditDialog = PowerBinderEditDialog(self) + self.Button = button + self.AddStepMenu = self.makeAddStepMenu() + + sizer = wx.BoxSizer(wx.VERTICAL); + self.mainSizer = sizer + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) + # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) + # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) + #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) + AddStepButton = wx.Button(self, -1, 'Add Step') + AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) + AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) + choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) + choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) + sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) + + rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) + + self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) + self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) + self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) + rearrangeCtrl.Add(self.RearrangeList, 1) + + rearrangeButtons = wx.BoxSizer(wx.VERTICAL) + self.DelButton = wx.Button(self, -1, "Delete") + self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) + self.EditButton = wx.Button(self, -1, "Edit") + self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) + self.EditButton.Disable() + upButton = wx.Button(self, -1, "\u25B2") + upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) + downButton = wx.Button(self, -1, "\u25BC") + downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) + rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) + rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) + + sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.BindStringDisplay = wx.TextCtrl(self, -1) + self.BindStringDisplay.Disable() + choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, + wx.ALIGN_CENTER_VERTICAL) + choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) + + sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) + + sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) + + # need to dig around and get the OK button since we show this dialog modelessly now. + okButton = self.FindWindow(self.GetAffirmativeId()) + okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) + + # Wrap everything in a vbox to add some padding + vbox = wx.BoxSizer(wx.VERTICAL); + vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); + + self.SetSizerAndFit(vbox); + self.Layout() + self.Fit() + self.SetFocus() + + # if we are loading from profile, ie, have "init", build the list from it + if init: self.LoadFromData(init) + + def LoadFromData(self, init): + for item in init: + for type, data in item.items(): + commandClass = commandClasses.get(type, None) + if not commandClass: + commandClass = deprecatedCommandClasses.get(type, None) + if not commandClass: + wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") + continue + newCommand = commandClass(self.EditDialog, data) + index = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.SetClientData(index, newCommand) + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) + self.EditDialog.mainSizer.Hide(newCommand.UI) + self.UpdateBindStringDisplay() + + def SaveToData(self): + data = [] + index = 0 + for _ in self.RearrangeList.GetItems(): + # check whether we have an object already attached to this choice + cmdObject = self.RearrangeList.GetClientData(index) + commandClassName = commandRevClasses[type(cmdObject)] + data.append({commandClassName: cmdObject.Serialize()}) + index = index + 1 + return data + + def OnAddStepButton(self, evt): + button = evt.EventObject + if not self.AddStepMenu: + self.AddStepMenu = self.makeAddStepMenu() + button.PopupMenu(self.AddStepMenu) + + + def OnOKButton(self, _): + if self.Button.tgtTxtCtrl: + bindString = self.MakeBindString() + if bindString != self.Button.tgtTxtCtrl.GetValue(): + self.Button.tgtTxtCtrl.SetValue(bindString) + wx.App.Get().Main.Profile.SetModified() + self.Close() + + def OnRearrangeDelete(self, _): + current = self.RearrangeList.GetSelection() + if current == wx.NOT_FOUND: return + + self.RearrangeList.Delete(current) + self.UpdateBindStringDisplay() + + def OnRearrangeUp(self, _): + self.RearrangeList.MoveCurrentUp() + self.UpdateBindStringDisplay() + + def OnRearrangeDown(self, _): + self.RearrangeList.MoveCurrentDown() + self.UpdateBindStringDisplay() + + def OnRearrangeEdit(self, _): + index = self.RearrangeList.GetSelection() + + # check whether we have an object already attached to this choice + cmdObject = None + try: + cmdObject = self.RearrangeList.GetClientData(index) + except Exception: + pass + + if cmdObject: + self.ShowEditDialogFor(cmdObject) + self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) + else: + print("cmdObject was None") + self.UpdateBindStringDisplay() + + # OnAddStepMenu creates a new step and adds it to the rearrangelist + def OnAddStepMenu(self, evt): + menuitem = self.AddStepMenu.FindItemById(evt.GetId()) + chosenName = menuitem.GetItemLabel() + + # make a new command object, attached to the parent dialog + newCommandClass = commandClasses[chosenName] + newCommand = newCommandClass(self.EditDialog) + + # show the edit dialog if this command needs it + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) + if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): + self.EditDialog.mainSizer.Remove(newCommand.UI) + return + + newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.Select(newBindIndex) + self.RearrangeList.SetClientData(newBindIndex, newCommand) + + self.OnListSelect() + self.UpdateBindStringDisplay() + + def OnListSelect(self, _ = None): + selected = self.RearrangeList.GetSelection() + + if selected != wx.NOT_FOUND: + selCommand = self.RearrangeList.GetClientData(selected) + if selCommand.UI: + self.EditButton.Enable() + else: + self.EditButton.Disable() + + def UpdateBindStringDisplay(self): + self.BindStringDisplay.SetValue(self.MakeBindString()) + self.BindStringDisplay.SetToolTip(self.MakeBindString()) + + def MakeBindString(self): + cmdBindStrings = [] + for index in range(self.RearrangeList.GetCount()): + c = self.RearrangeList.GetClientData(index) + if c: cmdBindStrings.append(c.MakeBindString()) + + bindstring = ('$$'.join(cmdBindStrings)) + return bindstring + + def ShowEditDialogFor(self, command): + if not command.UI: return + + self.EditDialog.mainSizer.Show(command.UI) + + self.EditDialog.Layout() + self.EditDialog.Fit() + + self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') + returnval = self.EditDialog.ShowModal() + + self.EditDialog.mainSizer.Hide(command.UI) + + return returnval + + def makeAddStepMenu(self): + + stepMenu = wx.Menu() + + for subname in menuStructure: + submenu = wx.Menu() + stepMenu.AppendSubMenu(submenu, subname) + for classname in menuStructure[subname]: + submenu.Append(wx.ID_ANY, classname) + + stepMenu.Append(wx.ID_ANY, 'Custom Bind') + + return stepMenu + +class PowerBinderButton(wx.BitmapButton): + + def __init__(self, parent, tgtTxtCtrl, init = {}): + wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) + self.Init = init + self.Dialog = None + self.DialogParent = parent + + self.tgtTxtCtrl = tgtTxtCtrl + self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) + self.SetToolTip("Launch PowerBinder") + + def PowerBinderEventHandler(self, _): + self.PowerBinderDialog().Show() + + def LoadFromData(self, data): + self.PowerBinderDialog().LoadFromData(data) + + def SaveToData(self): + return self.PowerBinderDialog().SaveToData() + + def PowerBinderDialog(self): + if not self.Dialog: + self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) + return self.Dialog + + +class PowerBinderEditDialog(wx.Dialog): + def __init__(self, parent): + wx.Dialog.__init__(self, parent, -1, "Edit Step", + style = wx.DEFAULT_DIALOG_STYLE) + + outerSizer = wx.BoxSizer(wx.VERTICAL) + + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + self.mainSizer.SetMinSize([500, 150]) + + self.Page = parent.Page + + self.mainSizer.Add( + self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), + 0, wx.EXPAND|wx.ALL, 10) + + outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) + + self.SetSizerAndFit(outerSizer) + self.Layout() + self.Fit() + +########### Power Binder Command Objects +class PowerBindCmd(): + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + commandClassName = commandRevClasses[type(self)] + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{commandClassName} - {short_bindstr}" + + +####### Away From Keyboard +class AFKCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) + +####### Attribute Monitor +class AttributeMonitorCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.Groups = {} + self.AttributeTable = { + 'Base' : { + 'Current Hit Points' : 'NT H', + 'Max Hit Points' : 'X H', + 'Current Endurance' : 'T E', + 'Max Endurance' : 'X EN', + 'Regeneration Rate' : 'N RAT', + 'Recovery Rate' : 'Y RA', + 'Endurance Consumption' : 'SU', + 'ToHit Bonus' : 'T B', + 'Accuracy Bonus' : 'CC', + 'Last Hit Chance' : 'T C', + 'Damage Bonus' : 'DA', + 'Healing Bonus' : 'NG B', + 'Recharge Time Bonus' : 'ME B', + 'Endurance Discount' : 'CE DIS', + 'Stealth Radius (PvP)' : 'PVP', + 'Stealth Radius (PvE)' : 'PVE', + 'Perception Radius' : 'RC', + 'Range Bonus' : 'GE B', + 'Threat Level' : 'AT L', + 'Experience to Next Level' : 'XT', + 'Experience Debt' : 'XP', + 'Influence / Infamy' : 'INF', + 'Inherent' : 'NH', + }, + 'Movement Speed' : { + 'Flying Speed' : 'FL', + 'Jumping Speed' : 'PI', + 'Max Jump Height' : 'X J', + 'Run Speed' : 'RU', + }, + 'Damage Resistance' : { + 'Smashing Resistance' : 'G R', + 'Lethal Resistance' : 'L R', + 'Fire Resistance' : 'RE R', + 'Cold Resistance' : 'COLD R', + 'Energy Resistance' : 'DamageType[4]', + 'Negative Energy Resistance' : 'GY R', + 'Psyonic Resistance' : 'NIC R', + 'Toxic Resistance' : 'XIC R', + }, + 'Defense' : { + 'Base Defense' : 'BAS', + 'Ranged Defense' : 'ED', + 'Melee Defense' : 'MEL', + 'AoE Defense' : '2', + 'Smashing Defense' : '3', + 'Lethal Defense' : '4', + 'Fire Defense' : '5', + 'Cold Defense' : '6', + 'Energy Defense' : '7', + 'Negative Energy Defense' : '8', + 'Psionic Defense' : '9', + 'Toxic Defense' : '1', + }, + 'Debuff Resistance' : { + 'Regeneration Resistance' : 'ON R', + 'Recovery Resistance' : 'RY R', + 'To Hit Resistance' : 'IT R', + 'Defense Resistance' : 'NSE RES', + }, + 'Status Effect Protection' : { + 'Hold Protection' : 'D P', + 'Immobilize Protection' : 'LIZE P', + 'Stun Protection' : 'N P', + 'Sleep Protection' : 'P P', + 'Knockback Protection' : 'K P', + 'Confuse Protection' : 'SE P', + 'Terrorize Protection' : 'ZE P', + 'Repel Protection' : 'EL P', + 'Teleport Protection' : 'T P', + }, + 'Status Effect Resistance' : { + 'Hold Resistance' : 'D R', + 'Immobilize Resistance' : 'LIZE R', + 'Stun Resistance' : 'N R', + 'Sleep Resistance' : 'P R', + 'Knockback Resistance' : 'K R', + 'Confuse Resistance' : 'SE R', + 'Terrorize Resistance' : 'ZE R', + 'Placate Resistance' : 'TE R', + 'Taunt Resistance' : 'NT R', + }, + 'Miscellaneous' : { + 'Level Shift' : 'L S', + }, + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.AttributeMenu = wx.Menu() + for group, controls in self.AttributeTable.items(): + submenu = wx.Menu() + self.AttributeMenu.AppendSubMenu(submenu, group) + for cb in controls: + submenu.Append(wx.ID_ANY, cb) + + self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) + + self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) + groupSizer.Add(self.editbox) + + newButton = self.editbox.GetNewButton() + newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) + + return groupSizer + + def MakeBindString(self): + map = {} + bindstrings = [] + for _, controls in self.AttributeTable.items(): + for cb, data in controls.items(): + map[cb] = data + + for string in self.editbox.GetStrings(): + if string: + bindstrings.append(f'monitorattribute {map[string]}') + + return '$$'.join(bindstrings) + + def Serialize(self): + return { + 'attributes' : self.editbox.GetStrings() + } + + def Deserialize(self, init): + self.editbox.SetStrings(init.get('attributes', [])) + + def OnNewButton(self, evt): + evt.GetEventObject().PopupMenu(self.AttributeMenu) + + def OnMenuItem(self, evt): + menuitem = evt.EventObject.FindItemById(evt.GetId()) + existingstrings = self.editbox.GetStrings() + existingstrings.append(menuitem.GetItemLabel()) + self.editbox.SetStrings(existingstrings) + +####### Auto Power +class AutoPowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) + autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.autoPowerName = PowerPicker(dialog) + autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) + + return autoPowerSizer + + def MakeBindString(self): + return f"powexecauto {self.autoPowerName.GetLabel()}" + + def Serialize(self): + return { + 'pname' : self.autoPowerName.GetLabel(), + 'picon' : self.autoPowerName.IconFilename + } + + def Deserialize(self, init): + if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) + +####### Buff Display Command +class BuffDisplayCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.buffDisplayMap = { + 'Status Window' : { + 'Hide Auto' : 1, + 'Hide Toggles' : 2, + 'No Blinking' : 4, + 'No Stacking' : 8, + 'Numeric Stacking' : 16, + 'Hide Buff Numbers' : 32, + 'Stop Sending Buffs' : 64, + }, + 'Group Window' : { + 'Hide Auto' : 256, + 'Hide Toggles' : 512, + 'No Blinking' : 1024, + 'No Stacking' : 2048, + 'Numeric Stacking' : 4096, + 'Hide Buff Numbers' : 8192, + 'Stop Sending Buffs' : 16384, + }, + 'Pet Window' : { + 'Hide Auto' : 65536, + 'Hide Toggles' : 131072, + 'No Blinking' : 262144, + 'No Stacking' : 524288, + 'Numeric Stacking' : 1048576, + 'Hide Buff Numbers' : 2097152, + 'Stop Sending Buffs' : 4194304, + }, + } + self.Groups = {} + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + for group, controls in self.buffDisplayMap.items(): + self.Groups[group] = ControlGroup(dialog, self.Page, label = group) + groupid = self.Groups[group].GetStaticBox().GetId() + for cb, data in controls.items(): + self.Groups[group].AddControl( + ctlType = 'checkbox', + ctlName = f"{groupid}_{group}_{cb}", + label = cb, + data = data, + ) + + groupSizer.Add(self.Groups[group]) + + return groupSizer + + def CalculateValue(self): + page = wx.App.Get().Main.Profile.CustomBinds + + total = 0 + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] + if checkbox.IsChecked(): + total = total + checkbox.Data + return total + + def MakeBindString(self): + return f"optionset buffsettings {self.CalculateValue()}" + + def Serialize(self): + return { 'value' : self.CalculateValue() } + + def Deserialize(self, init): + value = init.get('value', 0) + + value = value or 0 # in case we had for some reason 'None' stashed in the init values + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] + checkbox.SetValue( checkbox.Data & value ) + +####### Chat Command +class ChatCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.chatChannelMap = { # before __init__ + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + chatCommandSizer = wx.GridBagSizer(5, 5) + self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") + chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) + # row 1 + self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) + self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) + self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) + # row 2 + self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) + self.chatCommandDuration.SetRange(1, 20) + self.chatCommandDuration.SetValue(7) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandDuration, (2,1)) + self.chatCommandChatSize = wx.Choice(dialog, -1, + choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) + self.chatCommandChatSize.SetSelection(5) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) + self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) + self.chatCommandChannel.SetSelection(0) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChannel, (2,5)) + # row 3 + self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") + chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) + self.chatCommandMessage = wx.TextCtrl(dialog, -1) + self.chatCommandMessage.SetHint('Chat Command Text') + chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) + + return chatCommandSizer + + def MakeBindString(self): + duration = self.chatCommandDuration.GetValue() + + choice = self.chatCommandChatSize + index = choice.GetSelection() + size = choice.GetString(index) + + duration = f"" if duration != 7 else "" + size = f"" if size != "1" else "" + + bdcolor = fgcolor = bgcolor = '' + if self.chatCommandUseColorsCB.IsChecked(): + bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + + bdcolor = f"" + fgcolor = f"" + bgcolor = f"" + + beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' + text = self.chatCommandMessage.GetValue() + + choice = self.chatCommandChannel + index = choice.GetSelection() + channel = choice.GetString(index) + + return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" + + def Serialize(self): + return { + 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), + 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), + 'channel' : self.chatCommandChannel .GetSelection(), + 'size' : self.chatCommandChatSize.GetSelection(), + 'duration' : self.chatCommandDuration.GetValue(), + 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'text' : self.chatCommandMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) + if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) + if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) + if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) + if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) + if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) + if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) + if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) + if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) + + +####### Chat Command Global +class ChatGlobalCmd(PowerBindCmd): + def BuildUI(self, dialog): + chatCommandGlobalSizer = wx.GridBagSizer(5,5) + + self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") + chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) + + self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalChannel.SetHint("Channel") + chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) + + self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') + chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) + + chatCommandGlobalSizer.AddGrowableCol(1) + + return chatCommandGlobalSizer + + def MakeBindString(self): + useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() + channel = self.chatCommandGlobalChannel.GetValue() + message = self.chatCommandGlobalMessage.GetValue() + + preface = "beginchat /" if useBeginchat else "" + + return f'{preface}send "{channel}" {message}' + + def Serialize(self): + return { + 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), + 'channel' : self.chatCommandGlobalChannel.GetValue(), + 'message' : self.chatCommandGlobalMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) + if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) + if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) + +#######Costume Change +class CostumeChangeCmd(PowerBindCmd): + def BuildUI(self, dialog): + costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeCostume = wx.Choice(dialog, -1, + choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) + self.costumeChangeCostume.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeEmote = wx.Choice(dialog, -1, + choices = GameData.Emotes['costumechange']) + self.costumeChangeEmote.Insert("- None -", 0) + self.costumeChangeEmote.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return costumeChangeSizer + + def MakeBindString(self): + costumeNumber = self.costumeChangeCostume.GetSelection() + costumeEmote = self.costumeChangeEmote.GetSelection() + + if costumeEmote: # None, or 0 == "- None -" + ccCmd = 'cce' + emoteName = self.costumeChangeEmote.GetString(costumeEmote) + emoteName = " CC" + emoteName.replace(" ","") + else: + ccCmd = 'cc' + emoteName = '' + + return f"{ccCmd} {costumeNumber}{emoteName}" + + def Serialize(self): + return{ + 'costumeNumber': self.costumeChangeCostume.GetSelection(), + 'costumeEmote' : self.costumeChangeEmote.GetSelection(), + } + + def Deserialize(self, init): + if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) + if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) + +####### Movement Command +class MovementCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + self.plusbutton.SetValue(True) + + self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.commandchoice = wx.Choice(dialog, choices = [ + "forward", "left", "right", "backward", "up", "down", + "turnleft", "turnright", "first", "autorun", "clicktomove", + ],) + sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) + self.commandchoice.SetSelection(0) + + self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + pre = post = '' + if self.plusbutton.GetValue() : pre = "+" + elif self.plusplusbutton.GetValue() : pre = "++" + elif self.minusbutton.GetValue() : pre = "-" + elif self.zerobutton.GetValue() : post = " 0" + elif self.onebutton.GetValue() : post = " 1" + + command = self.commandchoice.GetString(self.commandchoice.GetSelection()) + + return f"{pre}{command}{post}" + + def Serialize(self): + mod = '' + if self.plusbutton.GetValue() : mod = "plus" + elif self.plusplusbutton.GetValue() : mod = "plusplus" + elif self.minusbutton.GetValue() : mod = "minus" + elif self.zerobutton.GetValue() : mod = "zero" + elif self.onebutton.GetValue() : mod = "one" + + return { + 'mod' : mod, + 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), + } + + def Deserialize(self, init): + mod = init.get('mod', 'plus') + + if mod == 'plus' : self.plusbutton.SetValue(True) + elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) + elif mod == 'minus' : self.minusbutton.SetValue(True) + elif mod == 'zero' : self.zerobutton.SetValue(True) + elif mod == 'one' : self.onebutton.SetValue(True) + + self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) + +####### Graphics Command +class GraphicsCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.FlexGridSizer(2) + + self.visscalecb = wx.CheckBox(dialog, label = "visscale") + sizer.Add(self.visscalecb) + self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) + sizer.Add(self.visscalesc) + + self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") + sizer.Add(self.dofweightcb) + self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) + sizer.Add(self.dofweightsc) + + self.fsaacb = wx.CheckBox(dialog, label = "fsaa") + sizer.Add(self.fsaacb) + self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) + self.fsaach.SetSelection(0) + sizer.Add(self.fsaach) + + self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") + sizer.Add(self.bloomscalecb) + self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) + self.bloomscalech.SetSelection(0) + sizer.Add(self.bloomscalech) + + self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") + sizer.Add(self.bloomweightcb) + self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) + sizer.Add(self.bloomweightsc) + + self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") + sizer.Add(self.lodbiascb) + self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) + sizer.Add(self.lodbiassc) + + self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") + sizer.Add(self.renderscalecb) + self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) + sizer.Add(self.renderscalesc) + + return sizer + + def MakeBindString(self): + # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. + bindstrings = [] + if self.visscalecb.IsChecked(): + bindstrings.append("visscale " + str(self.visscalesc.GetValue())) + if self.dofweightcb.IsChecked(): + bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) + if self.fsaacb.IsChecked(): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bindstrings.append("fsaa " + fsaavalue) + if self.bloomscalecb.IsChecked(): + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + bindstrings.append("bloomscale " + bloomscalevalue) + if self.bloomweightcb.IsChecked(): + bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) + if self.lodbiascb.IsChecked(): + bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) + if self.renderscalecb.IsChecked(): + bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) + + return '$$'.join(bindstrings) + + def Serialize(self): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + return { + 'visscalecb' : self.visscalecb.IsChecked(), + 'visscalesc' : self.visscalesc.GetValue(), + 'dofweightcb' : self.dofweightcb.IsChecked(), + 'dofweightsc' : self.dofweightsc.GetValue(), + 'fsaacb' : self.fsaacb.IsChecked(), + 'fsaach' : fsaavalue, + 'bloomscalecb' : self.bloomscalecb.IsChecked(), + 'bloomscalech' : bloomscalevalue, + 'bloomweightcb' : self.bloomweightcb.IsChecked(), + 'bloomweightsc' : self.bloomweightsc.GetValue(), + 'lodbiascb' : self.lodbiascb.IsChecked(), + 'lodbiassc' : self.lodbiassc.GetValue(), + 'renderscalecb' : self.renderscalecb.IsChecked(), + 'renderscalesc' : self.renderscalesc.GetValue(), + } + + def Deserialize(self, init): + self.visscalecb.SetValue(init.get('visscalecb', False)) + self.visscalesc.SetValue(init.get('visscalesc', 1.0)) + self.dofweightcb.SetValue(init.get('dofweightcb', False)) + self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) + self.fsaacb.SetValue(init.get('fsaacb', False)) + self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) + self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) + self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) + self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) + self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) + self.lodbiascb.SetValue(init.get('lodbiascb', False)) + self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) + self.renderscalecb.SetValue(init.get('renderscalecb', False)) + self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) + +####### Custom Bind +class CustomBindCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.customBindName = wx.TextCtrl(dialog, -1) + self.customBindName.SetHint('Custom Bind Text') + sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + return self.customBindName.GetValue() + + def Serialize(self): + return { 'customBindName': self.customBindName.GetValue() } + + def Deserialize(self,init): + if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) + +####### Emote +class EmoteCmd(PowerBindCmd): + def BuildUI(self, dialog): + emoteSizer = wx.BoxSizer(wx.HORIZONTAL) + self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") + emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + self.emoteName = wx.Button(dialog, -1, "...") + self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) + emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) + + return emoteSizer + + def MakeBindString(self): + displayedEmoteName = self.emoteName.GetLabel() + actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] + + return actualEmotePayload + + def Serialize(self): + return {'emoteName': self.emoteName.GetLabel()} + + def Deserialize(self, init): + if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) + +####### Load Binds Directory +class LoadBindsDir(PowerBindCmd): + def BuildUI(self, dialog): + mainSizer = wx.BoxSizer(wx.VERTICAL) + + lbSizer = wx.BoxSizer(wx.HORIZONTAL) + lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") + lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + profiles = Profile.GetAllProfileBindsDirs() + + self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) + lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") + self.lbResetCB.SetValue(True) + + mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + return mainSizer + + def MakeBindString(self): + + # If the specified binds directory disappeared between runs, we'd crash, so handle that. + if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' + + config = wx.ConfigBase.Get() + if config.Exists('GameBindPath'): + bindpath = config.Read('GameBindPath') + else: + bindpath = config.Read('BindPath') + + reset = "" + if self.lbResetCB.GetValue(): + reset = "keybind_reset$$" + + resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' + return reset + 'bindloadfile ' + str(resetfilepath) + + def Serialize(self): + return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), + 'ResetKeybinds' : self.lbResetCB.GetValue(), + } + + def Deserialize(self, init): + if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) + self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) + +####### Power Abort +class PowerAbortCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecabort' + +####### Power Unqueue +class PowerUnqueueCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecunqueue' + +####### SG Mode +class SGModeCmd(PowerBindCmd): + def BuildUI(self, dialog): + sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) + sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") + self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") + + sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) + + return sgmodeSizer + + def MakeBindString(self): + if self.sgmodeOnRB.GetValue(): + return 'sgmodeset 1' + elif self.sgmodeOffRB.GetValue(): + return 'sgmodeset 0' + else: + return 'sgmode' + + def Serialize(self): + if self.sgmodeOnRB.GetValue(): + val = "On" + elif self.sgmodeOffRB.GetValue(): + val = "Off" + else: + val = "Toggle" + + return {"value" : val} + + def Deserialize(self, init): + val = init.get('value', '') + if val == "On": + self.sgmodeOnRB.SetValue(True) + elif val == "Off": + self.sgmodeOffRB.SetValue(True) + else: + self.sgmodeToggleRB.SetValue(True) + +####### Target Custom +class TargetCustomCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetCustomSizer = wx.GridBagSizer(5,5) + targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), + flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) + self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetCustomModeChoice.SetSelection(0) + targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) + self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) + self.targetCustomOptionalName.SetHint("Optional name to match") + targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) + self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") + targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) + self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") + targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) + self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") + targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) + self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") + targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) + self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") + targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) + self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") + targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) + self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") + targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) + self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") + targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) + + targetCustomSizer.AddGrowableCol(2) + + return targetCustomSizer + + def MakeBindString(self): + choice = self.targetCustomModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + targetCommand = "targetcustom" + mode.lower() + + enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" + friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" + defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" + alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" + mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" + notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" + base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" + notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" + + name = self.targetCustomOptionalName.GetValue() + + return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" + + def Serialize(self): + return { + 'mode' : self.targetCustomModeChoice.GetSelection(), + 'enemy' : self.targetCustomCBEnemies. IsChecked(), + 'friend' : self.targetCustomCBFriends. IsChecked(), + 'defeated' : self.targetCustomCBDefeated. IsChecked(), + 'alive' : self.targetCustomCBAlive. IsChecked(), + 'mypet' : self.targetCustomCBMyPets. IsChecked(), + 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), + 'base' : self.targetCustomCBBaseItems. IsChecked(), + 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), + 'name' : self.targetCustomOptionalName.GetValue(), + } + + def Deserialize(self, init): + if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) + if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) + if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) + if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) + if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) + if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) + if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) + if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) + if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) + if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) + + +####### Target Enemy +class TargetEnemyCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) + targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetEnemyModeChoice.SetSelection(0) + targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetEnemySizer + + def MakeBindString(self): + choice = self.targetEnemyModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetenemy" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetEnemyModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) + +####### Target Friend +class TargetFriendCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) + targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetFriendModeChoice.SetSelection(0) + targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetFriendSizer + + def MakeBindString(self): + choice = self.targetFriendModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetfriend" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetFriendModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) + +####### Team/Pet Select +class TeamPetSelectCmd(PowerBindCmd): + def BuildUI(self, dialog): + teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], + style=wx.ALIGN_CENTER_VERTICAL) + self.teamPetSelectNumber.SetSelection(0) + teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) + + return teamPetSelectSizer + + def MakeBindString(self): + teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' + targetNumber = self.teamPetSelectNumber.GetSelection()+1 + + return f"{teamOrPet}select {targetNumber}" + + def Serialize(self): + return { + 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', + 'targetNum': self.teamPetSelectNumber.GetSelection(), + } + + def Deserialize(self, init): + ToP = init.get('teamOrPet', '') + if ToP == 'pet': + self.teamPetSelectPetRB.SetValue(True) + else: + self.teamPetSelectTeamRB.SetValue(True) + if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) + +####### Unselect +class UnselectCmd(PowerBindCmd): + def MakeBindString(self): + return 'unselect' + +####### Use Insp By Name +class UseInspByNameCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) + for _, types in GameData.Inspirations.items(): + for _, info in types.items(): + for insp in info['tiers']: + name = re.sub(' ', '', str(insp)) + icon = GetIcon(f'Inspirations/{name}') + self.useInspByNameModeChoice.Append(insp, icon) + self.useInspByNameModeChoice.SetSelection(0) + useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) + + return useInspByNameSizer + + def MakeBindString(self): + choice = self.useInspByNameModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "inspexecname " + mode.lower() + + def GetAllInsps(self): + Insplist = [] + for _, info in GameData.Inspirations.items(): + for insp in info['tiers']: + Insplist.append(insp) + Insplist.append("---") + Insplist.pop(-1) # snip the terminal "---" + + return Insplist + + def Serialize(self): + return { 'insp' : self.useInspByNameModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) + +####### Use Insp From Row / Column +class UseInspRowColCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnRow.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) + self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnCol.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) + + return useInspRowColumnSizer + + def MakeBindString(self): + row = self.useInspRowColumnRow.GetSelection()+1 + col = self.useInspRowColumnCol.GetSelection()+1 + + return f"inspexectray {col} {row}" + + def Serialize(self): + return { + 'col' : self.useInspRowColumnCol.GetSelection(), + 'row' : self.useInspRowColumnRow.GetSelection(), + } + + def Deserialize(self, init): + if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) + if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) + +####### Use Power +class UsePowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + outerSizer = wx.BoxSizer(wx.HORIZONTAL) + + usePowerSizer = wx.GridBagSizer(5,5) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBToggle, (0,1)) + self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOn, (0,2)) + self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOff, (0,3)) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerName = PowerPicker(dialog) + usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) + usePowerSizer.AddGrowableCol(3) + + outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) + + return outerSizer + + def MakeBindString(self): + if self.usePowerRBToggle.GetValue(): + method = "powexecname" + elif self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') + return '' + + return f"{method} {self.usePowerName.GetLabel()}" + + def Serialize(self): + if self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + method = "powexecname" + return { + 'method': method, + 'pname' : self.usePowerName.GetLabel(), + 'picon' : self.usePowerName.IconFilename + } + + def Deserialize(self, init): + method = init.get('method', '') + if method == 'powexectoggleon': + self.usePowerRBOn.SetValue(True) + elif method == 'powexectoggleoff': + self.usePowerRBOff.SetValue(True) + else: + self.usePowerRBToggle.SetValue(True) + if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) + +####### Use Power From Tray +class UsePowerFromTrayCmd(PowerBindCmd): + def BuildUI(self, dialog): + usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTrayTray = wx.Choice(dialog, -1, + choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', + 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) + self.usePowerFromTrayTray.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) + self.usePowerFromTraySlot.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return usePowerFromTraySizer + + def MakeBindString(self): + choice = self.usePowerFromTrayTray + tray = choice.GetSelection() + + choice = self.usePowerFromTraySlot + slot = choice.GetSelection()+1 + + mode = "slot" + mode2 = '' + if tray > 3: + mode = "tray" + mode2 = f" {tray - 3}" + elif tray == 3: + mode = "alt2slot" + elif tray == 2: + mode = "altslot" + + return f"powexec{mode} {slot}{mode2}" + + def Serialize(self): + return { + 'tray' : self.usePowerFromTrayTray.GetSelection(), + 'slot' : self.usePowerFromTraySlot.GetSelection(), + } + + def Deserialize(self, init): + if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) + if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) + +####### Window Color +class WindowColorCmd(PowerBindCmd): + def BuildUI(self, dialog): + windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) + borderSizer = wx.BoxSizer(wx.VERTICAL) + self.ColorBorder.SetSizer(borderSizer) + self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) + borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) + + windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) + + RGBASizer = wx.FlexGridSizer(3, 4, 5) + + RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) + self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) + self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + windowColorSizer.Add(RGBASizer) + + self.UpdateFromSlider() + + return windowColorSizer + + def MakeBindString(self): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + return f"windowcolor {Rval} {Gval} {Bval} {Aval}" + + def Serialize(self): + return { + 'Rval' : self.RSlider.GetValue(), + 'Gval' : self.GSlider.GetValue(), + 'Bval' : self.BSlider.GetValue(), + 'Aval' : self.ASlider.GetValue(), + } + + def Deserialize(self, init): + self.RSlider.SetValue(init['Rval']) + self.GSlider.SetValue(init['Gval']) + self.BSlider.SetValue(init['Bval']) + self.ASlider.SetValue(init['Aval']) + self.UpdateFromSlider() + + def UpdateFromSlider(self, _ = None): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RReadout.SetValue(Rval) + self.GReadout.SetValue(Gval) + self.BReadout.SetValue(Bval) + self.AReadout.SetValue(Aval) + self.ColorBorder.Refresh() + + def UpdateFromText(self, _ = None): + Rval = self.RReadout.GetValue() + Gval = self.GReadout.GetValue() + Bval = self.BReadout.GetValue() + Aval = self.AReadout.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RSlider.SetValue(Rval) + self.GSlider.SetValue(Gval) + self.BSlider.SetValue(Bval) + self.ASlider.SetValue(Aval) + self.ColorBorder.Refresh() + +####### Window Save / Load +class WindowSaveLoadCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) + self.CommandChoice.SetSelection(0) + sizer.Add(self.CommandChoice, 0, wx.ALL, 5) + + self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), + value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) + sizer.Add(self.FilePath, 0, wx.ALL, 5) + + return sizer + + def MakeBindString(self): + command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] + return f'{command} "{self.FilePath.GetValue()}"' + + def Serialize(self): + return { + 'command' : self.CommandChoice.GetSelection(), + 'filename' : self.FilePath.GetValue(), + } + + def Deserialize(self, init): + self.CommandChoice.SetSelection(init.get('command', 0)) + self.FilePath.SetValue(init.get('filename', '')) + +####### Window Toggle +class WindowToggleCmd(PowerBindCmd): + def BuildUI(self, dialog): + self.WindowNames = { + 'Actions' : 'actions', + 'Auction House' : 'ah', + 'Badge' : 'badge', + 'Channel Search' : 'chansearch', + 'Chat' : 'chat', + 'Custom Chat 1' : 'chat1', + 'Custom Chat 2' : 'chat2', + 'Custom Chat 3' : 'chat3', + 'Custom Chat 4' : 'chat4', + 'Clues' : 'clue', + 'Combat Numbers' : 'combatnumbers', + 'Contacts' : 'contact', + 'Contact Finder' : 'contactfinder', + 'Costumes' : 'costume', + 'Email' : 'email', + 'Enhancements' : 'enhancements', + 'Friends' : 'friend', + 'Group' : 'group', + 'Help' : 'helpwindow', + 'Incarnate' : 'incarnate', + 'Inspirations' : 'insp', + 'League' : 'league', + 'LFG' : 'lfg', + 'Map' : 'map', + 'Mission' : 'mission', + 'Nav / Compass' : 'nav', + 'Options' : 'options', + 'Pets' : 'pet', + 'Petition' : 'petition', + 'Power Tray' : 'powers', + 'Power List' : 'powerlist', + 'Quit' : 'quit', + 'Recipes' : 'recipe', + 'Salvage' : 'salvage', + 'Search' : 'search', + 'Supergroup' : 'sg', + 'Target' : 'target', + 'Team' : 'team', + 'Tray' : 'tray', + 'Tray1' : 'tray1', + 'Tray2' : 'tray2', + 'Tray3' : 'tray3', + 'Tray4' : 'tray4', + 'Tray5' : 'tray5', + 'Tray6' : 'tray6', + 'Tray7' : 'tray7', + 'Tray8' : 'tray8', + 'Vault' : 'vault', + } + + self.ShortToggleCommands = { + 'Auction House' : 'ah', + 'Chat' : 'chat', + 'Help' : 'helpwindow', + 'Map' : 'map', + 'Nav / Compass' : 'nav', + 'Power Tray' : 'powers', + 'Target' : 'target', + 'Tray' : 'tray', + } + + windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) + windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) + self.windowToggleTray.SetSelection(0) + windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.windowShowRB = wx.RadioButton(dialog, -1, "Show") + self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") + + windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) + + return windowToggleSizer + + def MakeBindString(self): + choice = self.windowToggleTray + index = choice.GetSelection() + windowdesc = choice.GetString(index) + windowname = self.WindowNames[windowdesc] + + if self.windowShowRB.GetValue(): + return 'show ' + windowname + elif self.windowHideRB.GetValue(): + return 'windowhide ' + windowname + else: + if shortcmd := self.ShortToggleCommands.get(windowdesc, None): + return shortcmd + else: + return 'toggle ' + windowname + + + def Serialize(self): + choice = self.windowToggleTray + if self.windowShowRB.GetValue(): + action = "Show" + elif self.windowHideRB.GetValue(): + action = "Hide" + else: + action = "Toggle" + return { + 'window': choice.GetString(choice.GetSelection()), + 'action': action, + } + + def Deserialize(self, init): + choice = self.windowToggleTray + if window := init.get('window', ''): + if isinstance(window, int): + choice.SetSelection(window) + else: + choice.SetSelection(choice.FindString(window)) + + if choice.GetSelection() == wx.NOT_FOUND: + choice.SetSelection(0) + + action = init.get('action', '') + if action == "Show": + self.windowShowRB.SetValue(True) + elif action == "Hide": + self.windowHideRB.SetValue(True) + else: + self.windowToggleRB.SetValue(True) + + +# Must always add to this list when adding a new command class above +menuStructure = { + 'Graphics / UI' : [ + 'Attribute Monitor', + 'Buff Display Settings', + 'Graphics Settings', + 'Window Color', + 'Window Save / Load', + 'Window Toggle', + ], + 'Inspirations' : [ + 'Use Inspiration By Name', + 'Use Inspiration From Row/Column', + ], + 'Powers' : [ + 'Auto Power', + 'Power Abort', + 'Power Unqueue', + 'Use Power', + 'Use Power From Tray', + ], + 'Social' : [ + 'Away From Keyboard', + 'Chat Command', + 'Chat Command (Global)', + 'Costume Change', + 'Emote', + 'Supergroup Mode', + ], + 'Targeting' : [ + 'Target Custom', + 'Target Enemy', + 'Target Frield', + 'Team/Pet Select', + 'Unselect', + ], + 'Misc' : [ + 'Load Binds Directory', + 'Movement Commands', + ], + # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, + # but I'm leaving it here to remind myself that we do that. + } + +# Must always add to this list when adding a new command class above +commandClasses = { + 'Auto Power' : AutoPowerCmd, + 'Away From Keyboard' : AFKCmd, + 'Attribute Monitor' : AttributeMonitorCmd, + 'Buff Display Settings' : BuffDisplayCmd, + 'Chat Command' : ChatCmd, + 'Chat Command (Global)' : ChatGlobalCmd, + 'Costume Change' : CostumeChangeCmd, + 'Custom Bind' : CustomBindCmd, + 'Emote' : EmoteCmd, + 'Graphics Settings' : GraphicsCmd, + 'Load Binds Directory' : LoadBindsDir, + 'Movement Commands' : MovementCmd, + 'Power Abort' : PowerAbortCmd, + 'Power Unqueue' : PowerUnqueueCmd, + 'Supergroup Mode' : SGModeCmd, + 'Target Custom' : TargetCustomCmd, + 'Target Enemy' : TargetEnemyCmd, + 'Target Friend' : TargetFriendCmd, + 'Team/Pet Select' : TeamPetSelectCmd, + 'Unselect' : UnselectCmd, + 'Use Inspiration By Name' : UseInspByNameCmd, + 'Use Inspiration From Row/Column' : UseInspRowColCmd, + 'Use Power' : UsePowerCmd, + 'Use Power From Tray' : UsePowerFromTrayCmd, + 'Window Color' : WindowColorCmd, + 'Window Save / Load' : WindowSaveLoadCmd, + 'Window Toggle' : WindowToggleCmd, +} +# use these when we rename a commandClass so that old Profiles will still load correctly. +# If we've also updated the class, we need to try to make sure the new class will still +# Deserialize the legacy data, or at least not crash. +deprecatedCommandClasses = { + 'SG Mode Toggle' : SGModeCmd, + 'Use Insp By Name' : UseInspByNameCmd, + 'Use Insp From Row/Column' : UseInspRowColCmd, +} +commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/TargetFriendCmd.py b/UI/PowerBinderCommand/TargetFriendCmd.py new file mode 100644 index 0000000..4c02ab7 --- /dev/null +++ b/UI/PowerBinderCommand/TargetFriendCmd.py @@ -0,0 +1,1800 @@ +import wx +import re +import UI +import UI.EmotePicker +from UI.ControlGroup import ControlGroup +from UI.PowerPicker import PowerPicker +from Help import HelpButton +import wx.adv +from wx.adv import BitmapComboBox, EditableListBox +from pathlib import PureWindowsPath +import GameData +import Profile +from Icon import GetIcon + +class PowerBinderDialog(wx.Dialog): + def __init__(self, parent, button, init = {}): + wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) + + self.Page = parent.Page + self.EditDialog = PowerBinderEditDialog(self) + self.Button = button + self.AddStepMenu = self.makeAddStepMenu() + + sizer = wx.BoxSizer(wx.VERTICAL); + self.mainSizer = sizer + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) + # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) + # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) + #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) + AddStepButton = wx.Button(self, -1, 'Add Step') + AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) + AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) + choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) + choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) + sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) + + rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) + + self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) + self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) + self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) + rearrangeCtrl.Add(self.RearrangeList, 1) + + rearrangeButtons = wx.BoxSizer(wx.VERTICAL) + self.DelButton = wx.Button(self, -1, "Delete") + self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) + self.EditButton = wx.Button(self, -1, "Edit") + self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) + self.EditButton.Disable() + upButton = wx.Button(self, -1, "\u25B2") + upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) + downButton = wx.Button(self, -1, "\u25BC") + downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) + rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) + rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) + + sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.BindStringDisplay = wx.TextCtrl(self, -1) + self.BindStringDisplay.Disable() + choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, + wx.ALIGN_CENTER_VERTICAL) + choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) + + sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) + + sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) + + # need to dig around and get the OK button since we show this dialog modelessly now. + okButton = self.FindWindow(self.GetAffirmativeId()) + okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) + + # Wrap everything in a vbox to add some padding + vbox = wx.BoxSizer(wx.VERTICAL); + vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); + + self.SetSizerAndFit(vbox); + self.Layout() + self.Fit() + self.SetFocus() + + # if we are loading from profile, ie, have "init", build the list from it + if init: self.LoadFromData(init) + + def LoadFromData(self, init): + for item in init: + for type, data in item.items(): + commandClass = commandClasses.get(type, None) + if not commandClass: + commandClass = deprecatedCommandClasses.get(type, None) + if not commandClass: + wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") + continue + newCommand = commandClass(self.EditDialog, data) + index = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.SetClientData(index, newCommand) + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) + self.EditDialog.mainSizer.Hide(newCommand.UI) + self.UpdateBindStringDisplay() + + def SaveToData(self): + data = [] + index = 0 + for _ in self.RearrangeList.GetItems(): + # check whether we have an object already attached to this choice + cmdObject = self.RearrangeList.GetClientData(index) + commandClassName = commandRevClasses[type(cmdObject)] + data.append({commandClassName: cmdObject.Serialize()}) + index = index + 1 + return data + + def OnAddStepButton(self, evt): + button = evt.EventObject + if not self.AddStepMenu: + self.AddStepMenu = self.makeAddStepMenu() + button.PopupMenu(self.AddStepMenu) + + + def OnOKButton(self, _): + if self.Button.tgtTxtCtrl: + bindString = self.MakeBindString() + if bindString != self.Button.tgtTxtCtrl.GetValue(): + self.Button.tgtTxtCtrl.SetValue(bindString) + wx.App.Get().Main.Profile.SetModified() + self.Close() + + def OnRearrangeDelete(self, _): + current = self.RearrangeList.GetSelection() + if current == wx.NOT_FOUND: return + + self.RearrangeList.Delete(current) + self.UpdateBindStringDisplay() + + def OnRearrangeUp(self, _): + self.RearrangeList.MoveCurrentUp() + self.UpdateBindStringDisplay() + + def OnRearrangeDown(self, _): + self.RearrangeList.MoveCurrentDown() + self.UpdateBindStringDisplay() + + def OnRearrangeEdit(self, _): + index = self.RearrangeList.GetSelection() + + # check whether we have an object already attached to this choice + cmdObject = None + try: + cmdObject = self.RearrangeList.GetClientData(index) + except Exception: + pass + + if cmdObject: + self.ShowEditDialogFor(cmdObject) + self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) + else: + print("cmdObject was None") + self.UpdateBindStringDisplay() + + # OnAddStepMenu creates a new step and adds it to the rearrangelist + def OnAddStepMenu(self, evt): + menuitem = self.AddStepMenu.FindItemById(evt.GetId()) + chosenName = menuitem.GetItemLabel() + + # make a new command object, attached to the parent dialog + newCommandClass = commandClasses[chosenName] + newCommand = newCommandClass(self.EditDialog) + + # show the edit dialog if this command needs it + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) + if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): + self.EditDialog.mainSizer.Remove(newCommand.UI) + return + + newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.Select(newBindIndex) + self.RearrangeList.SetClientData(newBindIndex, newCommand) + + self.OnListSelect() + self.UpdateBindStringDisplay() + + def OnListSelect(self, _ = None): + selected = self.RearrangeList.GetSelection() + + if selected != wx.NOT_FOUND: + selCommand = self.RearrangeList.GetClientData(selected) + if selCommand.UI: + self.EditButton.Enable() + else: + self.EditButton.Disable() + + def UpdateBindStringDisplay(self): + self.BindStringDisplay.SetValue(self.MakeBindString()) + self.BindStringDisplay.SetToolTip(self.MakeBindString()) + + def MakeBindString(self): + cmdBindStrings = [] + for index in range(self.RearrangeList.GetCount()): + c = self.RearrangeList.GetClientData(index) + if c: cmdBindStrings.append(c.MakeBindString()) + + bindstring = ('$$'.join(cmdBindStrings)) + return bindstring + + def ShowEditDialogFor(self, command): + if not command.UI: return + + self.EditDialog.mainSizer.Show(command.UI) + + self.EditDialog.Layout() + self.EditDialog.Fit() + + self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') + returnval = self.EditDialog.ShowModal() + + self.EditDialog.mainSizer.Hide(command.UI) + + return returnval + + def makeAddStepMenu(self): + + stepMenu = wx.Menu() + + for subname in menuStructure: + submenu = wx.Menu() + stepMenu.AppendSubMenu(submenu, subname) + for classname in menuStructure[subname]: + submenu.Append(wx.ID_ANY, classname) + + stepMenu.Append(wx.ID_ANY, 'Custom Bind') + + return stepMenu + +class PowerBinderButton(wx.BitmapButton): + + def __init__(self, parent, tgtTxtCtrl, init = {}): + wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) + self.Init = init + self.Dialog = None + self.DialogParent = parent + + self.tgtTxtCtrl = tgtTxtCtrl + self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) + self.SetToolTip("Launch PowerBinder") + + def PowerBinderEventHandler(self, _): + self.PowerBinderDialog().Show() + + def LoadFromData(self, data): + self.PowerBinderDialog().LoadFromData(data) + + def SaveToData(self): + return self.PowerBinderDialog().SaveToData() + + def PowerBinderDialog(self): + if not self.Dialog: + self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) + return self.Dialog + + +class PowerBinderEditDialog(wx.Dialog): + def __init__(self, parent): + wx.Dialog.__init__(self, parent, -1, "Edit Step", + style = wx.DEFAULT_DIALOG_STYLE) + + outerSizer = wx.BoxSizer(wx.VERTICAL) + + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + self.mainSizer.SetMinSize([500, 150]) + + self.Page = parent.Page + + self.mainSizer.Add( + self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), + 0, wx.EXPAND|wx.ALL, 10) + + outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) + + self.SetSizerAndFit(outerSizer) + self.Layout() + self.Fit() + +########### Power Binder Command Objects +class PowerBindCmd(): + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + commandClassName = commandRevClasses[type(self)] + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{commandClassName} - {short_bindstr}" + + +####### Away From Keyboard +class AFKCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) + +####### Attribute Monitor +class AttributeMonitorCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.Groups = {} + self.AttributeTable = { + 'Base' : { + 'Current Hit Points' : 'NT H', + 'Max Hit Points' : 'X H', + 'Current Endurance' : 'T E', + 'Max Endurance' : 'X EN', + 'Regeneration Rate' : 'N RAT', + 'Recovery Rate' : 'Y RA', + 'Endurance Consumption' : 'SU', + 'ToHit Bonus' : 'T B', + 'Accuracy Bonus' : 'CC', + 'Last Hit Chance' : 'T C', + 'Damage Bonus' : 'DA', + 'Healing Bonus' : 'NG B', + 'Recharge Time Bonus' : 'ME B', + 'Endurance Discount' : 'CE DIS', + 'Stealth Radius (PvP)' : 'PVP', + 'Stealth Radius (PvE)' : 'PVE', + 'Perception Radius' : 'RC', + 'Range Bonus' : 'GE B', + 'Threat Level' : 'AT L', + 'Experience to Next Level' : 'XT', + 'Experience Debt' : 'XP', + 'Influence / Infamy' : 'INF', + 'Inherent' : 'NH', + }, + 'Movement Speed' : { + 'Flying Speed' : 'FL', + 'Jumping Speed' : 'PI', + 'Max Jump Height' : 'X J', + 'Run Speed' : 'RU', + }, + 'Damage Resistance' : { + 'Smashing Resistance' : 'G R', + 'Lethal Resistance' : 'L R', + 'Fire Resistance' : 'RE R', + 'Cold Resistance' : 'COLD R', + 'Energy Resistance' : 'DamageType[4]', + 'Negative Energy Resistance' : 'GY R', + 'Psyonic Resistance' : 'NIC R', + 'Toxic Resistance' : 'XIC R', + }, + 'Defense' : { + 'Base Defense' : 'BAS', + 'Ranged Defense' : 'ED', + 'Melee Defense' : 'MEL', + 'AoE Defense' : '2', + 'Smashing Defense' : '3', + 'Lethal Defense' : '4', + 'Fire Defense' : '5', + 'Cold Defense' : '6', + 'Energy Defense' : '7', + 'Negative Energy Defense' : '8', + 'Psionic Defense' : '9', + 'Toxic Defense' : '1', + }, + 'Debuff Resistance' : { + 'Regeneration Resistance' : 'ON R', + 'Recovery Resistance' : 'RY R', + 'To Hit Resistance' : 'IT R', + 'Defense Resistance' : 'NSE RES', + }, + 'Status Effect Protection' : { + 'Hold Protection' : 'D P', + 'Immobilize Protection' : 'LIZE P', + 'Stun Protection' : 'N P', + 'Sleep Protection' : 'P P', + 'Knockback Protection' : 'K P', + 'Confuse Protection' : 'SE P', + 'Terrorize Protection' : 'ZE P', + 'Repel Protection' : 'EL P', + 'Teleport Protection' : 'T P', + }, + 'Status Effect Resistance' : { + 'Hold Resistance' : 'D R', + 'Immobilize Resistance' : 'LIZE R', + 'Stun Resistance' : 'N R', + 'Sleep Resistance' : 'P R', + 'Knockback Resistance' : 'K R', + 'Confuse Resistance' : 'SE R', + 'Terrorize Resistance' : 'ZE R', + 'Placate Resistance' : 'TE R', + 'Taunt Resistance' : 'NT R', + }, + 'Miscellaneous' : { + 'Level Shift' : 'L S', + }, + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.AttributeMenu = wx.Menu() + for group, controls in self.AttributeTable.items(): + submenu = wx.Menu() + self.AttributeMenu.AppendSubMenu(submenu, group) + for cb in controls: + submenu.Append(wx.ID_ANY, cb) + + self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) + + self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) + groupSizer.Add(self.editbox) + + newButton = self.editbox.GetNewButton() + newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) + + return groupSizer + + def MakeBindString(self): + map = {} + bindstrings = [] + for _, controls in self.AttributeTable.items(): + for cb, data in controls.items(): + map[cb] = data + + for string in self.editbox.GetStrings(): + if string: + bindstrings.append(f'monitorattribute {map[string]}') + + return '$$'.join(bindstrings) + + def Serialize(self): + return { + 'attributes' : self.editbox.GetStrings() + } + + def Deserialize(self, init): + self.editbox.SetStrings(init.get('attributes', [])) + + def OnNewButton(self, evt): + evt.GetEventObject().PopupMenu(self.AttributeMenu) + + def OnMenuItem(self, evt): + menuitem = evt.EventObject.FindItemById(evt.GetId()) + existingstrings = self.editbox.GetStrings() + existingstrings.append(menuitem.GetItemLabel()) + self.editbox.SetStrings(existingstrings) + +####### Auto Power +class AutoPowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) + autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.autoPowerName = PowerPicker(dialog) + autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) + + return autoPowerSizer + + def MakeBindString(self): + return f"powexecauto {self.autoPowerName.GetLabel()}" + + def Serialize(self): + return { + 'pname' : self.autoPowerName.GetLabel(), + 'picon' : self.autoPowerName.IconFilename + } + + def Deserialize(self, init): + if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) + +####### Buff Display Command +class BuffDisplayCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.buffDisplayMap = { + 'Status Window' : { + 'Hide Auto' : 1, + 'Hide Toggles' : 2, + 'No Blinking' : 4, + 'No Stacking' : 8, + 'Numeric Stacking' : 16, + 'Hide Buff Numbers' : 32, + 'Stop Sending Buffs' : 64, + }, + 'Group Window' : { + 'Hide Auto' : 256, + 'Hide Toggles' : 512, + 'No Blinking' : 1024, + 'No Stacking' : 2048, + 'Numeric Stacking' : 4096, + 'Hide Buff Numbers' : 8192, + 'Stop Sending Buffs' : 16384, + }, + 'Pet Window' : { + 'Hide Auto' : 65536, + 'Hide Toggles' : 131072, + 'No Blinking' : 262144, + 'No Stacking' : 524288, + 'Numeric Stacking' : 1048576, + 'Hide Buff Numbers' : 2097152, + 'Stop Sending Buffs' : 4194304, + }, + } + self.Groups = {} + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + for group, controls in self.buffDisplayMap.items(): + self.Groups[group] = ControlGroup(dialog, self.Page, label = group) + groupid = self.Groups[group].GetStaticBox().GetId() + for cb, data in controls.items(): + self.Groups[group].AddControl( + ctlType = 'checkbox', + ctlName = f"{groupid}_{group}_{cb}", + label = cb, + data = data, + ) + + groupSizer.Add(self.Groups[group]) + + return groupSizer + + def CalculateValue(self): + page = wx.App.Get().Main.Profile.CustomBinds + + total = 0 + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] + if checkbox.IsChecked(): + total = total + checkbox.Data + return total + + def MakeBindString(self): + return f"optionset buffsettings {self.CalculateValue()}" + + def Serialize(self): + return { 'value' : self.CalculateValue() } + + def Deserialize(self, init): + value = init.get('value', 0) + + value = value or 0 # in case we had for some reason 'None' stashed in the init values + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] + checkbox.SetValue( checkbox.Data & value ) + +####### Chat Command +class ChatCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.chatChannelMap = { # before __init__ + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + chatCommandSizer = wx.GridBagSizer(5, 5) + self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") + chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) + # row 1 + self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) + self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) + self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) + # row 2 + self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) + self.chatCommandDuration.SetRange(1, 20) + self.chatCommandDuration.SetValue(7) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandDuration, (2,1)) + self.chatCommandChatSize = wx.Choice(dialog, -1, + choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) + self.chatCommandChatSize.SetSelection(5) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) + self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) + self.chatCommandChannel.SetSelection(0) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChannel, (2,5)) + # row 3 + self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") + chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) + self.chatCommandMessage = wx.TextCtrl(dialog, -1) + self.chatCommandMessage.SetHint('Chat Command Text') + chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) + + return chatCommandSizer + + def MakeBindString(self): + duration = self.chatCommandDuration.GetValue() + + choice = self.chatCommandChatSize + index = choice.GetSelection() + size = choice.GetString(index) + + duration = f"" if duration != 7 else "" + size = f"" if size != "1" else "" + + bdcolor = fgcolor = bgcolor = '' + if self.chatCommandUseColorsCB.IsChecked(): + bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + + bdcolor = f"" + fgcolor = f"" + bgcolor = f"" + + beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' + text = self.chatCommandMessage.GetValue() + + choice = self.chatCommandChannel + index = choice.GetSelection() + channel = choice.GetString(index) + + return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" + + def Serialize(self): + return { + 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), + 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), + 'channel' : self.chatCommandChannel .GetSelection(), + 'size' : self.chatCommandChatSize.GetSelection(), + 'duration' : self.chatCommandDuration.GetValue(), + 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'text' : self.chatCommandMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) + if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) + if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) + if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) + if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) + if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) + if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) + if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) + if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) + + +####### Chat Command Global +class ChatGlobalCmd(PowerBindCmd): + def BuildUI(self, dialog): + chatCommandGlobalSizer = wx.GridBagSizer(5,5) + + self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") + chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) + + self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalChannel.SetHint("Channel") + chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) + + self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') + chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) + + chatCommandGlobalSizer.AddGrowableCol(1) + + return chatCommandGlobalSizer + + def MakeBindString(self): + useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() + channel = self.chatCommandGlobalChannel.GetValue() + message = self.chatCommandGlobalMessage.GetValue() + + preface = "beginchat /" if useBeginchat else "" + + return f'{preface}send "{channel}" {message}' + + def Serialize(self): + return { + 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), + 'channel' : self.chatCommandGlobalChannel.GetValue(), + 'message' : self.chatCommandGlobalMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) + if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) + if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) + +#######Costume Change +class CostumeChangeCmd(PowerBindCmd): + def BuildUI(self, dialog): + costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeCostume = wx.Choice(dialog, -1, + choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) + self.costumeChangeCostume.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeEmote = wx.Choice(dialog, -1, + choices = GameData.Emotes['costumechange']) + self.costumeChangeEmote.Insert("- None -", 0) + self.costumeChangeEmote.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return costumeChangeSizer + + def MakeBindString(self): + costumeNumber = self.costumeChangeCostume.GetSelection() + costumeEmote = self.costumeChangeEmote.GetSelection() + + if costumeEmote: # None, or 0 == "- None -" + ccCmd = 'cce' + emoteName = self.costumeChangeEmote.GetString(costumeEmote) + emoteName = " CC" + emoteName.replace(" ","") + else: + ccCmd = 'cc' + emoteName = '' + + return f"{ccCmd} {costumeNumber}{emoteName}" + + def Serialize(self): + return{ + 'costumeNumber': self.costumeChangeCostume.GetSelection(), + 'costumeEmote' : self.costumeChangeEmote.GetSelection(), + } + + def Deserialize(self, init): + if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) + if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) + +####### Movement Command +class MovementCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + self.plusbutton.SetValue(True) + + self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.commandchoice = wx.Choice(dialog, choices = [ + "forward", "left", "right", "backward", "up", "down", + "turnleft", "turnright", "first", "autorun", "clicktomove", + ],) + sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) + self.commandchoice.SetSelection(0) + + self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + pre = post = '' + if self.plusbutton.GetValue() : pre = "+" + elif self.plusplusbutton.GetValue() : pre = "++" + elif self.minusbutton.GetValue() : pre = "-" + elif self.zerobutton.GetValue() : post = " 0" + elif self.onebutton.GetValue() : post = " 1" + + command = self.commandchoice.GetString(self.commandchoice.GetSelection()) + + return f"{pre}{command}{post}" + + def Serialize(self): + mod = '' + if self.plusbutton.GetValue() : mod = "plus" + elif self.plusplusbutton.GetValue() : mod = "plusplus" + elif self.minusbutton.GetValue() : mod = "minus" + elif self.zerobutton.GetValue() : mod = "zero" + elif self.onebutton.GetValue() : mod = "one" + + return { + 'mod' : mod, + 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), + } + + def Deserialize(self, init): + mod = init.get('mod', 'plus') + + if mod == 'plus' : self.plusbutton.SetValue(True) + elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) + elif mod == 'minus' : self.minusbutton.SetValue(True) + elif mod == 'zero' : self.zerobutton.SetValue(True) + elif mod == 'one' : self.onebutton.SetValue(True) + + self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) + +####### Graphics Command +class GraphicsCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.FlexGridSizer(2) + + self.visscalecb = wx.CheckBox(dialog, label = "visscale") + sizer.Add(self.visscalecb) + self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) + sizer.Add(self.visscalesc) + + self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") + sizer.Add(self.dofweightcb) + self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) + sizer.Add(self.dofweightsc) + + self.fsaacb = wx.CheckBox(dialog, label = "fsaa") + sizer.Add(self.fsaacb) + self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) + self.fsaach.SetSelection(0) + sizer.Add(self.fsaach) + + self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") + sizer.Add(self.bloomscalecb) + self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) + self.bloomscalech.SetSelection(0) + sizer.Add(self.bloomscalech) + + self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") + sizer.Add(self.bloomweightcb) + self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) + sizer.Add(self.bloomweightsc) + + self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") + sizer.Add(self.lodbiascb) + self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) + sizer.Add(self.lodbiassc) + + self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") + sizer.Add(self.renderscalecb) + self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) + sizer.Add(self.renderscalesc) + + return sizer + + def MakeBindString(self): + # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. + bindstrings = [] + if self.visscalecb.IsChecked(): + bindstrings.append("visscale " + str(self.visscalesc.GetValue())) + if self.dofweightcb.IsChecked(): + bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) + if self.fsaacb.IsChecked(): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bindstrings.append("fsaa " + fsaavalue) + if self.bloomscalecb.IsChecked(): + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + bindstrings.append("bloomscale " + bloomscalevalue) + if self.bloomweightcb.IsChecked(): + bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) + if self.lodbiascb.IsChecked(): + bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) + if self.renderscalecb.IsChecked(): + bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) + + return '$$'.join(bindstrings) + + def Serialize(self): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + return { + 'visscalecb' : self.visscalecb.IsChecked(), + 'visscalesc' : self.visscalesc.GetValue(), + 'dofweightcb' : self.dofweightcb.IsChecked(), + 'dofweightsc' : self.dofweightsc.GetValue(), + 'fsaacb' : self.fsaacb.IsChecked(), + 'fsaach' : fsaavalue, + 'bloomscalecb' : self.bloomscalecb.IsChecked(), + 'bloomscalech' : bloomscalevalue, + 'bloomweightcb' : self.bloomweightcb.IsChecked(), + 'bloomweightsc' : self.bloomweightsc.GetValue(), + 'lodbiascb' : self.lodbiascb.IsChecked(), + 'lodbiassc' : self.lodbiassc.GetValue(), + 'renderscalecb' : self.renderscalecb.IsChecked(), + 'renderscalesc' : self.renderscalesc.GetValue(), + } + + def Deserialize(self, init): + self.visscalecb.SetValue(init.get('visscalecb', False)) + self.visscalesc.SetValue(init.get('visscalesc', 1.0)) + self.dofweightcb.SetValue(init.get('dofweightcb', False)) + self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) + self.fsaacb.SetValue(init.get('fsaacb', False)) + self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) + self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) + self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) + self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) + self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) + self.lodbiascb.SetValue(init.get('lodbiascb', False)) + self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) + self.renderscalecb.SetValue(init.get('renderscalecb', False)) + self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) + +####### Custom Bind +class CustomBindCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.customBindName = wx.TextCtrl(dialog, -1) + self.customBindName.SetHint('Custom Bind Text') + sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + return self.customBindName.GetValue() + + def Serialize(self): + return { 'customBindName': self.customBindName.GetValue() } + + def Deserialize(self,init): + if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) + +####### Emote +class EmoteCmd(PowerBindCmd): + def BuildUI(self, dialog): + emoteSizer = wx.BoxSizer(wx.HORIZONTAL) + self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") + emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + self.emoteName = wx.Button(dialog, -1, "...") + self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) + emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) + + return emoteSizer + + def MakeBindString(self): + displayedEmoteName = self.emoteName.GetLabel() + actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] + + return actualEmotePayload + + def Serialize(self): + return {'emoteName': self.emoteName.GetLabel()} + + def Deserialize(self, init): + if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) + +####### Load Binds Directory +class LoadBindsDir(PowerBindCmd): + def BuildUI(self, dialog): + mainSizer = wx.BoxSizer(wx.VERTICAL) + + lbSizer = wx.BoxSizer(wx.HORIZONTAL) + lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") + lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + profiles = Profile.GetAllProfileBindsDirs() + + self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) + lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") + self.lbResetCB.SetValue(True) + + mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + return mainSizer + + def MakeBindString(self): + + # If the specified binds directory disappeared between runs, we'd crash, so handle that. + if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' + + config = wx.ConfigBase.Get() + if config.Exists('GameBindPath'): + bindpath = config.Read('GameBindPath') + else: + bindpath = config.Read('BindPath') + + reset = "" + if self.lbResetCB.GetValue(): + reset = "keybind_reset$$" + + resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' + return reset + 'bindloadfile ' + str(resetfilepath) + + def Serialize(self): + return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), + 'ResetKeybinds' : self.lbResetCB.GetValue(), + } + + def Deserialize(self, init): + if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) + self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) + +####### Power Abort +class PowerAbortCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecabort' + +####### Power Unqueue +class PowerUnqueueCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecunqueue' + +####### SG Mode +class SGModeCmd(PowerBindCmd): + def BuildUI(self, dialog): + sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) + sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") + self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") + + sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) + + return sgmodeSizer + + def MakeBindString(self): + if self.sgmodeOnRB.GetValue(): + return 'sgmodeset 1' + elif self.sgmodeOffRB.GetValue(): + return 'sgmodeset 0' + else: + return 'sgmode' + + def Serialize(self): + if self.sgmodeOnRB.GetValue(): + val = "On" + elif self.sgmodeOffRB.GetValue(): + val = "Off" + else: + val = "Toggle" + + return {"value" : val} + + def Deserialize(self, init): + val = init.get('value', '') + if val == "On": + self.sgmodeOnRB.SetValue(True) + elif val == "Off": + self.sgmodeOffRB.SetValue(True) + else: + self.sgmodeToggleRB.SetValue(True) + +####### Target Custom +class TargetCustomCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetCustomSizer = wx.GridBagSizer(5,5) + targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), + flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) + self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetCustomModeChoice.SetSelection(0) + targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) + self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) + self.targetCustomOptionalName.SetHint("Optional name to match") + targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) + self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") + targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) + self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") + targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) + self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") + targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) + self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") + targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) + self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") + targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) + self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") + targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) + self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") + targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) + self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") + targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) + + targetCustomSizer.AddGrowableCol(2) + + return targetCustomSizer + + def MakeBindString(self): + choice = self.targetCustomModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + targetCommand = "targetcustom" + mode.lower() + + enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" + friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" + defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" + alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" + mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" + notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" + base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" + notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" + + name = self.targetCustomOptionalName.GetValue() + + return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" + + def Serialize(self): + return { + 'mode' : self.targetCustomModeChoice.GetSelection(), + 'enemy' : self.targetCustomCBEnemies. IsChecked(), + 'friend' : self.targetCustomCBFriends. IsChecked(), + 'defeated' : self.targetCustomCBDefeated. IsChecked(), + 'alive' : self.targetCustomCBAlive. IsChecked(), + 'mypet' : self.targetCustomCBMyPets. IsChecked(), + 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), + 'base' : self.targetCustomCBBaseItems. IsChecked(), + 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), + 'name' : self.targetCustomOptionalName.GetValue(), + } + + def Deserialize(self, init): + if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) + if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) + if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) + if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) + if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) + if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) + if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) + if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) + if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) + if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) + + +####### Target Enemy +class TargetEnemyCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) + targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetEnemyModeChoice.SetSelection(0) + targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetEnemySizer + + def MakeBindString(self): + choice = self.targetEnemyModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetenemy" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetEnemyModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) + +####### Target Friend +class TargetFriendCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) + targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetFriendModeChoice.SetSelection(0) + targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetFriendSizer + + def MakeBindString(self): + choice = self.targetFriendModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetfriend" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetFriendModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) + +####### Team/Pet Select +class TeamPetSelectCmd(PowerBindCmd): + def BuildUI(self, dialog): + teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], + style=wx.ALIGN_CENTER_VERTICAL) + self.teamPetSelectNumber.SetSelection(0) + teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) + + return teamPetSelectSizer + + def MakeBindString(self): + teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' + targetNumber = self.teamPetSelectNumber.GetSelection()+1 + + return f"{teamOrPet}select {targetNumber}" + + def Serialize(self): + return { + 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', + 'targetNum': self.teamPetSelectNumber.GetSelection(), + } + + def Deserialize(self, init): + ToP = init.get('teamOrPet', '') + if ToP == 'pet': + self.teamPetSelectPetRB.SetValue(True) + else: + self.teamPetSelectTeamRB.SetValue(True) + if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) + +####### Unselect +class UnselectCmd(PowerBindCmd): + def MakeBindString(self): + return 'unselect' + +####### Use Insp By Name +class UseInspByNameCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) + for _, types in GameData.Inspirations.items(): + for _, info in types.items(): + for insp in info['tiers']: + name = re.sub(' ', '', str(insp)) + icon = GetIcon(f'Inspirations/{name}') + self.useInspByNameModeChoice.Append(insp, icon) + self.useInspByNameModeChoice.SetSelection(0) + useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) + + return useInspByNameSizer + + def MakeBindString(self): + choice = self.useInspByNameModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "inspexecname " + mode.lower() + + def GetAllInsps(self): + Insplist = [] + for _, info in GameData.Inspirations.items(): + for insp in info['tiers']: + Insplist.append(insp) + Insplist.append("---") + Insplist.pop(-1) # snip the terminal "---" + + return Insplist + + def Serialize(self): + return { 'insp' : self.useInspByNameModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) + +####### Use Insp From Row / Column +class UseInspRowColCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnRow.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) + self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnCol.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) + + return useInspRowColumnSizer + + def MakeBindString(self): + row = self.useInspRowColumnRow.GetSelection()+1 + col = self.useInspRowColumnCol.GetSelection()+1 + + return f"inspexectray {col} {row}" + + def Serialize(self): + return { + 'col' : self.useInspRowColumnCol.GetSelection(), + 'row' : self.useInspRowColumnRow.GetSelection(), + } + + def Deserialize(self, init): + if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) + if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) + +####### Use Power +class UsePowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + outerSizer = wx.BoxSizer(wx.HORIZONTAL) + + usePowerSizer = wx.GridBagSizer(5,5) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBToggle, (0,1)) + self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOn, (0,2)) + self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOff, (0,3)) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerName = PowerPicker(dialog) + usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) + usePowerSizer.AddGrowableCol(3) + + outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) + + return outerSizer + + def MakeBindString(self): + if self.usePowerRBToggle.GetValue(): + method = "powexecname" + elif self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') + return '' + + return f"{method} {self.usePowerName.GetLabel()}" + + def Serialize(self): + if self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + method = "powexecname" + return { + 'method': method, + 'pname' : self.usePowerName.GetLabel(), + 'picon' : self.usePowerName.IconFilename + } + + def Deserialize(self, init): + method = init.get('method', '') + if method == 'powexectoggleon': + self.usePowerRBOn.SetValue(True) + elif method == 'powexectoggleoff': + self.usePowerRBOff.SetValue(True) + else: + self.usePowerRBToggle.SetValue(True) + if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) + +####### Use Power From Tray +class UsePowerFromTrayCmd(PowerBindCmd): + def BuildUI(self, dialog): + usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTrayTray = wx.Choice(dialog, -1, + choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', + 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) + self.usePowerFromTrayTray.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) + self.usePowerFromTraySlot.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return usePowerFromTraySizer + + def MakeBindString(self): + choice = self.usePowerFromTrayTray + tray = choice.GetSelection() + + choice = self.usePowerFromTraySlot + slot = choice.GetSelection()+1 + + mode = "slot" + mode2 = '' + if tray > 3: + mode = "tray" + mode2 = f" {tray - 3}" + elif tray == 3: + mode = "alt2slot" + elif tray == 2: + mode = "altslot" + + return f"powexec{mode} {slot}{mode2}" + + def Serialize(self): + return { + 'tray' : self.usePowerFromTrayTray.GetSelection(), + 'slot' : self.usePowerFromTraySlot.GetSelection(), + } + + def Deserialize(self, init): + if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) + if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) + +####### Window Color +class WindowColorCmd(PowerBindCmd): + def BuildUI(self, dialog): + windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) + borderSizer = wx.BoxSizer(wx.VERTICAL) + self.ColorBorder.SetSizer(borderSizer) + self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) + borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) + + windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) + + RGBASizer = wx.FlexGridSizer(3, 4, 5) + + RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) + self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) + self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + windowColorSizer.Add(RGBASizer) + + self.UpdateFromSlider() + + return windowColorSizer + + def MakeBindString(self): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + return f"windowcolor {Rval} {Gval} {Bval} {Aval}" + + def Serialize(self): + return { + 'Rval' : self.RSlider.GetValue(), + 'Gval' : self.GSlider.GetValue(), + 'Bval' : self.BSlider.GetValue(), + 'Aval' : self.ASlider.GetValue(), + } + + def Deserialize(self, init): + self.RSlider.SetValue(init['Rval']) + self.GSlider.SetValue(init['Gval']) + self.BSlider.SetValue(init['Bval']) + self.ASlider.SetValue(init['Aval']) + self.UpdateFromSlider() + + def UpdateFromSlider(self, _ = None): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RReadout.SetValue(Rval) + self.GReadout.SetValue(Gval) + self.BReadout.SetValue(Bval) + self.AReadout.SetValue(Aval) + self.ColorBorder.Refresh() + + def UpdateFromText(self, _ = None): + Rval = self.RReadout.GetValue() + Gval = self.GReadout.GetValue() + Bval = self.BReadout.GetValue() + Aval = self.AReadout.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RSlider.SetValue(Rval) + self.GSlider.SetValue(Gval) + self.BSlider.SetValue(Bval) + self.ASlider.SetValue(Aval) + self.ColorBorder.Refresh() + +####### Window Save / Load +class WindowSaveLoadCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) + self.CommandChoice.SetSelection(0) + sizer.Add(self.CommandChoice, 0, wx.ALL, 5) + + self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), + value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) + sizer.Add(self.FilePath, 0, wx.ALL, 5) + + return sizer + + def MakeBindString(self): + command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] + return f'{command} "{self.FilePath.GetValue()}"' + + def Serialize(self): + return { + 'command' : self.CommandChoice.GetSelection(), + 'filename' : self.FilePath.GetValue(), + } + + def Deserialize(self, init): + self.CommandChoice.SetSelection(init.get('command', 0)) + self.FilePath.SetValue(init.get('filename', '')) + +####### Window Toggle +class WindowToggleCmd(PowerBindCmd): + def BuildUI(self, dialog): + self.WindowNames = { + 'Actions' : 'actions', + 'Auction House' : 'ah', + 'Badge' : 'badge', + 'Channel Search' : 'chansearch', + 'Chat' : 'chat', + 'Custom Chat 1' : 'chat1', + 'Custom Chat 2' : 'chat2', + 'Custom Chat 3' : 'chat3', + 'Custom Chat 4' : 'chat4', + 'Clues' : 'clue', + 'Combat Numbers' : 'combatnumbers', + 'Contacts' : 'contact', + 'Contact Finder' : 'contactfinder', + 'Costumes' : 'costume', + 'Email' : 'email', + 'Enhancements' : 'enhancements', + 'Friends' : 'friend', + 'Group' : 'group', + 'Help' : 'helpwindow', + 'Incarnate' : 'incarnate', + 'Inspirations' : 'insp', + 'League' : 'league', + 'LFG' : 'lfg', + 'Map' : 'map', + 'Mission' : 'mission', + 'Nav / Compass' : 'nav', + 'Options' : 'options', + 'Pets' : 'pet', + 'Petition' : 'petition', + 'Power Tray' : 'powers', + 'Power List' : 'powerlist', + 'Quit' : 'quit', + 'Recipes' : 'recipe', + 'Salvage' : 'salvage', + 'Search' : 'search', + 'Supergroup' : 'sg', + 'Target' : 'target', + 'Team' : 'team', + 'Tray' : 'tray', + 'Tray1' : 'tray1', + 'Tray2' : 'tray2', + 'Tray3' : 'tray3', + 'Tray4' : 'tray4', + 'Tray5' : 'tray5', + 'Tray6' : 'tray6', + 'Tray7' : 'tray7', + 'Tray8' : 'tray8', + 'Vault' : 'vault', + } + + self.ShortToggleCommands = { + 'Auction House' : 'ah', + 'Chat' : 'chat', + 'Help' : 'helpwindow', + 'Map' : 'map', + 'Nav / Compass' : 'nav', + 'Power Tray' : 'powers', + 'Target' : 'target', + 'Tray' : 'tray', + } + + windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) + windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) + self.windowToggleTray.SetSelection(0) + windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.windowShowRB = wx.RadioButton(dialog, -1, "Show") + self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") + + windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) + + return windowToggleSizer + + def MakeBindString(self): + choice = self.windowToggleTray + index = choice.GetSelection() + windowdesc = choice.GetString(index) + windowname = self.WindowNames[windowdesc] + + if self.windowShowRB.GetValue(): + return 'show ' + windowname + elif self.windowHideRB.GetValue(): + return 'windowhide ' + windowname + else: + if shortcmd := self.ShortToggleCommands.get(windowdesc, None): + return shortcmd + else: + return 'toggle ' + windowname + + + def Serialize(self): + choice = self.windowToggleTray + if self.windowShowRB.GetValue(): + action = "Show" + elif self.windowHideRB.GetValue(): + action = "Hide" + else: + action = "Toggle" + return { + 'window': choice.GetString(choice.GetSelection()), + 'action': action, + } + + def Deserialize(self, init): + choice = self.windowToggleTray + if window := init.get('window', ''): + if isinstance(window, int): + choice.SetSelection(window) + else: + choice.SetSelection(choice.FindString(window)) + + if choice.GetSelection() == wx.NOT_FOUND: + choice.SetSelection(0) + + action = init.get('action', '') + if action == "Show": + self.windowShowRB.SetValue(True) + elif action == "Hide": + self.windowHideRB.SetValue(True) + else: + self.windowToggleRB.SetValue(True) + + +# Must always add to this list when adding a new command class above +menuStructure = { + 'Graphics / UI' : [ + 'Attribute Monitor', + 'Buff Display Settings', + 'Graphics Settings', + 'Window Color', + 'Window Save / Load', + 'Window Toggle', + ], + 'Inspirations' : [ + 'Use Inspiration By Name', + 'Use Inspiration From Row/Column', + ], + 'Powers' : [ + 'Auto Power', + 'Power Abort', + 'Power Unqueue', + 'Use Power', + 'Use Power From Tray', + ], + 'Social' : [ + 'Away From Keyboard', + 'Chat Command', + 'Chat Command (Global)', + 'Costume Change', + 'Emote', + 'Supergroup Mode', + ], + 'Targeting' : [ + 'Target Custom', + 'Target Enemy', + 'Target Frield', + 'Team/Pet Select', + 'Unselect', + ], + 'Misc' : [ + 'Load Binds Directory', + 'Movement Commands', + ], + # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, + # but I'm leaving it here to remind myself that we do that. + } + +# Must always add to this list when adding a new command class above +commandClasses = { + 'Auto Power' : AutoPowerCmd, + 'Away From Keyboard' : AFKCmd, + 'Attribute Monitor' : AttributeMonitorCmd, + 'Buff Display Settings' : BuffDisplayCmd, + 'Chat Command' : ChatCmd, + 'Chat Command (Global)' : ChatGlobalCmd, + 'Costume Change' : CostumeChangeCmd, + 'Custom Bind' : CustomBindCmd, + 'Emote' : EmoteCmd, + 'Graphics Settings' : GraphicsCmd, + 'Load Binds Directory' : LoadBindsDir, + 'Movement Commands' : MovementCmd, + 'Power Abort' : PowerAbortCmd, + 'Power Unqueue' : PowerUnqueueCmd, + 'Supergroup Mode' : SGModeCmd, + 'Target Custom' : TargetCustomCmd, + 'Target Enemy' : TargetEnemyCmd, + 'Target Friend' : TargetFriendCmd, + 'Team/Pet Select' : TeamPetSelectCmd, + 'Unselect' : UnselectCmd, + 'Use Inspiration By Name' : UseInspByNameCmd, + 'Use Inspiration From Row/Column' : UseInspRowColCmd, + 'Use Power' : UsePowerCmd, + 'Use Power From Tray' : UsePowerFromTrayCmd, + 'Window Color' : WindowColorCmd, + 'Window Save / Load' : WindowSaveLoadCmd, + 'Window Toggle' : WindowToggleCmd, +} +# use these when we rename a commandClass so that old Profiles will still load correctly. +# If we've also updated the class, we need to try to make sure the new class will still +# Deserialize the legacy data, or at least not crash. +deprecatedCommandClasses = { + 'SG Mode Toggle' : SGModeCmd, + 'Use Insp By Name' : UseInspByNameCmd, + 'Use Insp From Row/Column' : UseInspRowColCmd, +} +commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/TeamPetSelectCmd.py b/UI/PowerBinderCommand/TeamPetSelectCmd.py new file mode 100644 index 0000000..4c02ab7 --- /dev/null +++ b/UI/PowerBinderCommand/TeamPetSelectCmd.py @@ -0,0 +1,1800 @@ +import wx +import re +import UI +import UI.EmotePicker +from UI.ControlGroup import ControlGroup +from UI.PowerPicker import PowerPicker +from Help import HelpButton +import wx.adv +from wx.adv import BitmapComboBox, EditableListBox +from pathlib import PureWindowsPath +import GameData +import Profile +from Icon import GetIcon + +class PowerBinderDialog(wx.Dialog): + def __init__(self, parent, button, init = {}): + wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) + + self.Page = parent.Page + self.EditDialog = PowerBinderEditDialog(self) + self.Button = button + self.AddStepMenu = self.makeAddStepMenu() + + sizer = wx.BoxSizer(wx.VERTICAL); + self.mainSizer = sizer + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) + # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) + # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) + #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) + AddStepButton = wx.Button(self, -1, 'Add Step') + AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) + AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) + choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) + choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) + sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) + + rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) + + self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) + self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) + self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) + rearrangeCtrl.Add(self.RearrangeList, 1) + + rearrangeButtons = wx.BoxSizer(wx.VERTICAL) + self.DelButton = wx.Button(self, -1, "Delete") + self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) + self.EditButton = wx.Button(self, -1, "Edit") + self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) + self.EditButton.Disable() + upButton = wx.Button(self, -1, "\u25B2") + upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) + downButton = wx.Button(self, -1, "\u25BC") + downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) + rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) + rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) + + sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.BindStringDisplay = wx.TextCtrl(self, -1) + self.BindStringDisplay.Disable() + choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, + wx.ALIGN_CENTER_VERTICAL) + choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) + + sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) + + sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) + + # need to dig around and get the OK button since we show this dialog modelessly now. + okButton = self.FindWindow(self.GetAffirmativeId()) + okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) + + # Wrap everything in a vbox to add some padding + vbox = wx.BoxSizer(wx.VERTICAL); + vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); + + self.SetSizerAndFit(vbox); + self.Layout() + self.Fit() + self.SetFocus() + + # if we are loading from profile, ie, have "init", build the list from it + if init: self.LoadFromData(init) + + def LoadFromData(self, init): + for item in init: + for type, data in item.items(): + commandClass = commandClasses.get(type, None) + if not commandClass: + commandClass = deprecatedCommandClasses.get(type, None) + if not commandClass: + wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") + continue + newCommand = commandClass(self.EditDialog, data) + index = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.SetClientData(index, newCommand) + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) + self.EditDialog.mainSizer.Hide(newCommand.UI) + self.UpdateBindStringDisplay() + + def SaveToData(self): + data = [] + index = 0 + for _ in self.RearrangeList.GetItems(): + # check whether we have an object already attached to this choice + cmdObject = self.RearrangeList.GetClientData(index) + commandClassName = commandRevClasses[type(cmdObject)] + data.append({commandClassName: cmdObject.Serialize()}) + index = index + 1 + return data + + def OnAddStepButton(self, evt): + button = evt.EventObject + if not self.AddStepMenu: + self.AddStepMenu = self.makeAddStepMenu() + button.PopupMenu(self.AddStepMenu) + + + def OnOKButton(self, _): + if self.Button.tgtTxtCtrl: + bindString = self.MakeBindString() + if bindString != self.Button.tgtTxtCtrl.GetValue(): + self.Button.tgtTxtCtrl.SetValue(bindString) + wx.App.Get().Main.Profile.SetModified() + self.Close() + + def OnRearrangeDelete(self, _): + current = self.RearrangeList.GetSelection() + if current == wx.NOT_FOUND: return + + self.RearrangeList.Delete(current) + self.UpdateBindStringDisplay() + + def OnRearrangeUp(self, _): + self.RearrangeList.MoveCurrentUp() + self.UpdateBindStringDisplay() + + def OnRearrangeDown(self, _): + self.RearrangeList.MoveCurrentDown() + self.UpdateBindStringDisplay() + + def OnRearrangeEdit(self, _): + index = self.RearrangeList.GetSelection() + + # check whether we have an object already attached to this choice + cmdObject = None + try: + cmdObject = self.RearrangeList.GetClientData(index) + except Exception: + pass + + if cmdObject: + self.ShowEditDialogFor(cmdObject) + self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) + else: + print("cmdObject was None") + self.UpdateBindStringDisplay() + + # OnAddStepMenu creates a new step and adds it to the rearrangelist + def OnAddStepMenu(self, evt): + menuitem = self.AddStepMenu.FindItemById(evt.GetId()) + chosenName = menuitem.GetItemLabel() + + # make a new command object, attached to the parent dialog + newCommandClass = commandClasses[chosenName] + newCommand = newCommandClass(self.EditDialog) + + # show the edit dialog if this command needs it + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) + if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): + self.EditDialog.mainSizer.Remove(newCommand.UI) + return + + newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.Select(newBindIndex) + self.RearrangeList.SetClientData(newBindIndex, newCommand) + + self.OnListSelect() + self.UpdateBindStringDisplay() + + def OnListSelect(self, _ = None): + selected = self.RearrangeList.GetSelection() + + if selected != wx.NOT_FOUND: + selCommand = self.RearrangeList.GetClientData(selected) + if selCommand.UI: + self.EditButton.Enable() + else: + self.EditButton.Disable() + + def UpdateBindStringDisplay(self): + self.BindStringDisplay.SetValue(self.MakeBindString()) + self.BindStringDisplay.SetToolTip(self.MakeBindString()) + + def MakeBindString(self): + cmdBindStrings = [] + for index in range(self.RearrangeList.GetCount()): + c = self.RearrangeList.GetClientData(index) + if c: cmdBindStrings.append(c.MakeBindString()) + + bindstring = ('$$'.join(cmdBindStrings)) + return bindstring + + def ShowEditDialogFor(self, command): + if not command.UI: return + + self.EditDialog.mainSizer.Show(command.UI) + + self.EditDialog.Layout() + self.EditDialog.Fit() + + self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') + returnval = self.EditDialog.ShowModal() + + self.EditDialog.mainSizer.Hide(command.UI) + + return returnval + + def makeAddStepMenu(self): + + stepMenu = wx.Menu() + + for subname in menuStructure: + submenu = wx.Menu() + stepMenu.AppendSubMenu(submenu, subname) + for classname in menuStructure[subname]: + submenu.Append(wx.ID_ANY, classname) + + stepMenu.Append(wx.ID_ANY, 'Custom Bind') + + return stepMenu + +class PowerBinderButton(wx.BitmapButton): + + def __init__(self, parent, tgtTxtCtrl, init = {}): + wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) + self.Init = init + self.Dialog = None + self.DialogParent = parent + + self.tgtTxtCtrl = tgtTxtCtrl + self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) + self.SetToolTip("Launch PowerBinder") + + def PowerBinderEventHandler(self, _): + self.PowerBinderDialog().Show() + + def LoadFromData(self, data): + self.PowerBinderDialog().LoadFromData(data) + + def SaveToData(self): + return self.PowerBinderDialog().SaveToData() + + def PowerBinderDialog(self): + if not self.Dialog: + self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) + return self.Dialog + + +class PowerBinderEditDialog(wx.Dialog): + def __init__(self, parent): + wx.Dialog.__init__(self, parent, -1, "Edit Step", + style = wx.DEFAULT_DIALOG_STYLE) + + outerSizer = wx.BoxSizer(wx.VERTICAL) + + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + self.mainSizer.SetMinSize([500, 150]) + + self.Page = parent.Page + + self.mainSizer.Add( + self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), + 0, wx.EXPAND|wx.ALL, 10) + + outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) + + self.SetSizerAndFit(outerSizer) + self.Layout() + self.Fit() + +########### Power Binder Command Objects +class PowerBindCmd(): + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + commandClassName = commandRevClasses[type(self)] + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{commandClassName} - {short_bindstr}" + + +####### Away From Keyboard +class AFKCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) + +####### Attribute Monitor +class AttributeMonitorCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.Groups = {} + self.AttributeTable = { + 'Base' : { + 'Current Hit Points' : 'NT H', + 'Max Hit Points' : 'X H', + 'Current Endurance' : 'T E', + 'Max Endurance' : 'X EN', + 'Regeneration Rate' : 'N RAT', + 'Recovery Rate' : 'Y RA', + 'Endurance Consumption' : 'SU', + 'ToHit Bonus' : 'T B', + 'Accuracy Bonus' : 'CC', + 'Last Hit Chance' : 'T C', + 'Damage Bonus' : 'DA', + 'Healing Bonus' : 'NG B', + 'Recharge Time Bonus' : 'ME B', + 'Endurance Discount' : 'CE DIS', + 'Stealth Radius (PvP)' : 'PVP', + 'Stealth Radius (PvE)' : 'PVE', + 'Perception Radius' : 'RC', + 'Range Bonus' : 'GE B', + 'Threat Level' : 'AT L', + 'Experience to Next Level' : 'XT', + 'Experience Debt' : 'XP', + 'Influence / Infamy' : 'INF', + 'Inherent' : 'NH', + }, + 'Movement Speed' : { + 'Flying Speed' : 'FL', + 'Jumping Speed' : 'PI', + 'Max Jump Height' : 'X J', + 'Run Speed' : 'RU', + }, + 'Damage Resistance' : { + 'Smashing Resistance' : 'G R', + 'Lethal Resistance' : 'L R', + 'Fire Resistance' : 'RE R', + 'Cold Resistance' : 'COLD R', + 'Energy Resistance' : 'DamageType[4]', + 'Negative Energy Resistance' : 'GY R', + 'Psyonic Resistance' : 'NIC R', + 'Toxic Resistance' : 'XIC R', + }, + 'Defense' : { + 'Base Defense' : 'BAS', + 'Ranged Defense' : 'ED', + 'Melee Defense' : 'MEL', + 'AoE Defense' : '2', + 'Smashing Defense' : '3', + 'Lethal Defense' : '4', + 'Fire Defense' : '5', + 'Cold Defense' : '6', + 'Energy Defense' : '7', + 'Negative Energy Defense' : '8', + 'Psionic Defense' : '9', + 'Toxic Defense' : '1', + }, + 'Debuff Resistance' : { + 'Regeneration Resistance' : 'ON R', + 'Recovery Resistance' : 'RY R', + 'To Hit Resistance' : 'IT R', + 'Defense Resistance' : 'NSE RES', + }, + 'Status Effect Protection' : { + 'Hold Protection' : 'D P', + 'Immobilize Protection' : 'LIZE P', + 'Stun Protection' : 'N P', + 'Sleep Protection' : 'P P', + 'Knockback Protection' : 'K P', + 'Confuse Protection' : 'SE P', + 'Terrorize Protection' : 'ZE P', + 'Repel Protection' : 'EL P', + 'Teleport Protection' : 'T P', + }, + 'Status Effect Resistance' : { + 'Hold Resistance' : 'D R', + 'Immobilize Resistance' : 'LIZE R', + 'Stun Resistance' : 'N R', + 'Sleep Resistance' : 'P R', + 'Knockback Resistance' : 'K R', + 'Confuse Resistance' : 'SE R', + 'Terrorize Resistance' : 'ZE R', + 'Placate Resistance' : 'TE R', + 'Taunt Resistance' : 'NT R', + }, + 'Miscellaneous' : { + 'Level Shift' : 'L S', + }, + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.AttributeMenu = wx.Menu() + for group, controls in self.AttributeTable.items(): + submenu = wx.Menu() + self.AttributeMenu.AppendSubMenu(submenu, group) + for cb in controls: + submenu.Append(wx.ID_ANY, cb) + + self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) + + self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) + groupSizer.Add(self.editbox) + + newButton = self.editbox.GetNewButton() + newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) + + return groupSizer + + def MakeBindString(self): + map = {} + bindstrings = [] + for _, controls in self.AttributeTable.items(): + for cb, data in controls.items(): + map[cb] = data + + for string in self.editbox.GetStrings(): + if string: + bindstrings.append(f'monitorattribute {map[string]}') + + return '$$'.join(bindstrings) + + def Serialize(self): + return { + 'attributes' : self.editbox.GetStrings() + } + + def Deserialize(self, init): + self.editbox.SetStrings(init.get('attributes', [])) + + def OnNewButton(self, evt): + evt.GetEventObject().PopupMenu(self.AttributeMenu) + + def OnMenuItem(self, evt): + menuitem = evt.EventObject.FindItemById(evt.GetId()) + existingstrings = self.editbox.GetStrings() + existingstrings.append(menuitem.GetItemLabel()) + self.editbox.SetStrings(existingstrings) + +####### Auto Power +class AutoPowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) + autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.autoPowerName = PowerPicker(dialog) + autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) + + return autoPowerSizer + + def MakeBindString(self): + return f"powexecauto {self.autoPowerName.GetLabel()}" + + def Serialize(self): + return { + 'pname' : self.autoPowerName.GetLabel(), + 'picon' : self.autoPowerName.IconFilename + } + + def Deserialize(self, init): + if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) + +####### Buff Display Command +class BuffDisplayCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.buffDisplayMap = { + 'Status Window' : { + 'Hide Auto' : 1, + 'Hide Toggles' : 2, + 'No Blinking' : 4, + 'No Stacking' : 8, + 'Numeric Stacking' : 16, + 'Hide Buff Numbers' : 32, + 'Stop Sending Buffs' : 64, + }, + 'Group Window' : { + 'Hide Auto' : 256, + 'Hide Toggles' : 512, + 'No Blinking' : 1024, + 'No Stacking' : 2048, + 'Numeric Stacking' : 4096, + 'Hide Buff Numbers' : 8192, + 'Stop Sending Buffs' : 16384, + }, + 'Pet Window' : { + 'Hide Auto' : 65536, + 'Hide Toggles' : 131072, + 'No Blinking' : 262144, + 'No Stacking' : 524288, + 'Numeric Stacking' : 1048576, + 'Hide Buff Numbers' : 2097152, + 'Stop Sending Buffs' : 4194304, + }, + } + self.Groups = {} + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + for group, controls in self.buffDisplayMap.items(): + self.Groups[group] = ControlGroup(dialog, self.Page, label = group) + groupid = self.Groups[group].GetStaticBox().GetId() + for cb, data in controls.items(): + self.Groups[group].AddControl( + ctlType = 'checkbox', + ctlName = f"{groupid}_{group}_{cb}", + label = cb, + data = data, + ) + + groupSizer.Add(self.Groups[group]) + + return groupSizer + + def CalculateValue(self): + page = wx.App.Get().Main.Profile.CustomBinds + + total = 0 + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] + if checkbox.IsChecked(): + total = total + checkbox.Data + return total + + def MakeBindString(self): + return f"optionset buffsettings {self.CalculateValue()}" + + def Serialize(self): + return { 'value' : self.CalculateValue() } + + def Deserialize(self, init): + value = init.get('value', 0) + + value = value or 0 # in case we had for some reason 'None' stashed in the init values + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] + checkbox.SetValue( checkbox.Data & value ) + +####### Chat Command +class ChatCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.chatChannelMap = { # before __init__ + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + chatCommandSizer = wx.GridBagSizer(5, 5) + self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") + chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) + # row 1 + self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) + self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) + self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) + # row 2 + self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) + self.chatCommandDuration.SetRange(1, 20) + self.chatCommandDuration.SetValue(7) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandDuration, (2,1)) + self.chatCommandChatSize = wx.Choice(dialog, -1, + choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) + self.chatCommandChatSize.SetSelection(5) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) + self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) + self.chatCommandChannel.SetSelection(0) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChannel, (2,5)) + # row 3 + self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") + chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) + self.chatCommandMessage = wx.TextCtrl(dialog, -1) + self.chatCommandMessage.SetHint('Chat Command Text') + chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) + + return chatCommandSizer + + def MakeBindString(self): + duration = self.chatCommandDuration.GetValue() + + choice = self.chatCommandChatSize + index = choice.GetSelection() + size = choice.GetString(index) + + duration = f"" if duration != 7 else "" + size = f"" if size != "1" else "" + + bdcolor = fgcolor = bgcolor = '' + if self.chatCommandUseColorsCB.IsChecked(): + bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + + bdcolor = f"" + fgcolor = f"" + bgcolor = f"" + + beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' + text = self.chatCommandMessage.GetValue() + + choice = self.chatCommandChannel + index = choice.GetSelection() + channel = choice.GetString(index) + + return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" + + def Serialize(self): + return { + 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), + 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), + 'channel' : self.chatCommandChannel .GetSelection(), + 'size' : self.chatCommandChatSize.GetSelection(), + 'duration' : self.chatCommandDuration.GetValue(), + 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'text' : self.chatCommandMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) + if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) + if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) + if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) + if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) + if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) + if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) + if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) + if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) + + +####### Chat Command Global +class ChatGlobalCmd(PowerBindCmd): + def BuildUI(self, dialog): + chatCommandGlobalSizer = wx.GridBagSizer(5,5) + + self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") + chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) + + self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalChannel.SetHint("Channel") + chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) + + self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') + chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) + + chatCommandGlobalSizer.AddGrowableCol(1) + + return chatCommandGlobalSizer + + def MakeBindString(self): + useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() + channel = self.chatCommandGlobalChannel.GetValue() + message = self.chatCommandGlobalMessage.GetValue() + + preface = "beginchat /" if useBeginchat else "" + + return f'{preface}send "{channel}" {message}' + + def Serialize(self): + return { + 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), + 'channel' : self.chatCommandGlobalChannel.GetValue(), + 'message' : self.chatCommandGlobalMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) + if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) + if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) + +#######Costume Change +class CostumeChangeCmd(PowerBindCmd): + def BuildUI(self, dialog): + costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeCostume = wx.Choice(dialog, -1, + choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) + self.costumeChangeCostume.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeEmote = wx.Choice(dialog, -1, + choices = GameData.Emotes['costumechange']) + self.costumeChangeEmote.Insert("- None -", 0) + self.costumeChangeEmote.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return costumeChangeSizer + + def MakeBindString(self): + costumeNumber = self.costumeChangeCostume.GetSelection() + costumeEmote = self.costumeChangeEmote.GetSelection() + + if costumeEmote: # None, or 0 == "- None -" + ccCmd = 'cce' + emoteName = self.costumeChangeEmote.GetString(costumeEmote) + emoteName = " CC" + emoteName.replace(" ","") + else: + ccCmd = 'cc' + emoteName = '' + + return f"{ccCmd} {costumeNumber}{emoteName}" + + def Serialize(self): + return{ + 'costumeNumber': self.costumeChangeCostume.GetSelection(), + 'costumeEmote' : self.costumeChangeEmote.GetSelection(), + } + + def Deserialize(self, init): + if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) + if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) + +####### Movement Command +class MovementCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + self.plusbutton.SetValue(True) + + self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.commandchoice = wx.Choice(dialog, choices = [ + "forward", "left", "right", "backward", "up", "down", + "turnleft", "turnright", "first", "autorun", "clicktomove", + ],) + sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) + self.commandchoice.SetSelection(0) + + self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + pre = post = '' + if self.plusbutton.GetValue() : pre = "+" + elif self.plusplusbutton.GetValue() : pre = "++" + elif self.minusbutton.GetValue() : pre = "-" + elif self.zerobutton.GetValue() : post = " 0" + elif self.onebutton.GetValue() : post = " 1" + + command = self.commandchoice.GetString(self.commandchoice.GetSelection()) + + return f"{pre}{command}{post}" + + def Serialize(self): + mod = '' + if self.plusbutton.GetValue() : mod = "plus" + elif self.plusplusbutton.GetValue() : mod = "plusplus" + elif self.minusbutton.GetValue() : mod = "minus" + elif self.zerobutton.GetValue() : mod = "zero" + elif self.onebutton.GetValue() : mod = "one" + + return { + 'mod' : mod, + 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), + } + + def Deserialize(self, init): + mod = init.get('mod', 'plus') + + if mod == 'plus' : self.plusbutton.SetValue(True) + elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) + elif mod == 'minus' : self.minusbutton.SetValue(True) + elif mod == 'zero' : self.zerobutton.SetValue(True) + elif mod == 'one' : self.onebutton.SetValue(True) + + self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) + +####### Graphics Command +class GraphicsCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.FlexGridSizer(2) + + self.visscalecb = wx.CheckBox(dialog, label = "visscale") + sizer.Add(self.visscalecb) + self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) + sizer.Add(self.visscalesc) + + self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") + sizer.Add(self.dofweightcb) + self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) + sizer.Add(self.dofweightsc) + + self.fsaacb = wx.CheckBox(dialog, label = "fsaa") + sizer.Add(self.fsaacb) + self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) + self.fsaach.SetSelection(0) + sizer.Add(self.fsaach) + + self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") + sizer.Add(self.bloomscalecb) + self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) + self.bloomscalech.SetSelection(0) + sizer.Add(self.bloomscalech) + + self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") + sizer.Add(self.bloomweightcb) + self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) + sizer.Add(self.bloomweightsc) + + self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") + sizer.Add(self.lodbiascb) + self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) + sizer.Add(self.lodbiassc) + + self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") + sizer.Add(self.renderscalecb) + self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) + sizer.Add(self.renderscalesc) + + return sizer + + def MakeBindString(self): + # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. + bindstrings = [] + if self.visscalecb.IsChecked(): + bindstrings.append("visscale " + str(self.visscalesc.GetValue())) + if self.dofweightcb.IsChecked(): + bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) + if self.fsaacb.IsChecked(): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bindstrings.append("fsaa " + fsaavalue) + if self.bloomscalecb.IsChecked(): + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + bindstrings.append("bloomscale " + bloomscalevalue) + if self.bloomweightcb.IsChecked(): + bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) + if self.lodbiascb.IsChecked(): + bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) + if self.renderscalecb.IsChecked(): + bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) + + return '$$'.join(bindstrings) + + def Serialize(self): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + return { + 'visscalecb' : self.visscalecb.IsChecked(), + 'visscalesc' : self.visscalesc.GetValue(), + 'dofweightcb' : self.dofweightcb.IsChecked(), + 'dofweightsc' : self.dofweightsc.GetValue(), + 'fsaacb' : self.fsaacb.IsChecked(), + 'fsaach' : fsaavalue, + 'bloomscalecb' : self.bloomscalecb.IsChecked(), + 'bloomscalech' : bloomscalevalue, + 'bloomweightcb' : self.bloomweightcb.IsChecked(), + 'bloomweightsc' : self.bloomweightsc.GetValue(), + 'lodbiascb' : self.lodbiascb.IsChecked(), + 'lodbiassc' : self.lodbiassc.GetValue(), + 'renderscalecb' : self.renderscalecb.IsChecked(), + 'renderscalesc' : self.renderscalesc.GetValue(), + } + + def Deserialize(self, init): + self.visscalecb.SetValue(init.get('visscalecb', False)) + self.visscalesc.SetValue(init.get('visscalesc', 1.0)) + self.dofweightcb.SetValue(init.get('dofweightcb', False)) + self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) + self.fsaacb.SetValue(init.get('fsaacb', False)) + self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) + self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) + self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) + self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) + self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) + self.lodbiascb.SetValue(init.get('lodbiascb', False)) + self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) + self.renderscalecb.SetValue(init.get('renderscalecb', False)) + self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) + +####### Custom Bind +class CustomBindCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.customBindName = wx.TextCtrl(dialog, -1) + self.customBindName.SetHint('Custom Bind Text') + sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + return self.customBindName.GetValue() + + def Serialize(self): + return { 'customBindName': self.customBindName.GetValue() } + + def Deserialize(self,init): + if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) + +####### Emote +class EmoteCmd(PowerBindCmd): + def BuildUI(self, dialog): + emoteSizer = wx.BoxSizer(wx.HORIZONTAL) + self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") + emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + self.emoteName = wx.Button(dialog, -1, "...") + self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) + emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) + + return emoteSizer + + def MakeBindString(self): + displayedEmoteName = self.emoteName.GetLabel() + actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] + + return actualEmotePayload + + def Serialize(self): + return {'emoteName': self.emoteName.GetLabel()} + + def Deserialize(self, init): + if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) + +####### Load Binds Directory +class LoadBindsDir(PowerBindCmd): + def BuildUI(self, dialog): + mainSizer = wx.BoxSizer(wx.VERTICAL) + + lbSizer = wx.BoxSizer(wx.HORIZONTAL) + lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") + lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + profiles = Profile.GetAllProfileBindsDirs() + + self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) + lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") + self.lbResetCB.SetValue(True) + + mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + return mainSizer + + def MakeBindString(self): + + # If the specified binds directory disappeared between runs, we'd crash, so handle that. + if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' + + config = wx.ConfigBase.Get() + if config.Exists('GameBindPath'): + bindpath = config.Read('GameBindPath') + else: + bindpath = config.Read('BindPath') + + reset = "" + if self.lbResetCB.GetValue(): + reset = "keybind_reset$$" + + resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' + return reset + 'bindloadfile ' + str(resetfilepath) + + def Serialize(self): + return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), + 'ResetKeybinds' : self.lbResetCB.GetValue(), + } + + def Deserialize(self, init): + if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) + self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) + +####### Power Abort +class PowerAbortCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecabort' + +####### Power Unqueue +class PowerUnqueueCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecunqueue' + +####### SG Mode +class SGModeCmd(PowerBindCmd): + def BuildUI(self, dialog): + sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) + sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") + self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") + + sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) + + return sgmodeSizer + + def MakeBindString(self): + if self.sgmodeOnRB.GetValue(): + return 'sgmodeset 1' + elif self.sgmodeOffRB.GetValue(): + return 'sgmodeset 0' + else: + return 'sgmode' + + def Serialize(self): + if self.sgmodeOnRB.GetValue(): + val = "On" + elif self.sgmodeOffRB.GetValue(): + val = "Off" + else: + val = "Toggle" + + return {"value" : val} + + def Deserialize(self, init): + val = init.get('value', '') + if val == "On": + self.sgmodeOnRB.SetValue(True) + elif val == "Off": + self.sgmodeOffRB.SetValue(True) + else: + self.sgmodeToggleRB.SetValue(True) + +####### Target Custom +class TargetCustomCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetCustomSizer = wx.GridBagSizer(5,5) + targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), + flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) + self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetCustomModeChoice.SetSelection(0) + targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) + self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) + self.targetCustomOptionalName.SetHint("Optional name to match") + targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) + self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") + targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) + self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") + targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) + self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") + targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) + self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") + targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) + self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") + targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) + self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") + targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) + self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") + targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) + self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") + targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) + + targetCustomSizer.AddGrowableCol(2) + + return targetCustomSizer + + def MakeBindString(self): + choice = self.targetCustomModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + targetCommand = "targetcustom" + mode.lower() + + enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" + friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" + defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" + alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" + mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" + notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" + base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" + notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" + + name = self.targetCustomOptionalName.GetValue() + + return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" + + def Serialize(self): + return { + 'mode' : self.targetCustomModeChoice.GetSelection(), + 'enemy' : self.targetCustomCBEnemies. IsChecked(), + 'friend' : self.targetCustomCBFriends. IsChecked(), + 'defeated' : self.targetCustomCBDefeated. IsChecked(), + 'alive' : self.targetCustomCBAlive. IsChecked(), + 'mypet' : self.targetCustomCBMyPets. IsChecked(), + 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), + 'base' : self.targetCustomCBBaseItems. IsChecked(), + 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), + 'name' : self.targetCustomOptionalName.GetValue(), + } + + def Deserialize(self, init): + if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) + if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) + if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) + if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) + if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) + if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) + if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) + if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) + if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) + if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) + + +####### Target Enemy +class TargetEnemyCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) + targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetEnemyModeChoice.SetSelection(0) + targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetEnemySizer + + def MakeBindString(self): + choice = self.targetEnemyModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetenemy" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetEnemyModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) + +####### Target Friend +class TargetFriendCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) + targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetFriendModeChoice.SetSelection(0) + targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetFriendSizer + + def MakeBindString(self): + choice = self.targetFriendModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetfriend" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetFriendModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) + +####### Team/Pet Select +class TeamPetSelectCmd(PowerBindCmd): + def BuildUI(self, dialog): + teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], + style=wx.ALIGN_CENTER_VERTICAL) + self.teamPetSelectNumber.SetSelection(0) + teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) + + return teamPetSelectSizer + + def MakeBindString(self): + teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' + targetNumber = self.teamPetSelectNumber.GetSelection()+1 + + return f"{teamOrPet}select {targetNumber}" + + def Serialize(self): + return { + 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', + 'targetNum': self.teamPetSelectNumber.GetSelection(), + } + + def Deserialize(self, init): + ToP = init.get('teamOrPet', '') + if ToP == 'pet': + self.teamPetSelectPetRB.SetValue(True) + else: + self.teamPetSelectTeamRB.SetValue(True) + if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) + +####### Unselect +class UnselectCmd(PowerBindCmd): + def MakeBindString(self): + return 'unselect' + +####### Use Insp By Name +class UseInspByNameCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) + for _, types in GameData.Inspirations.items(): + for _, info in types.items(): + for insp in info['tiers']: + name = re.sub(' ', '', str(insp)) + icon = GetIcon(f'Inspirations/{name}') + self.useInspByNameModeChoice.Append(insp, icon) + self.useInspByNameModeChoice.SetSelection(0) + useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) + + return useInspByNameSizer + + def MakeBindString(self): + choice = self.useInspByNameModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "inspexecname " + mode.lower() + + def GetAllInsps(self): + Insplist = [] + for _, info in GameData.Inspirations.items(): + for insp in info['tiers']: + Insplist.append(insp) + Insplist.append("---") + Insplist.pop(-1) # snip the terminal "---" + + return Insplist + + def Serialize(self): + return { 'insp' : self.useInspByNameModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) + +####### Use Insp From Row / Column +class UseInspRowColCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnRow.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) + self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnCol.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) + + return useInspRowColumnSizer + + def MakeBindString(self): + row = self.useInspRowColumnRow.GetSelection()+1 + col = self.useInspRowColumnCol.GetSelection()+1 + + return f"inspexectray {col} {row}" + + def Serialize(self): + return { + 'col' : self.useInspRowColumnCol.GetSelection(), + 'row' : self.useInspRowColumnRow.GetSelection(), + } + + def Deserialize(self, init): + if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) + if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) + +####### Use Power +class UsePowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + outerSizer = wx.BoxSizer(wx.HORIZONTAL) + + usePowerSizer = wx.GridBagSizer(5,5) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBToggle, (0,1)) + self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOn, (0,2)) + self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOff, (0,3)) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerName = PowerPicker(dialog) + usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) + usePowerSizer.AddGrowableCol(3) + + outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) + + return outerSizer + + def MakeBindString(self): + if self.usePowerRBToggle.GetValue(): + method = "powexecname" + elif self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') + return '' + + return f"{method} {self.usePowerName.GetLabel()}" + + def Serialize(self): + if self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + method = "powexecname" + return { + 'method': method, + 'pname' : self.usePowerName.GetLabel(), + 'picon' : self.usePowerName.IconFilename + } + + def Deserialize(self, init): + method = init.get('method', '') + if method == 'powexectoggleon': + self.usePowerRBOn.SetValue(True) + elif method == 'powexectoggleoff': + self.usePowerRBOff.SetValue(True) + else: + self.usePowerRBToggle.SetValue(True) + if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) + +####### Use Power From Tray +class UsePowerFromTrayCmd(PowerBindCmd): + def BuildUI(self, dialog): + usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTrayTray = wx.Choice(dialog, -1, + choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', + 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) + self.usePowerFromTrayTray.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) + self.usePowerFromTraySlot.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return usePowerFromTraySizer + + def MakeBindString(self): + choice = self.usePowerFromTrayTray + tray = choice.GetSelection() + + choice = self.usePowerFromTraySlot + slot = choice.GetSelection()+1 + + mode = "slot" + mode2 = '' + if tray > 3: + mode = "tray" + mode2 = f" {tray - 3}" + elif tray == 3: + mode = "alt2slot" + elif tray == 2: + mode = "altslot" + + return f"powexec{mode} {slot}{mode2}" + + def Serialize(self): + return { + 'tray' : self.usePowerFromTrayTray.GetSelection(), + 'slot' : self.usePowerFromTraySlot.GetSelection(), + } + + def Deserialize(self, init): + if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) + if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) + +####### Window Color +class WindowColorCmd(PowerBindCmd): + def BuildUI(self, dialog): + windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) + borderSizer = wx.BoxSizer(wx.VERTICAL) + self.ColorBorder.SetSizer(borderSizer) + self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) + borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) + + windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) + + RGBASizer = wx.FlexGridSizer(3, 4, 5) + + RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) + self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) + self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + windowColorSizer.Add(RGBASizer) + + self.UpdateFromSlider() + + return windowColorSizer + + def MakeBindString(self): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + return f"windowcolor {Rval} {Gval} {Bval} {Aval}" + + def Serialize(self): + return { + 'Rval' : self.RSlider.GetValue(), + 'Gval' : self.GSlider.GetValue(), + 'Bval' : self.BSlider.GetValue(), + 'Aval' : self.ASlider.GetValue(), + } + + def Deserialize(self, init): + self.RSlider.SetValue(init['Rval']) + self.GSlider.SetValue(init['Gval']) + self.BSlider.SetValue(init['Bval']) + self.ASlider.SetValue(init['Aval']) + self.UpdateFromSlider() + + def UpdateFromSlider(self, _ = None): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RReadout.SetValue(Rval) + self.GReadout.SetValue(Gval) + self.BReadout.SetValue(Bval) + self.AReadout.SetValue(Aval) + self.ColorBorder.Refresh() + + def UpdateFromText(self, _ = None): + Rval = self.RReadout.GetValue() + Gval = self.GReadout.GetValue() + Bval = self.BReadout.GetValue() + Aval = self.AReadout.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RSlider.SetValue(Rval) + self.GSlider.SetValue(Gval) + self.BSlider.SetValue(Bval) + self.ASlider.SetValue(Aval) + self.ColorBorder.Refresh() + +####### Window Save / Load +class WindowSaveLoadCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) + self.CommandChoice.SetSelection(0) + sizer.Add(self.CommandChoice, 0, wx.ALL, 5) + + self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), + value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) + sizer.Add(self.FilePath, 0, wx.ALL, 5) + + return sizer + + def MakeBindString(self): + command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] + return f'{command} "{self.FilePath.GetValue()}"' + + def Serialize(self): + return { + 'command' : self.CommandChoice.GetSelection(), + 'filename' : self.FilePath.GetValue(), + } + + def Deserialize(self, init): + self.CommandChoice.SetSelection(init.get('command', 0)) + self.FilePath.SetValue(init.get('filename', '')) + +####### Window Toggle +class WindowToggleCmd(PowerBindCmd): + def BuildUI(self, dialog): + self.WindowNames = { + 'Actions' : 'actions', + 'Auction House' : 'ah', + 'Badge' : 'badge', + 'Channel Search' : 'chansearch', + 'Chat' : 'chat', + 'Custom Chat 1' : 'chat1', + 'Custom Chat 2' : 'chat2', + 'Custom Chat 3' : 'chat3', + 'Custom Chat 4' : 'chat4', + 'Clues' : 'clue', + 'Combat Numbers' : 'combatnumbers', + 'Contacts' : 'contact', + 'Contact Finder' : 'contactfinder', + 'Costumes' : 'costume', + 'Email' : 'email', + 'Enhancements' : 'enhancements', + 'Friends' : 'friend', + 'Group' : 'group', + 'Help' : 'helpwindow', + 'Incarnate' : 'incarnate', + 'Inspirations' : 'insp', + 'League' : 'league', + 'LFG' : 'lfg', + 'Map' : 'map', + 'Mission' : 'mission', + 'Nav / Compass' : 'nav', + 'Options' : 'options', + 'Pets' : 'pet', + 'Petition' : 'petition', + 'Power Tray' : 'powers', + 'Power List' : 'powerlist', + 'Quit' : 'quit', + 'Recipes' : 'recipe', + 'Salvage' : 'salvage', + 'Search' : 'search', + 'Supergroup' : 'sg', + 'Target' : 'target', + 'Team' : 'team', + 'Tray' : 'tray', + 'Tray1' : 'tray1', + 'Tray2' : 'tray2', + 'Tray3' : 'tray3', + 'Tray4' : 'tray4', + 'Tray5' : 'tray5', + 'Tray6' : 'tray6', + 'Tray7' : 'tray7', + 'Tray8' : 'tray8', + 'Vault' : 'vault', + } + + self.ShortToggleCommands = { + 'Auction House' : 'ah', + 'Chat' : 'chat', + 'Help' : 'helpwindow', + 'Map' : 'map', + 'Nav / Compass' : 'nav', + 'Power Tray' : 'powers', + 'Target' : 'target', + 'Tray' : 'tray', + } + + windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) + windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) + self.windowToggleTray.SetSelection(0) + windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.windowShowRB = wx.RadioButton(dialog, -1, "Show") + self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") + + windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) + + return windowToggleSizer + + def MakeBindString(self): + choice = self.windowToggleTray + index = choice.GetSelection() + windowdesc = choice.GetString(index) + windowname = self.WindowNames[windowdesc] + + if self.windowShowRB.GetValue(): + return 'show ' + windowname + elif self.windowHideRB.GetValue(): + return 'windowhide ' + windowname + else: + if shortcmd := self.ShortToggleCommands.get(windowdesc, None): + return shortcmd + else: + return 'toggle ' + windowname + + + def Serialize(self): + choice = self.windowToggleTray + if self.windowShowRB.GetValue(): + action = "Show" + elif self.windowHideRB.GetValue(): + action = "Hide" + else: + action = "Toggle" + return { + 'window': choice.GetString(choice.GetSelection()), + 'action': action, + } + + def Deserialize(self, init): + choice = self.windowToggleTray + if window := init.get('window', ''): + if isinstance(window, int): + choice.SetSelection(window) + else: + choice.SetSelection(choice.FindString(window)) + + if choice.GetSelection() == wx.NOT_FOUND: + choice.SetSelection(0) + + action = init.get('action', '') + if action == "Show": + self.windowShowRB.SetValue(True) + elif action == "Hide": + self.windowHideRB.SetValue(True) + else: + self.windowToggleRB.SetValue(True) + + +# Must always add to this list when adding a new command class above +menuStructure = { + 'Graphics / UI' : [ + 'Attribute Monitor', + 'Buff Display Settings', + 'Graphics Settings', + 'Window Color', + 'Window Save / Load', + 'Window Toggle', + ], + 'Inspirations' : [ + 'Use Inspiration By Name', + 'Use Inspiration From Row/Column', + ], + 'Powers' : [ + 'Auto Power', + 'Power Abort', + 'Power Unqueue', + 'Use Power', + 'Use Power From Tray', + ], + 'Social' : [ + 'Away From Keyboard', + 'Chat Command', + 'Chat Command (Global)', + 'Costume Change', + 'Emote', + 'Supergroup Mode', + ], + 'Targeting' : [ + 'Target Custom', + 'Target Enemy', + 'Target Frield', + 'Team/Pet Select', + 'Unselect', + ], + 'Misc' : [ + 'Load Binds Directory', + 'Movement Commands', + ], + # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, + # but I'm leaving it here to remind myself that we do that. + } + +# Must always add to this list when adding a new command class above +commandClasses = { + 'Auto Power' : AutoPowerCmd, + 'Away From Keyboard' : AFKCmd, + 'Attribute Monitor' : AttributeMonitorCmd, + 'Buff Display Settings' : BuffDisplayCmd, + 'Chat Command' : ChatCmd, + 'Chat Command (Global)' : ChatGlobalCmd, + 'Costume Change' : CostumeChangeCmd, + 'Custom Bind' : CustomBindCmd, + 'Emote' : EmoteCmd, + 'Graphics Settings' : GraphicsCmd, + 'Load Binds Directory' : LoadBindsDir, + 'Movement Commands' : MovementCmd, + 'Power Abort' : PowerAbortCmd, + 'Power Unqueue' : PowerUnqueueCmd, + 'Supergroup Mode' : SGModeCmd, + 'Target Custom' : TargetCustomCmd, + 'Target Enemy' : TargetEnemyCmd, + 'Target Friend' : TargetFriendCmd, + 'Team/Pet Select' : TeamPetSelectCmd, + 'Unselect' : UnselectCmd, + 'Use Inspiration By Name' : UseInspByNameCmd, + 'Use Inspiration From Row/Column' : UseInspRowColCmd, + 'Use Power' : UsePowerCmd, + 'Use Power From Tray' : UsePowerFromTrayCmd, + 'Window Color' : WindowColorCmd, + 'Window Save / Load' : WindowSaveLoadCmd, + 'Window Toggle' : WindowToggleCmd, +} +# use these when we rename a commandClass so that old Profiles will still load correctly. +# If we've also updated the class, we need to try to make sure the new class will still +# Deserialize the legacy data, or at least not crash. +deprecatedCommandClasses = { + 'SG Mode Toggle' : SGModeCmd, + 'Use Insp By Name' : UseInspByNameCmd, + 'Use Insp From Row/Column' : UseInspRowColCmd, +} +commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/UnselectCmd.py b/UI/PowerBinderCommand/UnselectCmd.py new file mode 100644 index 0000000..4c02ab7 --- /dev/null +++ b/UI/PowerBinderCommand/UnselectCmd.py @@ -0,0 +1,1800 @@ +import wx +import re +import UI +import UI.EmotePicker +from UI.ControlGroup import ControlGroup +from UI.PowerPicker import PowerPicker +from Help import HelpButton +import wx.adv +from wx.adv import BitmapComboBox, EditableListBox +from pathlib import PureWindowsPath +import GameData +import Profile +from Icon import GetIcon + +class PowerBinderDialog(wx.Dialog): + def __init__(self, parent, button, init = {}): + wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) + + self.Page = parent.Page + self.EditDialog = PowerBinderEditDialog(self) + self.Button = button + self.AddStepMenu = self.makeAddStepMenu() + + sizer = wx.BoxSizer(wx.VERTICAL); + self.mainSizer = sizer + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) + # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) + # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) + #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) + AddStepButton = wx.Button(self, -1, 'Add Step') + AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) + AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) + choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) + choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) + sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) + + rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) + + self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) + self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) + self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) + rearrangeCtrl.Add(self.RearrangeList, 1) + + rearrangeButtons = wx.BoxSizer(wx.VERTICAL) + self.DelButton = wx.Button(self, -1, "Delete") + self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) + self.EditButton = wx.Button(self, -1, "Edit") + self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) + self.EditButton.Disable() + upButton = wx.Button(self, -1, "\u25B2") + upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) + downButton = wx.Button(self, -1, "\u25BC") + downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) + rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) + rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) + + sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.BindStringDisplay = wx.TextCtrl(self, -1) + self.BindStringDisplay.Disable() + choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, + wx.ALIGN_CENTER_VERTICAL) + choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) + + sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) + + sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) + + # need to dig around and get the OK button since we show this dialog modelessly now. + okButton = self.FindWindow(self.GetAffirmativeId()) + okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) + + # Wrap everything in a vbox to add some padding + vbox = wx.BoxSizer(wx.VERTICAL); + vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); + + self.SetSizerAndFit(vbox); + self.Layout() + self.Fit() + self.SetFocus() + + # if we are loading from profile, ie, have "init", build the list from it + if init: self.LoadFromData(init) + + def LoadFromData(self, init): + for item in init: + for type, data in item.items(): + commandClass = commandClasses.get(type, None) + if not commandClass: + commandClass = deprecatedCommandClasses.get(type, None) + if not commandClass: + wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") + continue + newCommand = commandClass(self.EditDialog, data) + index = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.SetClientData(index, newCommand) + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) + self.EditDialog.mainSizer.Hide(newCommand.UI) + self.UpdateBindStringDisplay() + + def SaveToData(self): + data = [] + index = 0 + for _ in self.RearrangeList.GetItems(): + # check whether we have an object already attached to this choice + cmdObject = self.RearrangeList.GetClientData(index) + commandClassName = commandRevClasses[type(cmdObject)] + data.append({commandClassName: cmdObject.Serialize()}) + index = index + 1 + return data + + def OnAddStepButton(self, evt): + button = evt.EventObject + if not self.AddStepMenu: + self.AddStepMenu = self.makeAddStepMenu() + button.PopupMenu(self.AddStepMenu) + + + def OnOKButton(self, _): + if self.Button.tgtTxtCtrl: + bindString = self.MakeBindString() + if bindString != self.Button.tgtTxtCtrl.GetValue(): + self.Button.tgtTxtCtrl.SetValue(bindString) + wx.App.Get().Main.Profile.SetModified() + self.Close() + + def OnRearrangeDelete(self, _): + current = self.RearrangeList.GetSelection() + if current == wx.NOT_FOUND: return + + self.RearrangeList.Delete(current) + self.UpdateBindStringDisplay() + + def OnRearrangeUp(self, _): + self.RearrangeList.MoveCurrentUp() + self.UpdateBindStringDisplay() + + def OnRearrangeDown(self, _): + self.RearrangeList.MoveCurrentDown() + self.UpdateBindStringDisplay() + + def OnRearrangeEdit(self, _): + index = self.RearrangeList.GetSelection() + + # check whether we have an object already attached to this choice + cmdObject = None + try: + cmdObject = self.RearrangeList.GetClientData(index) + except Exception: + pass + + if cmdObject: + self.ShowEditDialogFor(cmdObject) + self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) + else: + print("cmdObject was None") + self.UpdateBindStringDisplay() + + # OnAddStepMenu creates a new step and adds it to the rearrangelist + def OnAddStepMenu(self, evt): + menuitem = self.AddStepMenu.FindItemById(evt.GetId()) + chosenName = menuitem.GetItemLabel() + + # make a new command object, attached to the parent dialog + newCommandClass = commandClasses[chosenName] + newCommand = newCommandClass(self.EditDialog) + + # show the edit dialog if this command needs it + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) + if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): + self.EditDialog.mainSizer.Remove(newCommand.UI) + return + + newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.Select(newBindIndex) + self.RearrangeList.SetClientData(newBindIndex, newCommand) + + self.OnListSelect() + self.UpdateBindStringDisplay() + + def OnListSelect(self, _ = None): + selected = self.RearrangeList.GetSelection() + + if selected != wx.NOT_FOUND: + selCommand = self.RearrangeList.GetClientData(selected) + if selCommand.UI: + self.EditButton.Enable() + else: + self.EditButton.Disable() + + def UpdateBindStringDisplay(self): + self.BindStringDisplay.SetValue(self.MakeBindString()) + self.BindStringDisplay.SetToolTip(self.MakeBindString()) + + def MakeBindString(self): + cmdBindStrings = [] + for index in range(self.RearrangeList.GetCount()): + c = self.RearrangeList.GetClientData(index) + if c: cmdBindStrings.append(c.MakeBindString()) + + bindstring = ('$$'.join(cmdBindStrings)) + return bindstring + + def ShowEditDialogFor(self, command): + if not command.UI: return + + self.EditDialog.mainSizer.Show(command.UI) + + self.EditDialog.Layout() + self.EditDialog.Fit() + + self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') + returnval = self.EditDialog.ShowModal() + + self.EditDialog.mainSizer.Hide(command.UI) + + return returnval + + def makeAddStepMenu(self): + + stepMenu = wx.Menu() + + for subname in menuStructure: + submenu = wx.Menu() + stepMenu.AppendSubMenu(submenu, subname) + for classname in menuStructure[subname]: + submenu.Append(wx.ID_ANY, classname) + + stepMenu.Append(wx.ID_ANY, 'Custom Bind') + + return stepMenu + +class PowerBinderButton(wx.BitmapButton): + + def __init__(self, parent, tgtTxtCtrl, init = {}): + wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) + self.Init = init + self.Dialog = None + self.DialogParent = parent + + self.tgtTxtCtrl = tgtTxtCtrl + self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) + self.SetToolTip("Launch PowerBinder") + + def PowerBinderEventHandler(self, _): + self.PowerBinderDialog().Show() + + def LoadFromData(self, data): + self.PowerBinderDialog().LoadFromData(data) + + def SaveToData(self): + return self.PowerBinderDialog().SaveToData() + + def PowerBinderDialog(self): + if not self.Dialog: + self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) + return self.Dialog + + +class PowerBinderEditDialog(wx.Dialog): + def __init__(self, parent): + wx.Dialog.__init__(self, parent, -1, "Edit Step", + style = wx.DEFAULT_DIALOG_STYLE) + + outerSizer = wx.BoxSizer(wx.VERTICAL) + + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + self.mainSizer.SetMinSize([500, 150]) + + self.Page = parent.Page + + self.mainSizer.Add( + self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), + 0, wx.EXPAND|wx.ALL, 10) + + outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) + + self.SetSizerAndFit(outerSizer) + self.Layout() + self.Fit() + +########### Power Binder Command Objects +class PowerBindCmd(): + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + commandClassName = commandRevClasses[type(self)] + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{commandClassName} - {short_bindstr}" + + +####### Away From Keyboard +class AFKCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) + +####### Attribute Monitor +class AttributeMonitorCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.Groups = {} + self.AttributeTable = { + 'Base' : { + 'Current Hit Points' : 'NT H', + 'Max Hit Points' : 'X H', + 'Current Endurance' : 'T E', + 'Max Endurance' : 'X EN', + 'Regeneration Rate' : 'N RAT', + 'Recovery Rate' : 'Y RA', + 'Endurance Consumption' : 'SU', + 'ToHit Bonus' : 'T B', + 'Accuracy Bonus' : 'CC', + 'Last Hit Chance' : 'T C', + 'Damage Bonus' : 'DA', + 'Healing Bonus' : 'NG B', + 'Recharge Time Bonus' : 'ME B', + 'Endurance Discount' : 'CE DIS', + 'Stealth Radius (PvP)' : 'PVP', + 'Stealth Radius (PvE)' : 'PVE', + 'Perception Radius' : 'RC', + 'Range Bonus' : 'GE B', + 'Threat Level' : 'AT L', + 'Experience to Next Level' : 'XT', + 'Experience Debt' : 'XP', + 'Influence / Infamy' : 'INF', + 'Inherent' : 'NH', + }, + 'Movement Speed' : { + 'Flying Speed' : 'FL', + 'Jumping Speed' : 'PI', + 'Max Jump Height' : 'X J', + 'Run Speed' : 'RU', + }, + 'Damage Resistance' : { + 'Smashing Resistance' : 'G R', + 'Lethal Resistance' : 'L R', + 'Fire Resistance' : 'RE R', + 'Cold Resistance' : 'COLD R', + 'Energy Resistance' : 'DamageType[4]', + 'Negative Energy Resistance' : 'GY R', + 'Psyonic Resistance' : 'NIC R', + 'Toxic Resistance' : 'XIC R', + }, + 'Defense' : { + 'Base Defense' : 'BAS', + 'Ranged Defense' : 'ED', + 'Melee Defense' : 'MEL', + 'AoE Defense' : '2', + 'Smashing Defense' : '3', + 'Lethal Defense' : '4', + 'Fire Defense' : '5', + 'Cold Defense' : '6', + 'Energy Defense' : '7', + 'Negative Energy Defense' : '8', + 'Psionic Defense' : '9', + 'Toxic Defense' : '1', + }, + 'Debuff Resistance' : { + 'Regeneration Resistance' : 'ON R', + 'Recovery Resistance' : 'RY R', + 'To Hit Resistance' : 'IT R', + 'Defense Resistance' : 'NSE RES', + }, + 'Status Effect Protection' : { + 'Hold Protection' : 'D P', + 'Immobilize Protection' : 'LIZE P', + 'Stun Protection' : 'N P', + 'Sleep Protection' : 'P P', + 'Knockback Protection' : 'K P', + 'Confuse Protection' : 'SE P', + 'Terrorize Protection' : 'ZE P', + 'Repel Protection' : 'EL P', + 'Teleport Protection' : 'T P', + }, + 'Status Effect Resistance' : { + 'Hold Resistance' : 'D R', + 'Immobilize Resistance' : 'LIZE R', + 'Stun Resistance' : 'N R', + 'Sleep Resistance' : 'P R', + 'Knockback Resistance' : 'K R', + 'Confuse Resistance' : 'SE R', + 'Terrorize Resistance' : 'ZE R', + 'Placate Resistance' : 'TE R', + 'Taunt Resistance' : 'NT R', + }, + 'Miscellaneous' : { + 'Level Shift' : 'L S', + }, + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.AttributeMenu = wx.Menu() + for group, controls in self.AttributeTable.items(): + submenu = wx.Menu() + self.AttributeMenu.AppendSubMenu(submenu, group) + for cb in controls: + submenu.Append(wx.ID_ANY, cb) + + self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) + + self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) + groupSizer.Add(self.editbox) + + newButton = self.editbox.GetNewButton() + newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) + + return groupSizer + + def MakeBindString(self): + map = {} + bindstrings = [] + for _, controls in self.AttributeTable.items(): + for cb, data in controls.items(): + map[cb] = data + + for string in self.editbox.GetStrings(): + if string: + bindstrings.append(f'monitorattribute {map[string]}') + + return '$$'.join(bindstrings) + + def Serialize(self): + return { + 'attributes' : self.editbox.GetStrings() + } + + def Deserialize(self, init): + self.editbox.SetStrings(init.get('attributes', [])) + + def OnNewButton(self, evt): + evt.GetEventObject().PopupMenu(self.AttributeMenu) + + def OnMenuItem(self, evt): + menuitem = evt.EventObject.FindItemById(evt.GetId()) + existingstrings = self.editbox.GetStrings() + existingstrings.append(menuitem.GetItemLabel()) + self.editbox.SetStrings(existingstrings) + +####### Auto Power +class AutoPowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) + autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.autoPowerName = PowerPicker(dialog) + autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) + + return autoPowerSizer + + def MakeBindString(self): + return f"powexecauto {self.autoPowerName.GetLabel()}" + + def Serialize(self): + return { + 'pname' : self.autoPowerName.GetLabel(), + 'picon' : self.autoPowerName.IconFilename + } + + def Deserialize(self, init): + if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) + +####### Buff Display Command +class BuffDisplayCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.buffDisplayMap = { + 'Status Window' : { + 'Hide Auto' : 1, + 'Hide Toggles' : 2, + 'No Blinking' : 4, + 'No Stacking' : 8, + 'Numeric Stacking' : 16, + 'Hide Buff Numbers' : 32, + 'Stop Sending Buffs' : 64, + }, + 'Group Window' : { + 'Hide Auto' : 256, + 'Hide Toggles' : 512, + 'No Blinking' : 1024, + 'No Stacking' : 2048, + 'Numeric Stacking' : 4096, + 'Hide Buff Numbers' : 8192, + 'Stop Sending Buffs' : 16384, + }, + 'Pet Window' : { + 'Hide Auto' : 65536, + 'Hide Toggles' : 131072, + 'No Blinking' : 262144, + 'No Stacking' : 524288, + 'Numeric Stacking' : 1048576, + 'Hide Buff Numbers' : 2097152, + 'Stop Sending Buffs' : 4194304, + }, + } + self.Groups = {} + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + for group, controls in self.buffDisplayMap.items(): + self.Groups[group] = ControlGroup(dialog, self.Page, label = group) + groupid = self.Groups[group].GetStaticBox().GetId() + for cb, data in controls.items(): + self.Groups[group].AddControl( + ctlType = 'checkbox', + ctlName = f"{groupid}_{group}_{cb}", + label = cb, + data = data, + ) + + groupSizer.Add(self.Groups[group]) + + return groupSizer + + def CalculateValue(self): + page = wx.App.Get().Main.Profile.CustomBinds + + total = 0 + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] + if checkbox.IsChecked(): + total = total + checkbox.Data + return total + + def MakeBindString(self): + return f"optionset buffsettings {self.CalculateValue()}" + + def Serialize(self): + return { 'value' : self.CalculateValue() } + + def Deserialize(self, init): + value = init.get('value', 0) + + value = value or 0 # in case we had for some reason 'None' stashed in the init values + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] + checkbox.SetValue( checkbox.Data & value ) + +####### Chat Command +class ChatCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.chatChannelMap = { # before __init__ + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + chatCommandSizer = wx.GridBagSizer(5, 5) + self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") + chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) + # row 1 + self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) + self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) + self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) + # row 2 + self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) + self.chatCommandDuration.SetRange(1, 20) + self.chatCommandDuration.SetValue(7) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandDuration, (2,1)) + self.chatCommandChatSize = wx.Choice(dialog, -1, + choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) + self.chatCommandChatSize.SetSelection(5) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) + self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) + self.chatCommandChannel.SetSelection(0) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChannel, (2,5)) + # row 3 + self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") + chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) + self.chatCommandMessage = wx.TextCtrl(dialog, -1) + self.chatCommandMessage.SetHint('Chat Command Text') + chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) + + return chatCommandSizer + + def MakeBindString(self): + duration = self.chatCommandDuration.GetValue() + + choice = self.chatCommandChatSize + index = choice.GetSelection() + size = choice.GetString(index) + + duration = f"" if duration != 7 else "" + size = f"" if size != "1" else "" + + bdcolor = fgcolor = bgcolor = '' + if self.chatCommandUseColorsCB.IsChecked(): + bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + + bdcolor = f"" + fgcolor = f"" + bgcolor = f"" + + beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' + text = self.chatCommandMessage.GetValue() + + choice = self.chatCommandChannel + index = choice.GetSelection() + channel = choice.GetString(index) + + return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" + + def Serialize(self): + return { + 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), + 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), + 'channel' : self.chatCommandChannel .GetSelection(), + 'size' : self.chatCommandChatSize.GetSelection(), + 'duration' : self.chatCommandDuration.GetValue(), + 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'text' : self.chatCommandMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) + if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) + if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) + if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) + if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) + if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) + if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) + if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) + if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) + + +####### Chat Command Global +class ChatGlobalCmd(PowerBindCmd): + def BuildUI(self, dialog): + chatCommandGlobalSizer = wx.GridBagSizer(5,5) + + self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") + chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) + + self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalChannel.SetHint("Channel") + chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) + + self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') + chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) + + chatCommandGlobalSizer.AddGrowableCol(1) + + return chatCommandGlobalSizer + + def MakeBindString(self): + useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() + channel = self.chatCommandGlobalChannel.GetValue() + message = self.chatCommandGlobalMessage.GetValue() + + preface = "beginchat /" if useBeginchat else "" + + return f'{preface}send "{channel}" {message}' + + def Serialize(self): + return { + 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), + 'channel' : self.chatCommandGlobalChannel.GetValue(), + 'message' : self.chatCommandGlobalMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) + if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) + if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) + +#######Costume Change +class CostumeChangeCmd(PowerBindCmd): + def BuildUI(self, dialog): + costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeCostume = wx.Choice(dialog, -1, + choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) + self.costumeChangeCostume.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeEmote = wx.Choice(dialog, -1, + choices = GameData.Emotes['costumechange']) + self.costumeChangeEmote.Insert("- None -", 0) + self.costumeChangeEmote.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return costumeChangeSizer + + def MakeBindString(self): + costumeNumber = self.costumeChangeCostume.GetSelection() + costumeEmote = self.costumeChangeEmote.GetSelection() + + if costumeEmote: # None, or 0 == "- None -" + ccCmd = 'cce' + emoteName = self.costumeChangeEmote.GetString(costumeEmote) + emoteName = " CC" + emoteName.replace(" ","") + else: + ccCmd = 'cc' + emoteName = '' + + return f"{ccCmd} {costumeNumber}{emoteName}" + + def Serialize(self): + return{ + 'costumeNumber': self.costumeChangeCostume.GetSelection(), + 'costumeEmote' : self.costumeChangeEmote.GetSelection(), + } + + def Deserialize(self, init): + if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) + if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) + +####### Movement Command +class MovementCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + self.plusbutton.SetValue(True) + + self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.commandchoice = wx.Choice(dialog, choices = [ + "forward", "left", "right", "backward", "up", "down", + "turnleft", "turnright", "first", "autorun", "clicktomove", + ],) + sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) + self.commandchoice.SetSelection(0) + + self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + pre = post = '' + if self.plusbutton.GetValue() : pre = "+" + elif self.plusplusbutton.GetValue() : pre = "++" + elif self.minusbutton.GetValue() : pre = "-" + elif self.zerobutton.GetValue() : post = " 0" + elif self.onebutton.GetValue() : post = " 1" + + command = self.commandchoice.GetString(self.commandchoice.GetSelection()) + + return f"{pre}{command}{post}" + + def Serialize(self): + mod = '' + if self.plusbutton.GetValue() : mod = "plus" + elif self.plusplusbutton.GetValue() : mod = "plusplus" + elif self.minusbutton.GetValue() : mod = "minus" + elif self.zerobutton.GetValue() : mod = "zero" + elif self.onebutton.GetValue() : mod = "one" + + return { + 'mod' : mod, + 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), + } + + def Deserialize(self, init): + mod = init.get('mod', 'plus') + + if mod == 'plus' : self.plusbutton.SetValue(True) + elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) + elif mod == 'minus' : self.minusbutton.SetValue(True) + elif mod == 'zero' : self.zerobutton.SetValue(True) + elif mod == 'one' : self.onebutton.SetValue(True) + + self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) + +####### Graphics Command +class GraphicsCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.FlexGridSizer(2) + + self.visscalecb = wx.CheckBox(dialog, label = "visscale") + sizer.Add(self.visscalecb) + self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) + sizer.Add(self.visscalesc) + + self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") + sizer.Add(self.dofweightcb) + self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) + sizer.Add(self.dofweightsc) + + self.fsaacb = wx.CheckBox(dialog, label = "fsaa") + sizer.Add(self.fsaacb) + self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) + self.fsaach.SetSelection(0) + sizer.Add(self.fsaach) + + self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") + sizer.Add(self.bloomscalecb) + self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) + self.bloomscalech.SetSelection(0) + sizer.Add(self.bloomscalech) + + self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") + sizer.Add(self.bloomweightcb) + self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) + sizer.Add(self.bloomweightsc) + + self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") + sizer.Add(self.lodbiascb) + self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) + sizer.Add(self.lodbiassc) + + self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") + sizer.Add(self.renderscalecb) + self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) + sizer.Add(self.renderscalesc) + + return sizer + + def MakeBindString(self): + # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. + bindstrings = [] + if self.visscalecb.IsChecked(): + bindstrings.append("visscale " + str(self.visscalesc.GetValue())) + if self.dofweightcb.IsChecked(): + bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) + if self.fsaacb.IsChecked(): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bindstrings.append("fsaa " + fsaavalue) + if self.bloomscalecb.IsChecked(): + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + bindstrings.append("bloomscale " + bloomscalevalue) + if self.bloomweightcb.IsChecked(): + bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) + if self.lodbiascb.IsChecked(): + bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) + if self.renderscalecb.IsChecked(): + bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) + + return '$$'.join(bindstrings) + + def Serialize(self): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + return { + 'visscalecb' : self.visscalecb.IsChecked(), + 'visscalesc' : self.visscalesc.GetValue(), + 'dofweightcb' : self.dofweightcb.IsChecked(), + 'dofweightsc' : self.dofweightsc.GetValue(), + 'fsaacb' : self.fsaacb.IsChecked(), + 'fsaach' : fsaavalue, + 'bloomscalecb' : self.bloomscalecb.IsChecked(), + 'bloomscalech' : bloomscalevalue, + 'bloomweightcb' : self.bloomweightcb.IsChecked(), + 'bloomweightsc' : self.bloomweightsc.GetValue(), + 'lodbiascb' : self.lodbiascb.IsChecked(), + 'lodbiassc' : self.lodbiassc.GetValue(), + 'renderscalecb' : self.renderscalecb.IsChecked(), + 'renderscalesc' : self.renderscalesc.GetValue(), + } + + def Deserialize(self, init): + self.visscalecb.SetValue(init.get('visscalecb', False)) + self.visscalesc.SetValue(init.get('visscalesc', 1.0)) + self.dofweightcb.SetValue(init.get('dofweightcb', False)) + self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) + self.fsaacb.SetValue(init.get('fsaacb', False)) + self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) + self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) + self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) + self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) + self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) + self.lodbiascb.SetValue(init.get('lodbiascb', False)) + self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) + self.renderscalecb.SetValue(init.get('renderscalecb', False)) + self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) + +####### Custom Bind +class CustomBindCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.customBindName = wx.TextCtrl(dialog, -1) + self.customBindName.SetHint('Custom Bind Text') + sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + return self.customBindName.GetValue() + + def Serialize(self): + return { 'customBindName': self.customBindName.GetValue() } + + def Deserialize(self,init): + if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) + +####### Emote +class EmoteCmd(PowerBindCmd): + def BuildUI(self, dialog): + emoteSizer = wx.BoxSizer(wx.HORIZONTAL) + self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") + emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + self.emoteName = wx.Button(dialog, -1, "...") + self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) + emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) + + return emoteSizer + + def MakeBindString(self): + displayedEmoteName = self.emoteName.GetLabel() + actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] + + return actualEmotePayload + + def Serialize(self): + return {'emoteName': self.emoteName.GetLabel()} + + def Deserialize(self, init): + if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) + +####### Load Binds Directory +class LoadBindsDir(PowerBindCmd): + def BuildUI(self, dialog): + mainSizer = wx.BoxSizer(wx.VERTICAL) + + lbSizer = wx.BoxSizer(wx.HORIZONTAL) + lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") + lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + profiles = Profile.GetAllProfileBindsDirs() + + self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) + lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") + self.lbResetCB.SetValue(True) + + mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + return mainSizer + + def MakeBindString(self): + + # If the specified binds directory disappeared between runs, we'd crash, so handle that. + if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' + + config = wx.ConfigBase.Get() + if config.Exists('GameBindPath'): + bindpath = config.Read('GameBindPath') + else: + bindpath = config.Read('BindPath') + + reset = "" + if self.lbResetCB.GetValue(): + reset = "keybind_reset$$" + + resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' + return reset + 'bindloadfile ' + str(resetfilepath) + + def Serialize(self): + return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), + 'ResetKeybinds' : self.lbResetCB.GetValue(), + } + + def Deserialize(self, init): + if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) + self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) + +####### Power Abort +class PowerAbortCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecabort' + +####### Power Unqueue +class PowerUnqueueCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecunqueue' + +####### SG Mode +class SGModeCmd(PowerBindCmd): + def BuildUI(self, dialog): + sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) + sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") + self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") + + sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) + + return sgmodeSizer + + def MakeBindString(self): + if self.sgmodeOnRB.GetValue(): + return 'sgmodeset 1' + elif self.sgmodeOffRB.GetValue(): + return 'sgmodeset 0' + else: + return 'sgmode' + + def Serialize(self): + if self.sgmodeOnRB.GetValue(): + val = "On" + elif self.sgmodeOffRB.GetValue(): + val = "Off" + else: + val = "Toggle" + + return {"value" : val} + + def Deserialize(self, init): + val = init.get('value', '') + if val == "On": + self.sgmodeOnRB.SetValue(True) + elif val == "Off": + self.sgmodeOffRB.SetValue(True) + else: + self.sgmodeToggleRB.SetValue(True) + +####### Target Custom +class TargetCustomCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetCustomSizer = wx.GridBagSizer(5,5) + targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), + flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) + self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetCustomModeChoice.SetSelection(0) + targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) + self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) + self.targetCustomOptionalName.SetHint("Optional name to match") + targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) + self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") + targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) + self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") + targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) + self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") + targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) + self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") + targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) + self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") + targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) + self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") + targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) + self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") + targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) + self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") + targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) + + targetCustomSizer.AddGrowableCol(2) + + return targetCustomSizer + + def MakeBindString(self): + choice = self.targetCustomModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + targetCommand = "targetcustom" + mode.lower() + + enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" + friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" + defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" + alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" + mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" + notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" + base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" + notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" + + name = self.targetCustomOptionalName.GetValue() + + return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" + + def Serialize(self): + return { + 'mode' : self.targetCustomModeChoice.GetSelection(), + 'enemy' : self.targetCustomCBEnemies. IsChecked(), + 'friend' : self.targetCustomCBFriends. IsChecked(), + 'defeated' : self.targetCustomCBDefeated. IsChecked(), + 'alive' : self.targetCustomCBAlive. IsChecked(), + 'mypet' : self.targetCustomCBMyPets. IsChecked(), + 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), + 'base' : self.targetCustomCBBaseItems. IsChecked(), + 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), + 'name' : self.targetCustomOptionalName.GetValue(), + } + + def Deserialize(self, init): + if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) + if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) + if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) + if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) + if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) + if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) + if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) + if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) + if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) + if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) + + +####### Target Enemy +class TargetEnemyCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) + targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetEnemyModeChoice.SetSelection(0) + targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetEnemySizer + + def MakeBindString(self): + choice = self.targetEnemyModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetenemy" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetEnemyModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) + +####### Target Friend +class TargetFriendCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) + targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetFriendModeChoice.SetSelection(0) + targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetFriendSizer + + def MakeBindString(self): + choice = self.targetFriendModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetfriend" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetFriendModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) + +####### Team/Pet Select +class TeamPetSelectCmd(PowerBindCmd): + def BuildUI(self, dialog): + teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], + style=wx.ALIGN_CENTER_VERTICAL) + self.teamPetSelectNumber.SetSelection(0) + teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) + + return teamPetSelectSizer + + def MakeBindString(self): + teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' + targetNumber = self.teamPetSelectNumber.GetSelection()+1 + + return f"{teamOrPet}select {targetNumber}" + + def Serialize(self): + return { + 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', + 'targetNum': self.teamPetSelectNumber.GetSelection(), + } + + def Deserialize(self, init): + ToP = init.get('teamOrPet', '') + if ToP == 'pet': + self.teamPetSelectPetRB.SetValue(True) + else: + self.teamPetSelectTeamRB.SetValue(True) + if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) + +####### Unselect +class UnselectCmd(PowerBindCmd): + def MakeBindString(self): + return 'unselect' + +####### Use Insp By Name +class UseInspByNameCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) + for _, types in GameData.Inspirations.items(): + for _, info in types.items(): + for insp in info['tiers']: + name = re.sub(' ', '', str(insp)) + icon = GetIcon(f'Inspirations/{name}') + self.useInspByNameModeChoice.Append(insp, icon) + self.useInspByNameModeChoice.SetSelection(0) + useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) + + return useInspByNameSizer + + def MakeBindString(self): + choice = self.useInspByNameModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "inspexecname " + mode.lower() + + def GetAllInsps(self): + Insplist = [] + for _, info in GameData.Inspirations.items(): + for insp in info['tiers']: + Insplist.append(insp) + Insplist.append("---") + Insplist.pop(-1) # snip the terminal "---" + + return Insplist + + def Serialize(self): + return { 'insp' : self.useInspByNameModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) + +####### Use Insp From Row / Column +class UseInspRowColCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnRow.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) + self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnCol.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) + + return useInspRowColumnSizer + + def MakeBindString(self): + row = self.useInspRowColumnRow.GetSelection()+1 + col = self.useInspRowColumnCol.GetSelection()+1 + + return f"inspexectray {col} {row}" + + def Serialize(self): + return { + 'col' : self.useInspRowColumnCol.GetSelection(), + 'row' : self.useInspRowColumnRow.GetSelection(), + } + + def Deserialize(self, init): + if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) + if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) + +####### Use Power +class UsePowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + outerSizer = wx.BoxSizer(wx.HORIZONTAL) + + usePowerSizer = wx.GridBagSizer(5,5) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBToggle, (0,1)) + self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOn, (0,2)) + self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOff, (0,3)) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerName = PowerPicker(dialog) + usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) + usePowerSizer.AddGrowableCol(3) + + outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) + + return outerSizer + + def MakeBindString(self): + if self.usePowerRBToggle.GetValue(): + method = "powexecname" + elif self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') + return '' + + return f"{method} {self.usePowerName.GetLabel()}" + + def Serialize(self): + if self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + method = "powexecname" + return { + 'method': method, + 'pname' : self.usePowerName.GetLabel(), + 'picon' : self.usePowerName.IconFilename + } + + def Deserialize(self, init): + method = init.get('method', '') + if method == 'powexectoggleon': + self.usePowerRBOn.SetValue(True) + elif method == 'powexectoggleoff': + self.usePowerRBOff.SetValue(True) + else: + self.usePowerRBToggle.SetValue(True) + if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) + +####### Use Power From Tray +class UsePowerFromTrayCmd(PowerBindCmd): + def BuildUI(self, dialog): + usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTrayTray = wx.Choice(dialog, -1, + choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', + 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) + self.usePowerFromTrayTray.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) + self.usePowerFromTraySlot.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return usePowerFromTraySizer + + def MakeBindString(self): + choice = self.usePowerFromTrayTray + tray = choice.GetSelection() + + choice = self.usePowerFromTraySlot + slot = choice.GetSelection()+1 + + mode = "slot" + mode2 = '' + if tray > 3: + mode = "tray" + mode2 = f" {tray - 3}" + elif tray == 3: + mode = "alt2slot" + elif tray == 2: + mode = "altslot" + + return f"powexec{mode} {slot}{mode2}" + + def Serialize(self): + return { + 'tray' : self.usePowerFromTrayTray.GetSelection(), + 'slot' : self.usePowerFromTraySlot.GetSelection(), + } + + def Deserialize(self, init): + if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) + if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) + +####### Window Color +class WindowColorCmd(PowerBindCmd): + def BuildUI(self, dialog): + windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) + borderSizer = wx.BoxSizer(wx.VERTICAL) + self.ColorBorder.SetSizer(borderSizer) + self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) + borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) + + windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) + + RGBASizer = wx.FlexGridSizer(3, 4, 5) + + RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) + self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) + self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + windowColorSizer.Add(RGBASizer) + + self.UpdateFromSlider() + + return windowColorSizer + + def MakeBindString(self): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + return f"windowcolor {Rval} {Gval} {Bval} {Aval}" + + def Serialize(self): + return { + 'Rval' : self.RSlider.GetValue(), + 'Gval' : self.GSlider.GetValue(), + 'Bval' : self.BSlider.GetValue(), + 'Aval' : self.ASlider.GetValue(), + } + + def Deserialize(self, init): + self.RSlider.SetValue(init['Rval']) + self.GSlider.SetValue(init['Gval']) + self.BSlider.SetValue(init['Bval']) + self.ASlider.SetValue(init['Aval']) + self.UpdateFromSlider() + + def UpdateFromSlider(self, _ = None): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RReadout.SetValue(Rval) + self.GReadout.SetValue(Gval) + self.BReadout.SetValue(Bval) + self.AReadout.SetValue(Aval) + self.ColorBorder.Refresh() + + def UpdateFromText(self, _ = None): + Rval = self.RReadout.GetValue() + Gval = self.GReadout.GetValue() + Bval = self.BReadout.GetValue() + Aval = self.AReadout.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RSlider.SetValue(Rval) + self.GSlider.SetValue(Gval) + self.BSlider.SetValue(Bval) + self.ASlider.SetValue(Aval) + self.ColorBorder.Refresh() + +####### Window Save / Load +class WindowSaveLoadCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) + self.CommandChoice.SetSelection(0) + sizer.Add(self.CommandChoice, 0, wx.ALL, 5) + + self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), + value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) + sizer.Add(self.FilePath, 0, wx.ALL, 5) + + return sizer + + def MakeBindString(self): + command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] + return f'{command} "{self.FilePath.GetValue()}"' + + def Serialize(self): + return { + 'command' : self.CommandChoice.GetSelection(), + 'filename' : self.FilePath.GetValue(), + } + + def Deserialize(self, init): + self.CommandChoice.SetSelection(init.get('command', 0)) + self.FilePath.SetValue(init.get('filename', '')) + +####### Window Toggle +class WindowToggleCmd(PowerBindCmd): + def BuildUI(self, dialog): + self.WindowNames = { + 'Actions' : 'actions', + 'Auction House' : 'ah', + 'Badge' : 'badge', + 'Channel Search' : 'chansearch', + 'Chat' : 'chat', + 'Custom Chat 1' : 'chat1', + 'Custom Chat 2' : 'chat2', + 'Custom Chat 3' : 'chat3', + 'Custom Chat 4' : 'chat4', + 'Clues' : 'clue', + 'Combat Numbers' : 'combatnumbers', + 'Contacts' : 'contact', + 'Contact Finder' : 'contactfinder', + 'Costumes' : 'costume', + 'Email' : 'email', + 'Enhancements' : 'enhancements', + 'Friends' : 'friend', + 'Group' : 'group', + 'Help' : 'helpwindow', + 'Incarnate' : 'incarnate', + 'Inspirations' : 'insp', + 'League' : 'league', + 'LFG' : 'lfg', + 'Map' : 'map', + 'Mission' : 'mission', + 'Nav / Compass' : 'nav', + 'Options' : 'options', + 'Pets' : 'pet', + 'Petition' : 'petition', + 'Power Tray' : 'powers', + 'Power List' : 'powerlist', + 'Quit' : 'quit', + 'Recipes' : 'recipe', + 'Salvage' : 'salvage', + 'Search' : 'search', + 'Supergroup' : 'sg', + 'Target' : 'target', + 'Team' : 'team', + 'Tray' : 'tray', + 'Tray1' : 'tray1', + 'Tray2' : 'tray2', + 'Tray3' : 'tray3', + 'Tray4' : 'tray4', + 'Tray5' : 'tray5', + 'Tray6' : 'tray6', + 'Tray7' : 'tray7', + 'Tray8' : 'tray8', + 'Vault' : 'vault', + } + + self.ShortToggleCommands = { + 'Auction House' : 'ah', + 'Chat' : 'chat', + 'Help' : 'helpwindow', + 'Map' : 'map', + 'Nav / Compass' : 'nav', + 'Power Tray' : 'powers', + 'Target' : 'target', + 'Tray' : 'tray', + } + + windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) + windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) + self.windowToggleTray.SetSelection(0) + windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.windowShowRB = wx.RadioButton(dialog, -1, "Show") + self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") + + windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) + + return windowToggleSizer + + def MakeBindString(self): + choice = self.windowToggleTray + index = choice.GetSelection() + windowdesc = choice.GetString(index) + windowname = self.WindowNames[windowdesc] + + if self.windowShowRB.GetValue(): + return 'show ' + windowname + elif self.windowHideRB.GetValue(): + return 'windowhide ' + windowname + else: + if shortcmd := self.ShortToggleCommands.get(windowdesc, None): + return shortcmd + else: + return 'toggle ' + windowname + + + def Serialize(self): + choice = self.windowToggleTray + if self.windowShowRB.GetValue(): + action = "Show" + elif self.windowHideRB.GetValue(): + action = "Hide" + else: + action = "Toggle" + return { + 'window': choice.GetString(choice.GetSelection()), + 'action': action, + } + + def Deserialize(self, init): + choice = self.windowToggleTray + if window := init.get('window', ''): + if isinstance(window, int): + choice.SetSelection(window) + else: + choice.SetSelection(choice.FindString(window)) + + if choice.GetSelection() == wx.NOT_FOUND: + choice.SetSelection(0) + + action = init.get('action', '') + if action == "Show": + self.windowShowRB.SetValue(True) + elif action == "Hide": + self.windowHideRB.SetValue(True) + else: + self.windowToggleRB.SetValue(True) + + +# Must always add to this list when adding a new command class above +menuStructure = { + 'Graphics / UI' : [ + 'Attribute Monitor', + 'Buff Display Settings', + 'Graphics Settings', + 'Window Color', + 'Window Save / Load', + 'Window Toggle', + ], + 'Inspirations' : [ + 'Use Inspiration By Name', + 'Use Inspiration From Row/Column', + ], + 'Powers' : [ + 'Auto Power', + 'Power Abort', + 'Power Unqueue', + 'Use Power', + 'Use Power From Tray', + ], + 'Social' : [ + 'Away From Keyboard', + 'Chat Command', + 'Chat Command (Global)', + 'Costume Change', + 'Emote', + 'Supergroup Mode', + ], + 'Targeting' : [ + 'Target Custom', + 'Target Enemy', + 'Target Frield', + 'Team/Pet Select', + 'Unselect', + ], + 'Misc' : [ + 'Load Binds Directory', + 'Movement Commands', + ], + # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, + # but I'm leaving it here to remind myself that we do that. + } + +# Must always add to this list when adding a new command class above +commandClasses = { + 'Auto Power' : AutoPowerCmd, + 'Away From Keyboard' : AFKCmd, + 'Attribute Monitor' : AttributeMonitorCmd, + 'Buff Display Settings' : BuffDisplayCmd, + 'Chat Command' : ChatCmd, + 'Chat Command (Global)' : ChatGlobalCmd, + 'Costume Change' : CostumeChangeCmd, + 'Custom Bind' : CustomBindCmd, + 'Emote' : EmoteCmd, + 'Graphics Settings' : GraphicsCmd, + 'Load Binds Directory' : LoadBindsDir, + 'Movement Commands' : MovementCmd, + 'Power Abort' : PowerAbortCmd, + 'Power Unqueue' : PowerUnqueueCmd, + 'Supergroup Mode' : SGModeCmd, + 'Target Custom' : TargetCustomCmd, + 'Target Enemy' : TargetEnemyCmd, + 'Target Friend' : TargetFriendCmd, + 'Team/Pet Select' : TeamPetSelectCmd, + 'Unselect' : UnselectCmd, + 'Use Inspiration By Name' : UseInspByNameCmd, + 'Use Inspiration From Row/Column' : UseInspRowColCmd, + 'Use Power' : UsePowerCmd, + 'Use Power From Tray' : UsePowerFromTrayCmd, + 'Window Color' : WindowColorCmd, + 'Window Save / Load' : WindowSaveLoadCmd, + 'Window Toggle' : WindowToggleCmd, +} +# use these when we rename a commandClass so that old Profiles will still load correctly. +# If we've also updated the class, we need to try to make sure the new class will still +# Deserialize the legacy data, or at least not crash. +deprecatedCommandClasses = { + 'SG Mode Toggle' : SGModeCmd, + 'Use Insp By Name' : UseInspByNameCmd, + 'Use Insp From Row/Column' : UseInspRowColCmd, +} +commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/UseInspByNameCmd.py b/UI/PowerBinderCommand/UseInspByNameCmd.py new file mode 100644 index 0000000..4c02ab7 --- /dev/null +++ b/UI/PowerBinderCommand/UseInspByNameCmd.py @@ -0,0 +1,1800 @@ +import wx +import re +import UI +import UI.EmotePicker +from UI.ControlGroup import ControlGroup +from UI.PowerPicker import PowerPicker +from Help import HelpButton +import wx.adv +from wx.adv import BitmapComboBox, EditableListBox +from pathlib import PureWindowsPath +import GameData +import Profile +from Icon import GetIcon + +class PowerBinderDialog(wx.Dialog): + def __init__(self, parent, button, init = {}): + wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) + + self.Page = parent.Page + self.EditDialog = PowerBinderEditDialog(self) + self.Button = button + self.AddStepMenu = self.makeAddStepMenu() + + sizer = wx.BoxSizer(wx.VERTICAL); + self.mainSizer = sizer + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) + # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) + # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) + #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) + AddStepButton = wx.Button(self, -1, 'Add Step') + AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) + AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) + choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) + choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) + sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) + + rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) + + self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) + self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) + self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) + rearrangeCtrl.Add(self.RearrangeList, 1) + + rearrangeButtons = wx.BoxSizer(wx.VERTICAL) + self.DelButton = wx.Button(self, -1, "Delete") + self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) + self.EditButton = wx.Button(self, -1, "Edit") + self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) + self.EditButton.Disable() + upButton = wx.Button(self, -1, "\u25B2") + upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) + downButton = wx.Button(self, -1, "\u25BC") + downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) + rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) + rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) + + sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.BindStringDisplay = wx.TextCtrl(self, -1) + self.BindStringDisplay.Disable() + choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, + wx.ALIGN_CENTER_VERTICAL) + choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) + + sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) + + sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) + + # need to dig around and get the OK button since we show this dialog modelessly now. + okButton = self.FindWindow(self.GetAffirmativeId()) + okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) + + # Wrap everything in a vbox to add some padding + vbox = wx.BoxSizer(wx.VERTICAL); + vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); + + self.SetSizerAndFit(vbox); + self.Layout() + self.Fit() + self.SetFocus() + + # if we are loading from profile, ie, have "init", build the list from it + if init: self.LoadFromData(init) + + def LoadFromData(self, init): + for item in init: + for type, data in item.items(): + commandClass = commandClasses.get(type, None) + if not commandClass: + commandClass = deprecatedCommandClasses.get(type, None) + if not commandClass: + wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") + continue + newCommand = commandClass(self.EditDialog, data) + index = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.SetClientData(index, newCommand) + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) + self.EditDialog.mainSizer.Hide(newCommand.UI) + self.UpdateBindStringDisplay() + + def SaveToData(self): + data = [] + index = 0 + for _ in self.RearrangeList.GetItems(): + # check whether we have an object already attached to this choice + cmdObject = self.RearrangeList.GetClientData(index) + commandClassName = commandRevClasses[type(cmdObject)] + data.append({commandClassName: cmdObject.Serialize()}) + index = index + 1 + return data + + def OnAddStepButton(self, evt): + button = evt.EventObject + if not self.AddStepMenu: + self.AddStepMenu = self.makeAddStepMenu() + button.PopupMenu(self.AddStepMenu) + + + def OnOKButton(self, _): + if self.Button.tgtTxtCtrl: + bindString = self.MakeBindString() + if bindString != self.Button.tgtTxtCtrl.GetValue(): + self.Button.tgtTxtCtrl.SetValue(bindString) + wx.App.Get().Main.Profile.SetModified() + self.Close() + + def OnRearrangeDelete(self, _): + current = self.RearrangeList.GetSelection() + if current == wx.NOT_FOUND: return + + self.RearrangeList.Delete(current) + self.UpdateBindStringDisplay() + + def OnRearrangeUp(self, _): + self.RearrangeList.MoveCurrentUp() + self.UpdateBindStringDisplay() + + def OnRearrangeDown(self, _): + self.RearrangeList.MoveCurrentDown() + self.UpdateBindStringDisplay() + + def OnRearrangeEdit(self, _): + index = self.RearrangeList.GetSelection() + + # check whether we have an object already attached to this choice + cmdObject = None + try: + cmdObject = self.RearrangeList.GetClientData(index) + except Exception: + pass + + if cmdObject: + self.ShowEditDialogFor(cmdObject) + self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) + else: + print("cmdObject was None") + self.UpdateBindStringDisplay() + + # OnAddStepMenu creates a new step and adds it to the rearrangelist + def OnAddStepMenu(self, evt): + menuitem = self.AddStepMenu.FindItemById(evt.GetId()) + chosenName = menuitem.GetItemLabel() + + # make a new command object, attached to the parent dialog + newCommandClass = commandClasses[chosenName] + newCommand = newCommandClass(self.EditDialog) + + # show the edit dialog if this command needs it + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) + if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): + self.EditDialog.mainSizer.Remove(newCommand.UI) + return + + newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.Select(newBindIndex) + self.RearrangeList.SetClientData(newBindIndex, newCommand) + + self.OnListSelect() + self.UpdateBindStringDisplay() + + def OnListSelect(self, _ = None): + selected = self.RearrangeList.GetSelection() + + if selected != wx.NOT_FOUND: + selCommand = self.RearrangeList.GetClientData(selected) + if selCommand.UI: + self.EditButton.Enable() + else: + self.EditButton.Disable() + + def UpdateBindStringDisplay(self): + self.BindStringDisplay.SetValue(self.MakeBindString()) + self.BindStringDisplay.SetToolTip(self.MakeBindString()) + + def MakeBindString(self): + cmdBindStrings = [] + for index in range(self.RearrangeList.GetCount()): + c = self.RearrangeList.GetClientData(index) + if c: cmdBindStrings.append(c.MakeBindString()) + + bindstring = ('$$'.join(cmdBindStrings)) + return bindstring + + def ShowEditDialogFor(self, command): + if not command.UI: return + + self.EditDialog.mainSizer.Show(command.UI) + + self.EditDialog.Layout() + self.EditDialog.Fit() + + self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') + returnval = self.EditDialog.ShowModal() + + self.EditDialog.mainSizer.Hide(command.UI) + + return returnval + + def makeAddStepMenu(self): + + stepMenu = wx.Menu() + + for subname in menuStructure: + submenu = wx.Menu() + stepMenu.AppendSubMenu(submenu, subname) + for classname in menuStructure[subname]: + submenu.Append(wx.ID_ANY, classname) + + stepMenu.Append(wx.ID_ANY, 'Custom Bind') + + return stepMenu + +class PowerBinderButton(wx.BitmapButton): + + def __init__(self, parent, tgtTxtCtrl, init = {}): + wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) + self.Init = init + self.Dialog = None + self.DialogParent = parent + + self.tgtTxtCtrl = tgtTxtCtrl + self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) + self.SetToolTip("Launch PowerBinder") + + def PowerBinderEventHandler(self, _): + self.PowerBinderDialog().Show() + + def LoadFromData(self, data): + self.PowerBinderDialog().LoadFromData(data) + + def SaveToData(self): + return self.PowerBinderDialog().SaveToData() + + def PowerBinderDialog(self): + if not self.Dialog: + self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) + return self.Dialog + + +class PowerBinderEditDialog(wx.Dialog): + def __init__(self, parent): + wx.Dialog.__init__(self, parent, -1, "Edit Step", + style = wx.DEFAULT_DIALOG_STYLE) + + outerSizer = wx.BoxSizer(wx.VERTICAL) + + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + self.mainSizer.SetMinSize([500, 150]) + + self.Page = parent.Page + + self.mainSizer.Add( + self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), + 0, wx.EXPAND|wx.ALL, 10) + + outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) + + self.SetSizerAndFit(outerSizer) + self.Layout() + self.Fit() + +########### Power Binder Command Objects +class PowerBindCmd(): + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + commandClassName = commandRevClasses[type(self)] + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{commandClassName} - {short_bindstr}" + + +####### Away From Keyboard +class AFKCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) + +####### Attribute Monitor +class AttributeMonitorCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.Groups = {} + self.AttributeTable = { + 'Base' : { + 'Current Hit Points' : 'NT H', + 'Max Hit Points' : 'X H', + 'Current Endurance' : 'T E', + 'Max Endurance' : 'X EN', + 'Regeneration Rate' : 'N RAT', + 'Recovery Rate' : 'Y RA', + 'Endurance Consumption' : 'SU', + 'ToHit Bonus' : 'T B', + 'Accuracy Bonus' : 'CC', + 'Last Hit Chance' : 'T C', + 'Damage Bonus' : 'DA', + 'Healing Bonus' : 'NG B', + 'Recharge Time Bonus' : 'ME B', + 'Endurance Discount' : 'CE DIS', + 'Stealth Radius (PvP)' : 'PVP', + 'Stealth Radius (PvE)' : 'PVE', + 'Perception Radius' : 'RC', + 'Range Bonus' : 'GE B', + 'Threat Level' : 'AT L', + 'Experience to Next Level' : 'XT', + 'Experience Debt' : 'XP', + 'Influence / Infamy' : 'INF', + 'Inherent' : 'NH', + }, + 'Movement Speed' : { + 'Flying Speed' : 'FL', + 'Jumping Speed' : 'PI', + 'Max Jump Height' : 'X J', + 'Run Speed' : 'RU', + }, + 'Damage Resistance' : { + 'Smashing Resistance' : 'G R', + 'Lethal Resistance' : 'L R', + 'Fire Resistance' : 'RE R', + 'Cold Resistance' : 'COLD R', + 'Energy Resistance' : 'DamageType[4]', + 'Negative Energy Resistance' : 'GY R', + 'Psyonic Resistance' : 'NIC R', + 'Toxic Resistance' : 'XIC R', + }, + 'Defense' : { + 'Base Defense' : 'BAS', + 'Ranged Defense' : 'ED', + 'Melee Defense' : 'MEL', + 'AoE Defense' : '2', + 'Smashing Defense' : '3', + 'Lethal Defense' : '4', + 'Fire Defense' : '5', + 'Cold Defense' : '6', + 'Energy Defense' : '7', + 'Negative Energy Defense' : '8', + 'Psionic Defense' : '9', + 'Toxic Defense' : '1', + }, + 'Debuff Resistance' : { + 'Regeneration Resistance' : 'ON R', + 'Recovery Resistance' : 'RY R', + 'To Hit Resistance' : 'IT R', + 'Defense Resistance' : 'NSE RES', + }, + 'Status Effect Protection' : { + 'Hold Protection' : 'D P', + 'Immobilize Protection' : 'LIZE P', + 'Stun Protection' : 'N P', + 'Sleep Protection' : 'P P', + 'Knockback Protection' : 'K P', + 'Confuse Protection' : 'SE P', + 'Terrorize Protection' : 'ZE P', + 'Repel Protection' : 'EL P', + 'Teleport Protection' : 'T P', + }, + 'Status Effect Resistance' : { + 'Hold Resistance' : 'D R', + 'Immobilize Resistance' : 'LIZE R', + 'Stun Resistance' : 'N R', + 'Sleep Resistance' : 'P R', + 'Knockback Resistance' : 'K R', + 'Confuse Resistance' : 'SE R', + 'Terrorize Resistance' : 'ZE R', + 'Placate Resistance' : 'TE R', + 'Taunt Resistance' : 'NT R', + }, + 'Miscellaneous' : { + 'Level Shift' : 'L S', + }, + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.AttributeMenu = wx.Menu() + for group, controls in self.AttributeTable.items(): + submenu = wx.Menu() + self.AttributeMenu.AppendSubMenu(submenu, group) + for cb in controls: + submenu.Append(wx.ID_ANY, cb) + + self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) + + self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) + groupSizer.Add(self.editbox) + + newButton = self.editbox.GetNewButton() + newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) + + return groupSizer + + def MakeBindString(self): + map = {} + bindstrings = [] + for _, controls in self.AttributeTable.items(): + for cb, data in controls.items(): + map[cb] = data + + for string in self.editbox.GetStrings(): + if string: + bindstrings.append(f'monitorattribute {map[string]}') + + return '$$'.join(bindstrings) + + def Serialize(self): + return { + 'attributes' : self.editbox.GetStrings() + } + + def Deserialize(self, init): + self.editbox.SetStrings(init.get('attributes', [])) + + def OnNewButton(self, evt): + evt.GetEventObject().PopupMenu(self.AttributeMenu) + + def OnMenuItem(self, evt): + menuitem = evt.EventObject.FindItemById(evt.GetId()) + existingstrings = self.editbox.GetStrings() + existingstrings.append(menuitem.GetItemLabel()) + self.editbox.SetStrings(existingstrings) + +####### Auto Power +class AutoPowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) + autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.autoPowerName = PowerPicker(dialog) + autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) + + return autoPowerSizer + + def MakeBindString(self): + return f"powexecauto {self.autoPowerName.GetLabel()}" + + def Serialize(self): + return { + 'pname' : self.autoPowerName.GetLabel(), + 'picon' : self.autoPowerName.IconFilename + } + + def Deserialize(self, init): + if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) + +####### Buff Display Command +class BuffDisplayCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.buffDisplayMap = { + 'Status Window' : { + 'Hide Auto' : 1, + 'Hide Toggles' : 2, + 'No Blinking' : 4, + 'No Stacking' : 8, + 'Numeric Stacking' : 16, + 'Hide Buff Numbers' : 32, + 'Stop Sending Buffs' : 64, + }, + 'Group Window' : { + 'Hide Auto' : 256, + 'Hide Toggles' : 512, + 'No Blinking' : 1024, + 'No Stacking' : 2048, + 'Numeric Stacking' : 4096, + 'Hide Buff Numbers' : 8192, + 'Stop Sending Buffs' : 16384, + }, + 'Pet Window' : { + 'Hide Auto' : 65536, + 'Hide Toggles' : 131072, + 'No Blinking' : 262144, + 'No Stacking' : 524288, + 'Numeric Stacking' : 1048576, + 'Hide Buff Numbers' : 2097152, + 'Stop Sending Buffs' : 4194304, + }, + } + self.Groups = {} + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + for group, controls in self.buffDisplayMap.items(): + self.Groups[group] = ControlGroup(dialog, self.Page, label = group) + groupid = self.Groups[group].GetStaticBox().GetId() + for cb, data in controls.items(): + self.Groups[group].AddControl( + ctlType = 'checkbox', + ctlName = f"{groupid}_{group}_{cb}", + label = cb, + data = data, + ) + + groupSizer.Add(self.Groups[group]) + + return groupSizer + + def CalculateValue(self): + page = wx.App.Get().Main.Profile.CustomBinds + + total = 0 + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] + if checkbox.IsChecked(): + total = total + checkbox.Data + return total + + def MakeBindString(self): + return f"optionset buffsettings {self.CalculateValue()}" + + def Serialize(self): + return { 'value' : self.CalculateValue() } + + def Deserialize(self, init): + value = init.get('value', 0) + + value = value or 0 # in case we had for some reason 'None' stashed in the init values + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] + checkbox.SetValue( checkbox.Data & value ) + +####### Chat Command +class ChatCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.chatChannelMap = { # before __init__ + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + chatCommandSizer = wx.GridBagSizer(5, 5) + self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") + chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) + # row 1 + self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) + self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) + self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) + # row 2 + self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) + self.chatCommandDuration.SetRange(1, 20) + self.chatCommandDuration.SetValue(7) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandDuration, (2,1)) + self.chatCommandChatSize = wx.Choice(dialog, -1, + choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) + self.chatCommandChatSize.SetSelection(5) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) + self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) + self.chatCommandChannel.SetSelection(0) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChannel, (2,5)) + # row 3 + self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") + chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) + self.chatCommandMessage = wx.TextCtrl(dialog, -1) + self.chatCommandMessage.SetHint('Chat Command Text') + chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) + + return chatCommandSizer + + def MakeBindString(self): + duration = self.chatCommandDuration.GetValue() + + choice = self.chatCommandChatSize + index = choice.GetSelection() + size = choice.GetString(index) + + duration = f"" if duration != 7 else "" + size = f"" if size != "1" else "" + + bdcolor = fgcolor = bgcolor = '' + if self.chatCommandUseColorsCB.IsChecked(): + bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + + bdcolor = f"" + fgcolor = f"" + bgcolor = f"" + + beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' + text = self.chatCommandMessage.GetValue() + + choice = self.chatCommandChannel + index = choice.GetSelection() + channel = choice.GetString(index) + + return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" + + def Serialize(self): + return { + 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), + 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), + 'channel' : self.chatCommandChannel .GetSelection(), + 'size' : self.chatCommandChatSize.GetSelection(), + 'duration' : self.chatCommandDuration.GetValue(), + 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'text' : self.chatCommandMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) + if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) + if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) + if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) + if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) + if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) + if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) + if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) + if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) + + +####### Chat Command Global +class ChatGlobalCmd(PowerBindCmd): + def BuildUI(self, dialog): + chatCommandGlobalSizer = wx.GridBagSizer(5,5) + + self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") + chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) + + self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalChannel.SetHint("Channel") + chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) + + self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') + chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) + + chatCommandGlobalSizer.AddGrowableCol(1) + + return chatCommandGlobalSizer + + def MakeBindString(self): + useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() + channel = self.chatCommandGlobalChannel.GetValue() + message = self.chatCommandGlobalMessage.GetValue() + + preface = "beginchat /" if useBeginchat else "" + + return f'{preface}send "{channel}" {message}' + + def Serialize(self): + return { + 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), + 'channel' : self.chatCommandGlobalChannel.GetValue(), + 'message' : self.chatCommandGlobalMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) + if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) + if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) + +#######Costume Change +class CostumeChangeCmd(PowerBindCmd): + def BuildUI(self, dialog): + costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeCostume = wx.Choice(dialog, -1, + choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) + self.costumeChangeCostume.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeEmote = wx.Choice(dialog, -1, + choices = GameData.Emotes['costumechange']) + self.costumeChangeEmote.Insert("- None -", 0) + self.costumeChangeEmote.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return costumeChangeSizer + + def MakeBindString(self): + costumeNumber = self.costumeChangeCostume.GetSelection() + costumeEmote = self.costumeChangeEmote.GetSelection() + + if costumeEmote: # None, or 0 == "- None -" + ccCmd = 'cce' + emoteName = self.costumeChangeEmote.GetString(costumeEmote) + emoteName = " CC" + emoteName.replace(" ","") + else: + ccCmd = 'cc' + emoteName = '' + + return f"{ccCmd} {costumeNumber}{emoteName}" + + def Serialize(self): + return{ + 'costumeNumber': self.costumeChangeCostume.GetSelection(), + 'costumeEmote' : self.costumeChangeEmote.GetSelection(), + } + + def Deserialize(self, init): + if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) + if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) + +####### Movement Command +class MovementCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + self.plusbutton.SetValue(True) + + self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.commandchoice = wx.Choice(dialog, choices = [ + "forward", "left", "right", "backward", "up", "down", + "turnleft", "turnright", "first", "autorun", "clicktomove", + ],) + sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) + self.commandchoice.SetSelection(0) + + self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + pre = post = '' + if self.plusbutton.GetValue() : pre = "+" + elif self.plusplusbutton.GetValue() : pre = "++" + elif self.minusbutton.GetValue() : pre = "-" + elif self.zerobutton.GetValue() : post = " 0" + elif self.onebutton.GetValue() : post = " 1" + + command = self.commandchoice.GetString(self.commandchoice.GetSelection()) + + return f"{pre}{command}{post}" + + def Serialize(self): + mod = '' + if self.plusbutton.GetValue() : mod = "plus" + elif self.plusplusbutton.GetValue() : mod = "plusplus" + elif self.minusbutton.GetValue() : mod = "minus" + elif self.zerobutton.GetValue() : mod = "zero" + elif self.onebutton.GetValue() : mod = "one" + + return { + 'mod' : mod, + 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), + } + + def Deserialize(self, init): + mod = init.get('mod', 'plus') + + if mod == 'plus' : self.plusbutton.SetValue(True) + elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) + elif mod == 'minus' : self.minusbutton.SetValue(True) + elif mod == 'zero' : self.zerobutton.SetValue(True) + elif mod == 'one' : self.onebutton.SetValue(True) + + self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) + +####### Graphics Command +class GraphicsCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.FlexGridSizer(2) + + self.visscalecb = wx.CheckBox(dialog, label = "visscale") + sizer.Add(self.visscalecb) + self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) + sizer.Add(self.visscalesc) + + self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") + sizer.Add(self.dofweightcb) + self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) + sizer.Add(self.dofweightsc) + + self.fsaacb = wx.CheckBox(dialog, label = "fsaa") + sizer.Add(self.fsaacb) + self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) + self.fsaach.SetSelection(0) + sizer.Add(self.fsaach) + + self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") + sizer.Add(self.bloomscalecb) + self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) + self.bloomscalech.SetSelection(0) + sizer.Add(self.bloomscalech) + + self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") + sizer.Add(self.bloomweightcb) + self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) + sizer.Add(self.bloomweightsc) + + self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") + sizer.Add(self.lodbiascb) + self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) + sizer.Add(self.lodbiassc) + + self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") + sizer.Add(self.renderscalecb) + self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) + sizer.Add(self.renderscalesc) + + return sizer + + def MakeBindString(self): + # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. + bindstrings = [] + if self.visscalecb.IsChecked(): + bindstrings.append("visscale " + str(self.visscalesc.GetValue())) + if self.dofweightcb.IsChecked(): + bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) + if self.fsaacb.IsChecked(): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bindstrings.append("fsaa " + fsaavalue) + if self.bloomscalecb.IsChecked(): + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + bindstrings.append("bloomscale " + bloomscalevalue) + if self.bloomweightcb.IsChecked(): + bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) + if self.lodbiascb.IsChecked(): + bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) + if self.renderscalecb.IsChecked(): + bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) + + return '$$'.join(bindstrings) + + def Serialize(self): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + return { + 'visscalecb' : self.visscalecb.IsChecked(), + 'visscalesc' : self.visscalesc.GetValue(), + 'dofweightcb' : self.dofweightcb.IsChecked(), + 'dofweightsc' : self.dofweightsc.GetValue(), + 'fsaacb' : self.fsaacb.IsChecked(), + 'fsaach' : fsaavalue, + 'bloomscalecb' : self.bloomscalecb.IsChecked(), + 'bloomscalech' : bloomscalevalue, + 'bloomweightcb' : self.bloomweightcb.IsChecked(), + 'bloomweightsc' : self.bloomweightsc.GetValue(), + 'lodbiascb' : self.lodbiascb.IsChecked(), + 'lodbiassc' : self.lodbiassc.GetValue(), + 'renderscalecb' : self.renderscalecb.IsChecked(), + 'renderscalesc' : self.renderscalesc.GetValue(), + } + + def Deserialize(self, init): + self.visscalecb.SetValue(init.get('visscalecb', False)) + self.visscalesc.SetValue(init.get('visscalesc', 1.0)) + self.dofweightcb.SetValue(init.get('dofweightcb', False)) + self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) + self.fsaacb.SetValue(init.get('fsaacb', False)) + self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) + self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) + self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) + self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) + self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) + self.lodbiascb.SetValue(init.get('lodbiascb', False)) + self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) + self.renderscalecb.SetValue(init.get('renderscalecb', False)) + self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) + +####### Custom Bind +class CustomBindCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.customBindName = wx.TextCtrl(dialog, -1) + self.customBindName.SetHint('Custom Bind Text') + sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + return self.customBindName.GetValue() + + def Serialize(self): + return { 'customBindName': self.customBindName.GetValue() } + + def Deserialize(self,init): + if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) + +####### Emote +class EmoteCmd(PowerBindCmd): + def BuildUI(self, dialog): + emoteSizer = wx.BoxSizer(wx.HORIZONTAL) + self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") + emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + self.emoteName = wx.Button(dialog, -1, "...") + self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) + emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) + + return emoteSizer + + def MakeBindString(self): + displayedEmoteName = self.emoteName.GetLabel() + actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] + + return actualEmotePayload + + def Serialize(self): + return {'emoteName': self.emoteName.GetLabel()} + + def Deserialize(self, init): + if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) + +####### Load Binds Directory +class LoadBindsDir(PowerBindCmd): + def BuildUI(self, dialog): + mainSizer = wx.BoxSizer(wx.VERTICAL) + + lbSizer = wx.BoxSizer(wx.HORIZONTAL) + lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") + lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + profiles = Profile.GetAllProfileBindsDirs() + + self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) + lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") + self.lbResetCB.SetValue(True) + + mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + return mainSizer + + def MakeBindString(self): + + # If the specified binds directory disappeared between runs, we'd crash, so handle that. + if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' + + config = wx.ConfigBase.Get() + if config.Exists('GameBindPath'): + bindpath = config.Read('GameBindPath') + else: + bindpath = config.Read('BindPath') + + reset = "" + if self.lbResetCB.GetValue(): + reset = "keybind_reset$$" + + resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' + return reset + 'bindloadfile ' + str(resetfilepath) + + def Serialize(self): + return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), + 'ResetKeybinds' : self.lbResetCB.GetValue(), + } + + def Deserialize(self, init): + if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) + self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) + +####### Power Abort +class PowerAbortCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecabort' + +####### Power Unqueue +class PowerUnqueueCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecunqueue' + +####### SG Mode +class SGModeCmd(PowerBindCmd): + def BuildUI(self, dialog): + sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) + sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") + self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") + + sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) + + return sgmodeSizer + + def MakeBindString(self): + if self.sgmodeOnRB.GetValue(): + return 'sgmodeset 1' + elif self.sgmodeOffRB.GetValue(): + return 'sgmodeset 0' + else: + return 'sgmode' + + def Serialize(self): + if self.sgmodeOnRB.GetValue(): + val = "On" + elif self.sgmodeOffRB.GetValue(): + val = "Off" + else: + val = "Toggle" + + return {"value" : val} + + def Deserialize(self, init): + val = init.get('value', '') + if val == "On": + self.sgmodeOnRB.SetValue(True) + elif val == "Off": + self.sgmodeOffRB.SetValue(True) + else: + self.sgmodeToggleRB.SetValue(True) + +####### Target Custom +class TargetCustomCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetCustomSizer = wx.GridBagSizer(5,5) + targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), + flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) + self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetCustomModeChoice.SetSelection(0) + targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) + self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) + self.targetCustomOptionalName.SetHint("Optional name to match") + targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) + self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") + targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) + self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") + targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) + self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") + targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) + self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") + targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) + self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") + targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) + self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") + targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) + self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") + targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) + self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") + targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) + + targetCustomSizer.AddGrowableCol(2) + + return targetCustomSizer + + def MakeBindString(self): + choice = self.targetCustomModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + targetCommand = "targetcustom" + mode.lower() + + enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" + friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" + defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" + alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" + mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" + notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" + base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" + notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" + + name = self.targetCustomOptionalName.GetValue() + + return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" + + def Serialize(self): + return { + 'mode' : self.targetCustomModeChoice.GetSelection(), + 'enemy' : self.targetCustomCBEnemies. IsChecked(), + 'friend' : self.targetCustomCBFriends. IsChecked(), + 'defeated' : self.targetCustomCBDefeated. IsChecked(), + 'alive' : self.targetCustomCBAlive. IsChecked(), + 'mypet' : self.targetCustomCBMyPets. IsChecked(), + 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), + 'base' : self.targetCustomCBBaseItems. IsChecked(), + 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), + 'name' : self.targetCustomOptionalName.GetValue(), + } + + def Deserialize(self, init): + if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) + if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) + if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) + if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) + if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) + if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) + if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) + if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) + if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) + if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) + + +####### Target Enemy +class TargetEnemyCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) + targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetEnemyModeChoice.SetSelection(0) + targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetEnemySizer + + def MakeBindString(self): + choice = self.targetEnemyModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetenemy" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetEnemyModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) + +####### Target Friend +class TargetFriendCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) + targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetFriendModeChoice.SetSelection(0) + targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetFriendSizer + + def MakeBindString(self): + choice = self.targetFriendModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetfriend" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetFriendModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) + +####### Team/Pet Select +class TeamPetSelectCmd(PowerBindCmd): + def BuildUI(self, dialog): + teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], + style=wx.ALIGN_CENTER_VERTICAL) + self.teamPetSelectNumber.SetSelection(0) + teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) + + return teamPetSelectSizer + + def MakeBindString(self): + teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' + targetNumber = self.teamPetSelectNumber.GetSelection()+1 + + return f"{teamOrPet}select {targetNumber}" + + def Serialize(self): + return { + 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', + 'targetNum': self.teamPetSelectNumber.GetSelection(), + } + + def Deserialize(self, init): + ToP = init.get('teamOrPet', '') + if ToP == 'pet': + self.teamPetSelectPetRB.SetValue(True) + else: + self.teamPetSelectTeamRB.SetValue(True) + if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) + +####### Unselect +class UnselectCmd(PowerBindCmd): + def MakeBindString(self): + return 'unselect' + +####### Use Insp By Name +class UseInspByNameCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) + for _, types in GameData.Inspirations.items(): + for _, info in types.items(): + for insp in info['tiers']: + name = re.sub(' ', '', str(insp)) + icon = GetIcon(f'Inspirations/{name}') + self.useInspByNameModeChoice.Append(insp, icon) + self.useInspByNameModeChoice.SetSelection(0) + useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) + + return useInspByNameSizer + + def MakeBindString(self): + choice = self.useInspByNameModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "inspexecname " + mode.lower() + + def GetAllInsps(self): + Insplist = [] + for _, info in GameData.Inspirations.items(): + for insp in info['tiers']: + Insplist.append(insp) + Insplist.append("---") + Insplist.pop(-1) # snip the terminal "---" + + return Insplist + + def Serialize(self): + return { 'insp' : self.useInspByNameModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) + +####### Use Insp From Row / Column +class UseInspRowColCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnRow.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) + self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnCol.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) + + return useInspRowColumnSizer + + def MakeBindString(self): + row = self.useInspRowColumnRow.GetSelection()+1 + col = self.useInspRowColumnCol.GetSelection()+1 + + return f"inspexectray {col} {row}" + + def Serialize(self): + return { + 'col' : self.useInspRowColumnCol.GetSelection(), + 'row' : self.useInspRowColumnRow.GetSelection(), + } + + def Deserialize(self, init): + if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) + if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) + +####### Use Power +class UsePowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + outerSizer = wx.BoxSizer(wx.HORIZONTAL) + + usePowerSizer = wx.GridBagSizer(5,5) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBToggle, (0,1)) + self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOn, (0,2)) + self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOff, (0,3)) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerName = PowerPicker(dialog) + usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) + usePowerSizer.AddGrowableCol(3) + + outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) + + return outerSizer + + def MakeBindString(self): + if self.usePowerRBToggle.GetValue(): + method = "powexecname" + elif self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') + return '' + + return f"{method} {self.usePowerName.GetLabel()}" + + def Serialize(self): + if self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + method = "powexecname" + return { + 'method': method, + 'pname' : self.usePowerName.GetLabel(), + 'picon' : self.usePowerName.IconFilename + } + + def Deserialize(self, init): + method = init.get('method', '') + if method == 'powexectoggleon': + self.usePowerRBOn.SetValue(True) + elif method == 'powexectoggleoff': + self.usePowerRBOff.SetValue(True) + else: + self.usePowerRBToggle.SetValue(True) + if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) + +####### Use Power From Tray +class UsePowerFromTrayCmd(PowerBindCmd): + def BuildUI(self, dialog): + usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTrayTray = wx.Choice(dialog, -1, + choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', + 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) + self.usePowerFromTrayTray.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) + self.usePowerFromTraySlot.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return usePowerFromTraySizer + + def MakeBindString(self): + choice = self.usePowerFromTrayTray + tray = choice.GetSelection() + + choice = self.usePowerFromTraySlot + slot = choice.GetSelection()+1 + + mode = "slot" + mode2 = '' + if tray > 3: + mode = "tray" + mode2 = f" {tray - 3}" + elif tray == 3: + mode = "alt2slot" + elif tray == 2: + mode = "altslot" + + return f"powexec{mode} {slot}{mode2}" + + def Serialize(self): + return { + 'tray' : self.usePowerFromTrayTray.GetSelection(), + 'slot' : self.usePowerFromTraySlot.GetSelection(), + } + + def Deserialize(self, init): + if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) + if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) + +####### Window Color +class WindowColorCmd(PowerBindCmd): + def BuildUI(self, dialog): + windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) + borderSizer = wx.BoxSizer(wx.VERTICAL) + self.ColorBorder.SetSizer(borderSizer) + self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) + borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) + + windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) + + RGBASizer = wx.FlexGridSizer(3, 4, 5) + + RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) + self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) + self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + windowColorSizer.Add(RGBASizer) + + self.UpdateFromSlider() + + return windowColorSizer + + def MakeBindString(self): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + return f"windowcolor {Rval} {Gval} {Bval} {Aval}" + + def Serialize(self): + return { + 'Rval' : self.RSlider.GetValue(), + 'Gval' : self.GSlider.GetValue(), + 'Bval' : self.BSlider.GetValue(), + 'Aval' : self.ASlider.GetValue(), + } + + def Deserialize(self, init): + self.RSlider.SetValue(init['Rval']) + self.GSlider.SetValue(init['Gval']) + self.BSlider.SetValue(init['Bval']) + self.ASlider.SetValue(init['Aval']) + self.UpdateFromSlider() + + def UpdateFromSlider(self, _ = None): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RReadout.SetValue(Rval) + self.GReadout.SetValue(Gval) + self.BReadout.SetValue(Bval) + self.AReadout.SetValue(Aval) + self.ColorBorder.Refresh() + + def UpdateFromText(self, _ = None): + Rval = self.RReadout.GetValue() + Gval = self.GReadout.GetValue() + Bval = self.BReadout.GetValue() + Aval = self.AReadout.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RSlider.SetValue(Rval) + self.GSlider.SetValue(Gval) + self.BSlider.SetValue(Bval) + self.ASlider.SetValue(Aval) + self.ColorBorder.Refresh() + +####### Window Save / Load +class WindowSaveLoadCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) + self.CommandChoice.SetSelection(0) + sizer.Add(self.CommandChoice, 0, wx.ALL, 5) + + self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), + value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) + sizer.Add(self.FilePath, 0, wx.ALL, 5) + + return sizer + + def MakeBindString(self): + command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] + return f'{command} "{self.FilePath.GetValue()}"' + + def Serialize(self): + return { + 'command' : self.CommandChoice.GetSelection(), + 'filename' : self.FilePath.GetValue(), + } + + def Deserialize(self, init): + self.CommandChoice.SetSelection(init.get('command', 0)) + self.FilePath.SetValue(init.get('filename', '')) + +####### Window Toggle +class WindowToggleCmd(PowerBindCmd): + def BuildUI(self, dialog): + self.WindowNames = { + 'Actions' : 'actions', + 'Auction House' : 'ah', + 'Badge' : 'badge', + 'Channel Search' : 'chansearch', + 'Chat' : 'chat', + 'Custom Chat 1' : 'chat1', + 'Custom Chat 2' : 'chat2', + 'Custom Chat 3' : 'chat3', + 'Custom Chat 4' : 'chat4', + 'Clues' : 'clue', + 'Combat Numbers' : 'combatnumbers', + 'Contacts' : 'contact', + 'Contact Finder' : 'contactfinder', + 'Costumes' : 'costume', + 'Email' : 'email', + 'Enhancements' : 'enhancements', + 'Friends' : 'friend', + 'Group' : 'group', + 'Help' : 'helpwindow', + 'Incarnate' : 'incarnate', + 'Inspirations' : 'insp', + 'League' : 'league', + 'LFG' : 'lfg', + 'Map' : 'map', + 'Mission' : 'mission', + 'Nav / Compass' : 'nav', + 'Options' : 'options', + 'Pets' : 'pet', + 'Petition' : 'petition', + 'Power Tray' : 'powers', + 'Power List' : 'powerlist', + 'Quit' : 'quit', + 'Recipes' : 'recipe', + 'Salvage' : 'salvage', + 'Search' : 'search', + 'Supergroup' : 'sg', + 'Target' : 'target', + 'Team' : 'team', + 'Tray' : 'tray', + 'Tray1' : 'tray1', + 'Tray2' : 'tray2', + 'Tray3' : 'tray3', + 'Tray4' : 'tray4', + 'Tray5' : 'tray5', + 'Tray6' : 'tray6', + 'Tray7' : 'tray7', + 'Tray8' : 'tray8', + 'Vault' : 'vault', + } + + self.ShortToggleCommands = { + 'Auction House' : 'ah', + 'Chat' : 'chat', + 'Help' : 'helpwindow', + 'Map' : 'map', + 'Nav / Compass' : 'nav', + 'Power Tray' : 'powers', + 'Target' : 'target', + 'Tray' : 'tray', + } + + windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) + windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) + self.windowToggleTray.SetSelection(0) + windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.windowShowRB = wx.RadioButton(dialog, -1, "Show") + self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") + + windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) + + return windowToggleSizer + + def MakeBindString(self): + choice = self.windowToggleTray + index = choice.GetSelection() + windowdesc = choice.GetString(index) + windowname = self.WindowNames[windowdesc] + + if self.windowShowRB.GetValue(): + return 'show ' + windowname + elif self.windowHideRB.GetValue(): + return 'windowhide ' + windowname + else: + if shortcmd := self.ShortToggleCommands.get(windowdesc, None): + return shortcmd + else: + return 'toggle ' + windowname + + + def Serialize(self): + choice = self.windowToggleTray + if self.windowShowRB.GetValue(): + action = "Show" + elif self.windowHideRB.GetValue(): + action = "Hide" + else: + action = "Toggle" + return { + 'window': choice.GetString(choice.GetSelection()), + 'action': action, + } + + def Deserialize(self, init): + choice = self.windowToggleTray + if window := init.get('window', ''): + if isinstance(window, int): + choice.SetSelection(window) + else: + choice.SetSelection(choice.FindString(window)) + + if choice.GetSelection() == wx.NOT_FOUND: + choice.SetSelection(0) + + action = init.get('action', '') + if action == "Show": + self.windowShowRB.SetValue(True) + elif action == "Hide": + self.windowHideRB.SetValue(True) + else: + self.windowToggleRB.SetValue(True) + + +# Must always add to this list when adding a new command class above +menuStructure = { + 'Graphics / UI' : [ + 'Attribute Monitor', + 'Buff Display Settings', + 'Graphics Settings', + 'Window Color', + 'Window Save / Load', + 'Window Toggle', + ], + 'Inspirations' : [ + 'Use Inspiration By Name', + 'Use Inspiration From Row/Column', + ], + 'Powers' : [ + 'Auto Power', + 'Power Abort', + 'Power Unqueue', + 'Use Power', + 'Use Power From Tray', + ], + 'Social' : [ + 'Away From Keyboard', + 'Chat Command', + 'Chat Command (Global)', + 'Costume Change', + 'Emote', + 'Supergroup Mode', + ], + 'Targeting' : [ + 'Target Custom', + 'Target Enemy', + 'Target Frield', + 'Team/Pet Select', + 'Unselect', + ], + 'Misc' : [ + 'Load Binds Directory', + 'Movement Commands', + ], + # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, + # but I'm leaving it here to remind myself that we do that. + } + +# Must always add to this list when adding a new command class above +commandClasses = { + 'Auto Power' : AutoPowerCmd, + 'Away From Keyboard' : AFKCmd, + 'Attribute Monitor' : AttributeMonitorCmd, + 'Buff Display Settings' : BuffDisplayCmd, + 'Chat Command' : ChatCmd, + 'Chat Command (Global)' : ChatGlobalCmd, + 'Costume Change' : CostumeChangeCmd, + 'Custom Bind' : CustomBindCmd, + 'Emote' : EmoteCmd, + 'Graphics Settings' : GraphicsCmd, + 'Load Binds Directory' : LoadBindsDir, + 'Movement Commands' : MovementCmd, + 'Power Abort' : PowerAbortCmd, + 'Power Unqueue' : PowerUnqueueCmd, + 'Supergroup Mode' : SGModeCmd, + 'Target Custom' : TargetCustomCmd, + 'Target Enemy' : TargetEnemyCmd, + 'Target Friend' : TargetFriendCmd, + 'Team/Pet Select' : TeamPetSelectCmd, + 'Unselect' : UnselectCmd, + 'Use Inspiration By Name' : UseInspByNameCmd, + 'Use Inspiration From Row/Column' : UseInspRowColCmd, + 'Use Power' : UsePowerCmd, + 'Use Power From Tray' : UsePowerFromTrayCmd, + 'Window Color' : WindowColorCmd, + 'Window Save / Load' : WindowSaveLoadCmd, + 'Window Toggle' : WindowToggleCmd, +} +# use these when we rename a commandClass so that old Profiles will still load correctly. +# If we've also updated the class, we need to try to make sure the new class will still +# Deserialize the legacy data, or at least not crash. +deprecatedCommandClasses = { + 'SG Mode Toggle' : SGModeCmd, + 'Use Insp By Name' : UseInspByNameCmd, + 'Use Insp From Row/Column' : UseInspRowColCmd, +} +commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/UseInspRowColCmd.py b/UI/PowerBinderCommand/UseInspRowColCmd.py new file mode 100644 index 0000000..4c02ab7 --- /dev/null +++ b/UI/PowerBinderCommand/UseInspRowColCmd.py @@ -0,0 +1,1800 @@ +import wx +import re +import UI +import UI.EmotePicker +from UI.ControlGroup import ControlGroup +from UI.PowerPicker import PowerPicker +from Help import HelpButton +import wx.adv +from wx.adv import BitmapComboBox, EditableListBox +from pathlib import PureWindowsPath +import GameData +import Profile +from Icon import GetIcon + +class PowerBinderDialog(wx.Dialog): + def __init__(self, parent, button, init = {}): + wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) + + self.Page = parent.Page + self.EditDialog = PowerBinderEditDialog(self) + self.Button = button + self.AddStepMenu = self.makeAddStepMenu() + + sizer = wx.BoxSizer(wx.VERTICAL); + self.mainSizer = sizer + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) + # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) + # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) + #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) + AddStepButton = wx.Button(self, -1, 'Add Step') + AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) + AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) + choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) + choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) + sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) + + rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) + + self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) + self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) + self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) + rearrangeCtrl.Add(self.RearrangeList, 1) + + rearrangeButtons = wx.BoxSizer(wx.VERTICAL) + self.DelButton = wx.Button(self, -1, "Delete") + self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) + self.EditButton = wx.Button(self, -1, "Edit") + self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) + self.EditButton.Disable() + upButton = wx.Button(self, -1, "\u25B2") + upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) + downButton = wx.Button(self, -1, "\u25BC") + downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) + rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) + rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) + + sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.BindStringDisplay = wx.TextCtrl(self, -1) + self.BindStringDisplay.Disable() + choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, + wx.ALIGN_CENTER_VERTICAL) + choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) + + sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) + + sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) + + # need to dig around and get the OK button since we show this dialog modelessly now. + okButton = self.FindWindow(self.GetAffirmativeId()) + okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) + + # Wrap everything in a vbox to add some padding + vbox = wx.BoxSizer(wx.VERTICAL); + vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); + + self.SetSizerAndFit(vbox); + self.Layout() + self.Fit() + self.SetFocus() + + # if we are loading from profile, ie, have "init", build the list from it + if init: self.LoadFromData(init) + + def LoadFromData(self, init): + for item in init: + for type, data in item.items(): + commandClass = commandClasses.get(type, None) + if not commandClass: + commandClass = deprecatedCommandClasses.get(type, None) + if not commandClass: + wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") + continue + newCommand = commandClass(self.EditDialog, data) + index = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.SetClientData(index, newCommand) + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) + self.EditDialog.mainSizer.Hide(newCommand.UI) + self.UpdateBindStringDisplay() + + def SaveToData(self): + data = [] + index = 0 + for _ in self.RearrangeList.GetItems(): + # check whether we have an object already attached to this choice + cmdObject = self.RearrangeList.GetClientData(index) + commandClassName = commandRevClasses[type(cmdObject)] + data.append({commandClassName: cmdObject.Serialize()}) + index = index + 1 + return data + + def OnAddStepButton(self, evt): + button = evt.EventObject + if not self.AddStepMenu: + self.AddStepMenu = self.makeAddStepMenu() + button.PopupMenu(self.AddStepMenu) + + + def OnOKButton(self, _): + if self.Button.tgtTxtCtrl: + bindString = self.MakeBindString() + if bindString != self.Button.tgtTxtCtrl.GetValue(): + self.Button.tgtTxtCtrl.SetValue(bindString) + wx.App.Get().Main.Profile.SetModified() + self.Close() + + def OnRearrangeDelete(self, _): + current = self.RearrangeList.GetSelection() + if current == wx.NOT_FOUND: return + + self.RearrangeList.Delete(current) + self.UpdateBindStringDisplay() + + def OnRearrangeUp(self, _): + self.RearrangeList.MoveCurrentUp() + self.UpdateBindStringDisplay() + + def OnRearrangeDown(self, _): + self.RearrangeList.MoveCurrentDown() + self.UpdateBindStringDisplay() + + def OnRearrangeEdit(self, _): + index = self.RearrangeList.GetSelection() + + # check whether we have an object already attached to this choice + cmdObject = None + try: + cmdObject = self.RearrangeList.GetClientData(index) + except Exception: + pass + + if cmdObject: + self.ShowEditDialogFor(cmdObject) + self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) + else: + print("cmdObject was None") + self.UpdateBindStringDisplay() + + # OnAddStepMenu creates a new step and adds it to the rearrangelist + def OnAddStepMenu(self, evt): + menuitem = self.AddStepMenu.FindItemById(evt.GetId()) + chosenName = menuitem.GetItemLabel() + + # make a new command object, attached to the parent dialog + newCommandClass = commandClasses[chosenName] + newCommand = newCommandClass(self.EditDialog) + + # show the edit dialog if this command needs it + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) + if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): + self.EditDialog.mainSizer.Remove(newCommand.UI) + return + + newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.Select(newBindIndex) + self.RearrangeList.SetClientData(newBindIndex, newCommand) + + self.OnListSelect() + self.UpdateBindStringDisplay() + + def OnListSelect(self, _ = None): + selected = self.RearrangeList.GetSelection() + + if selected != wx.NOT_FOUND: + selCommand = self.RearrangeList.GetClientData(selected) + if selCommand.UI: + self.EditButton.Enable() + else: + self.EditButton.Disable() + + def UpdateBindStringDisplay(self): + self.BindStringDisplay.SetValue(self.MakeBindString()) + self.BindStringDisplay.SetToolTip(self.MakeBindString()) + + def MakeBindString(self): + cmdBindStrings = [] + for index in range(self.RearrangeList.GetCount()): + c = self.RearrangeList.GetClientData(index) + if c: cmdBindStrings.append(c.MakeBindString()) + + bindstring = ('$$'.join(cmdBindStrings)) + return bindstring + + def ShowEditDialogFor(self, command): + if not command.UI: return + + self.EditDialog.mainSizer.Show(command.UI) + + self.EditDialog.Layout() + self.EditDialog.Fit() + + self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') + returnval = self.EditDialog.ShowModal() + + self.EditDialog.mainSizer.Hide(command.UI) + + return returnval + + def makeAddStepMenu(self): + + stepMenu = wx.Menu() + + for subname in menuStructure: + submenu = wx.Menu() + stepMenu.AppendSubMenu(submenu, subname) + for classname in menuStructure[subname]: + submenu.Append(wx.ID_ANY, classname) + + stepMenu.Append(wx.ID_ANY, 'Custom Bind') + + return stepMenu + +class PowerBinderButton(wx.BitmapButton): + + def __init__(self, parent, tgtTxtCtrl, init = {}): + wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) + self.Init = init + self.Dialog = None + self.DialogParent = parent + + self.tgtTxtCtrl = tgtTxtCtrl + self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) + self.SetToolTip("Launch PowerBinder") + + def PowerBinderEventHandler(self, _): + self.PowerBinderDialog().Show() + + def LoadFromData(self, data): + self.PowerBinderDialog().LoadFromData(data) + + def SaveToData(self): + return self.PowerBinderDialog().SaveToData() + + def PowerBinderDialog(self): + if not self.Dialog: + self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) + return self.Dialog + + +class PowerBinderEditDialog(wx.Dialog): + def __init__(self, parent): + wx.Dialog.__init__(self, parent, -1, "Edit Step", + style = wx.DEFAULT_DIALOG_STYLE) + + outerSizer = wx.BoxSizer(wx.VERTICAL) + + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + self.mainSizer.SetMinSize([500, 150]) + + self.Page = parent.Page + + self.mainSizer.Add( + self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), + 0, wx.EXPAND|wx.ALL, 10) + + outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) + + self.SetSizerAndFit(outerSizer) + self.Layout() + self.Fit() + +########### Power Binder Command Objects +class PowerBindCmd(): + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + commandClassName = commandRevClasses[type(self)] + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{commandClassName} - {short_bindstr}" + + +####### Away From Keyboard +class AFKCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) + +####### Attribute Monitor +class AttributeMonitorCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.Groups = {} + self.AttributeTable = { + 'Base' : { + 'Current Hit Points' : 'NT H', + 'Max Hit Points' : 'X H', + 'Current Endurance' : 'T E', + 'Max Endurance' : 'X EN', + 'Regeneration Rate' : 'N RAT', + 'Recovery Rate' : 'Y RA', + 'Endurance Consumption' : 'SU', + 'ToHit Bonus' : 'T B', + 'Accuracy Bonus' : 'CC', + 'Last Hit Chance' : 'T C', + 'Damage Bonus' : 'DA', + 'Healing Bonus' : 'NG B', + 'Recharge Time Bonus' : 'ME B', + 'Endurance Discount' : 'CE DIS', + 'Stealth Radius (PvP)' : 'PVP', + 'Stealth Radius (PvE)' : 'PVE', + 'Perception Radius' : 'RC', + 'Range Bonus' : 'GE B', + 'Threat Level' : 'AT L', + 'Experience to Next Level' : 'XT', + 'Experience Debt' : 'XP', + 'Influence / Infamy' : 'INF', + 'Inherent' : 'NH', + }, + 'Movement Speed' : { + 'Flying Speed' : 'FL', + 'Jumping Speed' : 'PI', + 'Max Jump Height' : 'X J', + 'Run Speed' : 'RU', + }, + 'Damage Resistance' : { + 'Smashing Resistance' : 'G R', + 'Lethal Resistance' : 'L R', + 'Fire Resistance' : 'RE R', + 'Cold Resistance' : 'COLD R', + 'Energy Resistance' : 'DamageType[4]', + 'Negative Energy Resistance' : 'GY R', + 'Psyonic Resistance' : 'NIC R', + 'Toxic Resistance' : 'XIC R', + }, + 'Defense' : { + 'Base Defense' : 'BAS', + 'Ranged Defense' : 'ED', + 'Melee Defense' : 'MEL', + 'AoE Defense' : '2', + 'Smashing Defense' : '3', + 'Lethal Defense' : '4', + 'Fire Defense' : '5', + 'Cold Defense' : '6', + 'Energy Defense' : '7', + 'Negative Energy Defense' : '8', + 'Psionic Defense' : '9', + 'Toxic Defense' : '1', + }, + 'Debuff Resistance' : { + 'Regeneration Resistance' : 'ON R', + 'Recovery Resistance' : 'RY R', + 'To Hit Resistance' : 'IT R', + 'Defense Resistance' : 'NSE RES', + }, + 'Status Effect Protection' : { + 'Hold Protection' : 'D P', + 'Immobilize Protection' : 'LIZE P', + 'Stun Protection' : 'N P', + 'Sleep Protection' : 'P P', + 'Knockback Protection' : 'K P', + 'Confuse Protection' : 'SE P', + 'Terrorize Protection' : 'ZE P', + 'Repel Protection' : 'EL P', + 'Teleport Protection' : 'T P', + }, + 'Status Effect Resistance' : { + 'Hold Resistance' : 'D R', + 'Immobilize Resistance' : 'LIZE R', + 'Stun Resistance' : 'N R', + 'Sleep Resistance' : 'P R', + 'Knockback Resistance' : 'K R', + 'Confuse Resistance' : 'SE R', + 'Terrorize Resistance' : 'ZE R', + 'Placate Resistance' : 'TE R', + 'Taunt Resistance' : 'NT R', + }, + 'Miscellaneous' : { + 'Level Shift' : 'L S', + }, + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.AttributeMenu = wx.Menu() + for group, controls in self.AttributeTable.items(): + submenu = wx.Menu() + self.AttributeMenu.AppendSubMenu(submenu, group) + for cb in controls: + submenu.Append(wx.ID_ANY, cb) + + self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) + + self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) + groupSizer.Add(self.editbox) + + newButton = self.editbox.GetNewButton() + newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) + + return groupSizer + + def MakeBindString(self): + map = {} + bindstrings = [] + for _, controls in self.AttributeTable.items(): + for cb, data in controls.items(): + map[cb] = data + + for string in self.editbox.GetStrings(): + if string: + bindstrings.append(f'monitorattribute {map[string]}') + + return '$$'.join(bindstrings) + + def Serialize(self): + return { + 'attributes' : self.editbox.GetStrings() + } + + def Deserialize(self, init): + self.editbox.SetStrings(init.get('attributes', [])) + + def OnNewButton(self, evt): + evt.GetEventObject().PopupMenu(self.AttributeMenu) + + def OnMenuItem(self, evt): + menuitem = evt.EventObject.FindItemById(evt.GetId()) + existingstrings = self.editbox.GetStrings() + existingstrings.append(menuitem.GetItemLabel()) + self.editbox.SetStrings(existingstrings) + +####### Auto Power +class AutoPowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) + autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.autoPowerName = PowerPicker(dialog) + autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) + + return autoPowerSizer + + def MakeBindString(self): + return f"powexecauto {self.autoPowerName.GetLabel()}" + + def Serialize(self): + return { + 'pname' : self.autoPowerName.GetLabel(), + 'picon' : self.autoPowerName.IconFilename + } + + def Deserialize(self, init): + if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) + +####### Buff Display Command +class BuffDisplayCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.buffDisplayMap = { + 'Status Window' : { + 'Hide Auto' : 1, + 'Hide Toggles' : 2, + 'No Blinking' : 4, + 'No Stacking' : 8, + 'Numeric Stacking' : 16, + 'Hide Buff Numbers' : 32, + 'Stop Sending Buffs' : 64, + }, + 'Group Window' : { + 'Hide Auto' : 256, + 'Hide Toggles' : 512, + 'No Blinking' : 1024, + 'No Stacking' : 2048, + 'Numeric Stacking' : 4096, + 'Hide Buff Numbers' : 8192, + 'Stop Sending Buffs' : 16384, + }, + 'Pet Window' : { + 'Hide Auto' : 65536, + 'Hide Toggles' : 131072, + 'No Blinking' : 262144, + 'No Stacking' : 524288, + 'Numeric Stacking' : 1048576, + 'Hide Buff Numbers' : 2097152, + 'Stop Sending Buffs' : 4194304, + }, + } + self.Groups = {} + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + for group, controls in self.buffDisplayMap.items(): + self.Groups[group] = ControlGroup(dialog, self.Page, label = group) + groupid = self.Groups[group].GetStaticBox().GetId() + for cb, data in controls.items(): + self.Groups[group].AddControl( + ctlType = 'checkbox', + ctlName = f"{groupid}_{group}_{cb}", + label = cb, + data = data, + ) + + groupSizer.Add(self.Groups[group]) + + return groupSizer + + def CalculateValue(self): + page = wx.App.Get().Main.Profile.CustomBinds + + total = 0 + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] + if checkbox.IsChecked(): + total = total + checkbox.Data + return total + + def MakeBindString(self): + return f"optionset buffsettings {self.CalculateValue()}" + + def Serialize(self): + return { 'value' : self.CalculateValue() } + + def Deserialize(self, init): + value = init.get('value', 0) + + value = value or 0 # in case we had for some reason 'None' stashed in the init values + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] + checkbox.SetValue( checkbox.Data & value ) + +####### Chat Command +class ChatCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.chatChannelMap = { # before __init__ + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + chatCommandSizer = wx.GridBagSizer(5, 5) + self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") + chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) + # row 1 + self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) + self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) + self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) + # row 2 + self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) + self.chatCommandDuration.SetRange(1, 20) + self.chatCommandDuration.SetValue(7) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandDuration, (2,1)) + self.chatCommandChatSize = wx.Choice(dialog, -1, + choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) + self.chatCommandChatSize.SetSelection(5) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) + self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) + self.chatCommandChannel.SetSelection(0) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChannel, (2,5)) + # row 3 + self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") + chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) + self.chatCommandMessage = wx.TextCtrl(dialog, -1) + self.chatCommandMessage.SetHint('Chat Command Text') + chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) + + return chatCommandSizer + + def MakeBindString(self): + duration = self.chatCommandDuration.GetValue() + + choice = self.chatCommandChatSize + index = choice.GetSelection() + size = choice.GetString(index) + + duration = f"" if duration != 7 else "" + size = f"" if size != "1" else "" + + bdcolor = fgcolor = bgcolor = '' + if self.chatCommandUseColorsCB.IsChecked(): + bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + + bdcolor = f"" + fgcolor = f"" + bgcolor = f"" + + beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' + text = self.chatCommandMessage.GetValue() + + choice = self.chatCommandChannel + index = choice.GetSelection() + channel = choice.GetString(index) + + return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" + + def Serialize(self): + return { + 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), + 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), + 'channel' : self.chatCommandChannel .GetSelection(), + 'size' : self.chatCommandChatSize.GetSelection(), + 'duration' : self.chatCommandDuration.GetValue(), + 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'text' : self.chatCommandMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) + if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) + if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) + if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) + if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) + if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) + if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) + if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) + if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) + + +####### Chat Command Global +class ChatGlobalCmd(PowerBindCmd): + def BuildUI(self, dialog): + chatCommandGlobalSizer = wx.GridBagSizer(5,5) + + self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") + chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) + + self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalChannel.SetHint("Channel") + chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) + + self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') + chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) + + chatCommandGlobalSizer.AddGrowableCol(1) + + return chatCommandGlobalSizer + + def MakeBindString(self): + useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() + channel = self.chatCommandGlobalChannel.GetValue() + message = self.chatCommandGlobalMessage.GetValue() + + preface = "beginchat /" if useBeginchat else "" + + return f'{preface}send "{channel}" {message}' + + def Serialize(self): + return { + 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), + 'channel' : self.chatCommandGlobalChannel.GetValue(), + 'message' : self.chatCommandGlobalMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) + if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) + if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) + +#######Costume Change +class CostumeChangeCmd(PowerBindCmd): + def BuildUI(self, dialog): + costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeCostume = wx.Choice(dialog, -1, + choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) + self.costumeChangeCostume.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeEmote = wx.Choice(dialog, -1, + choices = GameData.Emotes['costumechange']) + self.costumeChangeEmote.Insert("- None -", 0) + self.costumeChangeEmote.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return costumeChangeSizer + + def MakeBindString(self): + costumeNumber = self.costumeChangeCostume.GetSelection() + costumeEmote = self.costumeChangeEmote.GetSelection() + + if costumeEmote: # None, or 0 == "- None -" + ccCmd = 'cce' + emoteName = self.costumeChangeEmote.GetString(costumeEmote) + emoteName = " CC" + emoteName.replace(" ","") + else: + ccCmd = 'cc' + emoteName = '' + + return f"{ccCmd} {costumeNumber}{emoteName}" + + def Serialize(self): + return{ + 'costumeNumber': self.costumeChangeCostume.GetSelection(), + 'costumeEmote' : self.costumeChangeEmote.GetSelection(), + } + + def Deserialize(self, init): + if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) + if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) + +####### Movement Command +class MovementCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + self.plusbutton.SetValue(True) + + self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.commandchoice = wx.Choice(dialog, choices = [ + "forward", "left", "right", "backward", "up", "down", + "turnleft", "turnright", "first", "autorun", "clicktomove", + ],) + sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) + self.commandchoice.SetSelection(0) + + self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + pre = post = '' + if self.plusbutton.GetValue() : pre = "+" + elif self.plusplusbutton.GetValue() : pre = "++" + elif self.minusbutton.GetValue() : pre = "-" + elif self.zerobutton.GetValue() : post = " 0" + elif self.onebutton.GetValue() : post = " 1" + + command = self.commandchoice.GetString(self.commandchoice.GetSelection()) + + return f"{pre}{command}{post}" + + def Serialize(self): + mod = '' + if self.plusbutton.GetValue() : mod = "plus" + elif self.plusplusbutton.GetValue() : mod = "plusplus" + elif self.minusbutton.GetValue() : mod = "minus" + elif self.zerobutton.GetValue() : mod = "zero" + elif self.onebutton.GetValue() : mod = "one" + + return { + 'mod' : mod, + 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), + } + + def Deserialize(self, init): + mod = init.get('mod', 'plus') + + if mod == 'plus' : self.plusbutton.SetValue(True) + elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) + elif mod == 'minus' : self.minusbutton.SetValue(True) + elif mod == 'zero' : self.zerobutton.SetValue(True) + elif mod == 'one' : self.onebutton.SetValue(True) + + self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) + +####### Graphics Command +class GraphicsCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.FlexGridSizer(2) + + self.visscalecb = wx.CheckBox(dialog, label = "visscale") + sizer.Add(self.visscalecb) + self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) + sizer.Add(self.visscalesc) + + self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") + sizer.Add(self.dofweightcb) + self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) + sizer.Add(self.dofweightsc) + + self.fsaacb = wx.CheckBox(dialog, label = "fsaa") + sizer.Add(self.fsaacb) + self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) + self.fsaach.SetSelection(0) + sizer.Add(self.fsaach) + + self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") + sizer.Add(self.bloomscalecb) + self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) + self.bloomscalech.SetSelection(0) + sizer.Add(self.bloomscalech) + + self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") + sizer.Add(self.bloomweightcb) + self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) + sizer.Add(self.bloomweightsc) + + self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") + sizer.Add(self.lodbiascb) + self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) + sizer.Add(self.lodbiassc) + + self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") + sizer.Add(self.renderscalecb) + self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) + sizer.Add(self.renderscalesc) + + return sizer + + def MakeBindString(self): + # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. + bindstrings = [] + if self.visscalecb.IsChecked(): + bindstrings.append("visscale " + str(self.visscalesc.GetValue())) + if self.dofweightcb.IsChecked(): + bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) + if self.fsaacb.IsChecked(): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bindstrings.append("fsaa " + fsaavalue) + if self.bloomscalecb.IsChecked(): + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + bindstrings.append("bloomscale " + bloomscalevalue) + if self.bloomweightcb.IsChecked(): + bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) + if self.lodbiascb.IsChecked(): + bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) + if self.renderscalecb.IsChecked(): + bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) + + return '$$'.join(bindstrings) + + def Serialize(self): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + return { + 'visscalecb' : self.visscalecb.IsChecked(), + 'visscalesc' : self.visscalesc.GetValue(), + 'dofweightcb' : self.dofweightcb.IsChecked(), + 'dofweightsc' : self.dofweightsc.GetValue(), + 'fsaacb' : self.fsaacb.IsChecked(), + 'fsaach' : fsaavalue, + 'bloomscalecb' : self.bloomscalecb.IsChecked(), + 'bloomscalech' : bloomscalevalue, + 'bloomweightcb' : self.bloomweightcb.IsChecked(), + 'bloomweightsc' : self.bloomweightsc.GetValue(), + 'lodbiascb' : self.lodbiascb.IsChecked(), + 'lodbiassc' : self.lodbiassc.GetValue(), + 'renderscalecb' : self.renderscalecb.IsChecked(), + 'renderscalesc' : self.renderscalesc.GetValue(), + } + + def Deserialize(self, init): + self.visscalecb.SetValue(init.get('visscalecb', False)) + self.visscalesc.SetValue(init.get('visscalesc', 1.0)) + self.dofweightcb.SetValue(init.get('dofweightcb', False)) + self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) + self.fsaacb.SetValue(init.get('fsaacb', False)) + self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) + self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) + self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) + self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) + self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) + self.lodbiascb.SetValue(init.get('lodbiascb', False)) + self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) + self.renderscalecb.SetValue(init.get('renderscalecb', False)) + self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) + +####### Custom Bind +class CustomBindCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.customBindName = wx.TextCtrl(dialog, -1) + self.customBindName.SetHint('Custom Bind Text') + sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + return self.customBindName.GetValue() + + def Serialize(self): + return { 'customBindName': self.customBindName.GetValue() } + + def Deserialize(self,init): + if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) + +####### Emote +class EmoteCmd(PowerBindCmd): + def BuildUI(self, dialog): + emoteSizer = wx.BoxSizer(wx.HORIZONTAL) + self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") + emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + self.emoteName = wx.Button(dialog, -1, "...") + self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) + emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) + + return emoteSizer + + def MakeBindString(self): + displayedEmoteName = self.emoteName.GetLabel() + actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] + + return actualEmotePayload + + def Serialize(self): + return {'emoteName': self.emoteName.GetLabel()} + + def Deserialize(self, init): + if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) + +####### Load Binds Directory +class LoadBindsDir(PowerBindCmd): + def BuildUI(self, dialog): + mainSizer = wx.BoxSizer(wx.VERTICAL) + + lbSizer = wx.BoxSizer(wx.HORIZONTAL) + lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") + lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + profiles = Profile.GetAllProfileBindsDirs() + + self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) + lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") + self.lbResetCB.SetValue(True) + + mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + return mainSizer + + def MakeBindString(self): + + # If the specified binds directory disappeared between runs, we'd crash, so handle that. + if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' + + config = wx.ConfigBase.Get() + if config.Exists('GameBindPath'): + bindpath = config.Read('GameBindPath') + else: + bindpath = config.Read('BindPath') + + reset = "" + if self.lbResetCB.GetValue(): + reset = "keybind_reset$$" + + resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' + return reset + 'bindloadfile ' + str(resetfilepath) + + def Serialize(self): + return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), + 'ResetKeybinds' : self.lbResetCB.GetValue(), + } + + def Deserialize(self, init): + if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) + self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) + +####### Power Abort +class PowerAbortCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecabort' + +####### Power Unqueue +class PowerUnqueueCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecunqueue' + +####### SG Mode +class SGModeCmd(PowerBindCmd): + def BuildUI(self, dialog): + sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) + sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") + self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") + + sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) + + return sgmodeSizer + + def MakeBindString(self): + if self.sgmodeOnRB.GetValue(): + return 'sgmodeset 1' + elif self.sgmodeOffRB.GetValue(): + return 'sgmodeset 0' + else: + return 'sgmode' + + def Serialize(self): + if self.sgmodeOnRB.GetValue(): + val = "On" + elif self.sgmodeOffRB.GetValue(): + val = "Off" + else: + val = "Toggle" + + return {"value" : val} + + def Deserialize(self, init): + val = init.get('value', '') + if val == "On": + self.sgmodeOnRB.SetValue(True) + elif val == "Off": + self.sgmodeOffRB.SetValue(True) + else: + self.sgmodeToggleRB.SetValue(True) + +####### Target Custom +class TargetCustomCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetCustomSizer = wx.GridBagSizer(5,5) + targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), + flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) + self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetCustomModeChoice.SetSelection(0) + targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) + self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) + self.targetCustomOptionalName.SetHint("Optional name to match") + targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) + self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") + targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) + self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") + targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) + self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") + targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) + self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") + targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) + self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") + targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) + self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") + targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) + self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") + targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) + self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") + targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) + + targetCustomSizer.AddGrowableCol(2) + + return targetCustomSizer + + def MakeBindString(self): + choice = self.targetCustomModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + targetCommand = "targetcustom" + mode.lower() + + enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" + friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" + defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" + alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" + mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" + notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" + base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" + notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" + + name = self.targetCustomOptionalName.GetValue() + + return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" + + def Serialize(self): + return { + 'mode' : self.targetCustomModeChoice.GetSelection(), + 'enemy' : self.targetCustomCBEnemies. IsChecked(), + 'friend' : self.targetCustomCBFriends. IsChecked(), + 'defeated' : self.targetCustomCBDefeated. IsChecked(), + 'alive' : self.targetCustomCBAlive. IsChecked(), + 'mypet' : self.targetCustomCBMyPets. IsChecked(), + 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), + 'base' : self.targetCustomCBBaseItems. IsChecked(), + 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), + 'name' : self.targetCustomOptionalName.GetValue(), + } + + def Deserialize(self, init): + if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) + if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) + if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) + if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) + if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) + if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) + if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) + if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) + if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) + if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) + + +####### Target Enemy +class TargetEnemyCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) + targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetEnemyModeChoice.SetSelection(0) + targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetEnemySizer + + def MakeBindString(self): + choice = self.targetEnemyModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetenemy" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetEnemyModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) + +####### Target Friend +class TargetFriendCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) + targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetFriendModeChoice.SetSelection(0) + targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetFriendSizer + + def MakeBindString(self): + choice = self.targetFriendModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetfriend" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetFriendModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) + +####### Team/Pet Select +class TeamPetSelectCmd(PowerBindCmd): + def BuildUI(self, dialog): + teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], + style=wx.ALIGN_CENTER_VERTICAL) + self.teamPetSelectNumber.SetSelection(0) + teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) + + return teamPetSelectSizer + + def MakeBindString(self): + teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' + targetNumber = self.teamPetSelectNumber.GetSelection()+1 + + return f"{teamOrPet}select {targetNumber}" + + def Serialize(self): + return { + 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', + 'targetNum': self.teamPetSelectNumber.GetSelection(), + } + + def Deserialize(self, init): + ToP = init.get('teamOrPet', '') + if ToP == 'pet': + self.teamPetSelectPetRB.SetValue(True) + else: + self.teamPetSelectTeamRB.SetValue(True) + if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) + +####### Unselect +class UnselectCmd(PowerBindCmd): + def MakeBindString(self): + return 'unselect' + +####### Use Insp By Name +class UseInspByNameCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) + for _, types in GameData.Inspirations.items(): + for _, info in types.items(): + for insp in info['tiers']: + name = re.sub(' ', '', str(insp)) + icon = GetIcon(f'Inspirations/{name}') + self.useInspByNameModeChoice.Append(insp, icon) + self.useInspByNameModeChoice.SetSelection(0) + useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) + + return useInspByNameSizer + + def MakeBindString(self): + choice = self.useInspByNameModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "inspexecname " + mode.lower() + + def GetAllInsps(self): + Insplist = [] + for _, info in GameData.Inspirations.items(): + for insp in info['tiers']: + Insplist.append(insp) + Insplist.append("---") + Insplist.pop(-1) # snip the terminal "---" + + return Insplist + + def Serialize(self): + return { 'insp' : self.useInspByNameModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) + +####### Use Insp From Row / Column +class UseInspRowColCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnRow.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) + self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnCol.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) + + return useInspRowColumnSizer + + def MakeBindString(self): + row = self.useInspRowColumnRow.GetSelection()+1 + col = self.useInspRowColumnCol.GetSelection()+1 + + return f"inspexectray {col} {row}" + + def Serialize(self): + return { + 'col' : self.useInspRowColumnCol.GetSelection(), + 'row' : self.useInspRowColumnRow.GetSelection(), + } + + def Deserialize(self, init): + if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) + if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) + +####### Use Power +class UsePowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + outerSizer = wx.BoxSizer(wx.HORIZONTAL) + + usePowerSizer = wx.GridBagSizer(5,5) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBToggle, (0,1)) + self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOn, (0,2)) + self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOff, (0,3)) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerName = PowerPicker(dialog) + usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) + usePowerSizer.AddGrowableCol(3) + + outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) + + return outerSizer + + def MakeBindString(self): + if self.usePowerRBToggle.GetValue(): + method = "powexecname" + elif self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') + return '' + + return f"{method} {self.usePowerName.GetLabel()}" + + def Serialize(self): + if self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + method = "powexecname" + return { + 'method': method, + 'pname' : self.usePowerName.GetLabel(), + 'picon' : self.usePowerName.IconFilename + } + + def Deserialize(self, init): + method = init.get('method', '') + if method == 'powexectoggleon': + self.usePowerRBOn.SetValue(True) + elif method == 'powexectoggleoff': + self.usePowerRBOff.SetValue(True) + else: + self.usePowerRBToggle.SetValue(True) + if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) + +####### Use Power From Tray +class UsePowerFromTrayCmd(PowerBindCmd): + def BuildUI(self, dialog): + usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTrayTray = wx.Choice(dialog, -1, + choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', + 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) + self.usePowerFromTrayTray.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) + self.usePowerFromTraySlot.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return usePowerFromTraySizer + + def MakeBindString(self): + choice = self.usePowerFromTrayTray + tray = choice.GetSelection() + + choice = self.usePowerFromTraySlot + slot = choice.GetSelection()+1 + + mode = "slot" + mode2 = '' + if tray > 3: + mode = "tray" + mode2 = f" {tray - 3}" + elif tray == 3: + mode = "alt2slot" + elif tray == 2: + mode = "altslot" + + return f"powexec{mode} {slot}{mode2}" + + def Serialize(self): + return { + 'tray' : self.usePowerFromTrayTray.GetSelection(), + 'slot' : self.usePowerFromTraySlot.GetSelection(), + } + + def Deserialize(self, init): + if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) + if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) + +####### Window Color +class WindowColorCmd(PowerBindCmd): + def BuildUI(self, dialog): + windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) + borderSizer = wx.BoxSizer(wx.VERTICAL) + self.ColorBorder.SetSizer(borderSizer) + self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) + borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) + + windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) + + RGBASizer = wx.FlexGridSizer(3, 4, 5) + + RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) + self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) + self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + windowColorSizer.Add(RGBASizer) + + self.UpdateFromSlider() + + return windowColorSizer + + def MakeBindString(self): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + return f"windowcolor {Rval} {Gval} {Bval} {Aval}" + + def Serialize(self): + return { + 'Rval' : self.RSlider.GetValue(), + 'Gval' : self.GSlider.GetValue(), + 'Bval' : self.BSlider.GetValue(), + 'Aval' : self.ASlider.GetValue(), + } + + def Deserialize(self, init): + self.RSlider.SetValue(init['Rval']) + self.GSlider.SetValue(init['Gval']) + self.BSlider.SetValue(init['Bval']) + self.ASlider.SetValue(init['Aval']) + self.UpdateFromSlider() + + def UpdateFromSlider(self, _ = None): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RReadout.SetValue(Rval) + self.GReadout.SetValue(Gval) + self.BReadout.SetValue(Bval) + self.AReadout.SetValue(Aval) + self.ColorBorder.Refresh() + + def UpdateFromText(self, _ = None): + Rval = self.RReadout.GetValue() + Gval = self.GReadout.GetValue() + Bval = self.BReadout.GetValue() + Aval = self.AReadout.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RSlider.SetValue(Rval) + self.GSlider.SetValue(Gval) + self.BSlider.SetValue(Bval) + self.ASlider.SetValue(Aval) + self.ColorBorder.Refresh() + +####### Window Save / Load +class WindowSaveLoadCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) + self.CommandChoice.SetSelection(0) + sizer.Add(self.CommandChoice, 0, wx.ALL, 5) + + self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), + value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) + sizer.Add(self.FilePath, 0, wx.ALL, 5) + + return sizer + + def MakeBindString(self): + command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] + return f'{command} "{self.FilePath.GetValue()}"' + + def Serialize(self): + return { + 'command' : self.CommandChoice.GetSelection(), + 'filename' : self.FilePath.GetValue(), + } + + def Deserialize(self, init): + self.CommandChoice.SetSelection(init.get('command', 0)) + self.FilePath.SetValue(init.get('filename', '')) + +####### Window Toggle +class WindowToggleCmd(PowerBindCmd): + def BuildUI(self, dialog): + self.WindowNames = { + 'Actions' : 'actions', + 'Auction House' : 'ah', + 'Badge' : 'badge', + 'Channel Search' : 'chansearch', + 'Chat' : 'chat', + 'Custom Chat 1' : 'chat1', + 'Custom Chat 2' : 'chat2', + 'Custom Chat 3' : 'chat3', + 'Custom Chat 4' : 'chat4', + 'Clues' : 'clue', + 'Combat Numbers' : 'combatnumbers', + 'Contacts' : 'contact', + 'Contact Finder' : 'contactfinder', + 'Costumes' : 'costume', + 'Email' : 'email', + 'Enhancements' : 'enhancements', + 'Friends' : 'friend', + 'Group' : 'group', + 'Help' : 'helpwindow', + 'Incarnate' : 'incarnate', + 'Inspirations' : 'insp', + 'League' : 'league', + 'LFG' : 'lfg', + 'Map' : 'map', + 'Mission' : 'mission', + 'Nav / Compass' : 'nav', + 'Options' : 'options', + 'Pets' : 'pet', + 'Petition' : 'petition', + 'Power Tray' : 'powers', + 'Power List' : 'powerlist', + 'Quit' : 'quit', + 'Recipes' : 'recipe', + 'Salvage' : 'salvage', + 'Search' : 'search', + 'Supergroup' : 'sg', + 'Target' : 'target', + 'Team' : 'team', + 'Tray' : 'tray', + 'Tray1' : 'tray1', + 'Tray2' : 'tray2', + 'Tray3' : 'tray3', + 'Tray4' : 'tray4', + 'Tray5' : 'tray5', + 'Tray6' : 'tray6', + 'Tray7' : 'tray7', + 'Tray8' : 'tray8', + 'Vault' : 'vault', + } + + self.ShortToggleCommands = { + 'Auction House' : 'ah', + 'Chat' : 'chat', + 'Help' : 'helpwindow', + 'Map' : 'map', + 'Nav / Compass' : 'nav', + 'Power Tray' : 'powers', + 'Target' : 'target', + 'Tray' : 'tray', + } + + windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) + windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) + self.windowToggleTray.SetSelection(0) + windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.windowShowRB = wx.RadioButton(dialog, -1, "Show") + self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") + + windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) + + return windowToggleSizer + + def MakeBindString(self): + choice = self.windowToggleTray + index = choice.GetSelection() + windowdesc = choice.GetString(index) + windowname = self.WindowNames[windowdesc] + + if self.windowShowRB.GetValue(): + return 'show ' + windowname + elif self.windowHideRB.GetValue(): + return 'windowhide ' + windowname + else: + if shortcmd := self.ShortToggleCommands.get(windowdesc, None): + return shortcmd + else: + return 'toggle ' + windowname + + + def Serialize(self): + choice = self.windowToggleTray + if self.windowShowRB.GetValue(): + action = "Show" + elif self.windowHideRB.GetValue(): + action = "Hide" + else: + action = "Toggle" + return { + 'window': choice.GetString(choice.GetSelection()), + 'action': action, + } + + def Deserialize(self, init): + choice = self.windowToggleTray + if window := init.get('window', ''): + if isinstance(window, int): + choice.SetSelection(window) + else: + choice.SetSelection(choice.FindString(window)) + + if choice.GetSelection() == wx.NOT_FOUND: + choice.SetSelection(0) + + action = init.get('action', '') + if action == "Show": + self.windowShowRB.SetValue(True) + elif action == "Hide": + self.windowHideRB.SetValue(True) + else: + self.windowToggleRB.SetValue(True) + + +# Must always add to this list when adding a new command class above +menuStructure = { + 'Graphics / UI' : [ + 'Attribute Monitor', + 'Buff Display Settings', + 'Graphics Settings', + 'Window Color', + 'Window Save / Load', + 'Window Toggle', + ], + 'Inspirations' : [ + 'Use Inspiration By Name', + 'Use Inspiration From Row/Column', + ], + 'Powers' : [ + 'Auto Power', + 'Power Abort', + 'Power Unqueue', + 'Use Power', + 'Use Power From Tray', + ], + 'Social' : [ + 'Away From Keyboard', + 'Chat Command', + 'Chat Command (Global)', + 'Costume Change', + 'Emote', + 'Supergroup Mode', + ], + 'Targeting' : [ + 'Target Custom', + 'Target Enemy', + 'Target Frield', + 'Team/Pet Select', + 'Unselect', + ], + 'Misc' : [ + 'Load Binds Directory', + 'Movement Commands', + ], + # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, + # but I'm leaving it here to remind myself that we do that. + } + +# Must always add to this list when adding a new command class above +commandClasses = { + 'Auto Power' : AutoPowerCmd, + 'Away From Keyboard' : AFKCmd, + 'Attribute Monitor' : AttributeMonitorCmd, + 'Buff Display Settings' : BuffDisplayCmd, + 'Chat Command' : ChatCmd, + 'Chat Command (Global)' : ChatGlobalCmd, + 'Costume Change' : CostumeChangeCmd, + 'Custom Bind' : CustomBindCmd, + 'Emote' : EmoteCmd, + 'Graphics Settings' : GraphicsCmd, + 'Load Binds Directory' : LoadBindsDir, + 'Movement Commands' : MovementCmd, + 'Power Abort' : PowerAbortCmd, + 'Power Unqueue' : PowerUnqueueCmd, + 'Supergroup Mode' : SGModeCmd, + 'Target Custom' : TargetCustomCmd, + 'Target Enemy' : TargetEnemyCmd, + 'Target Friend' : TargetFriendCmd, + 'Team/Pet Select' : TeamPetSelectCmd, + 'Unselect' : UnselectCmd, + 'Use Inspiration By Name' : UseInspByNameCmd, + 'Use Inspiration From Row/Column' : UseInspRowColCmd, + 'Use Power' : UsePowerCmd, + 'Use Power From Tray' : UsePowerFromTrayCmd, + 'Window Color' : WindowColorCmd, + 'Window Save / Load' : WindowSaveLoadCmd, + 'Window Toggle' : WindowToggleCmd, +} +# use these when we rename a commandClass so that old Profiles will still load correctly. +# If we've also updated the class, we need to try to make sure the new class will still +# Deserialize the legacy data, or at least not crash. +deprecatedCommandClasses = { + 'SG Mode Toggle' : SGModeCmd, + 'Use Insp By Name' : UseInspByNameCmd, + 'Use Insp From Row/Column' : UseInspRowColCmd, +} +commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/UsePowerCmd.py b/UI/PowerBinderCommand/UsePowerCmd.py new file mode 100644 index 0000000..4c02ab7 --- /dev/null +++ b/UI/PowerBinderCommand/UsePowerCmd.py @@ -0,0 +1,1800 @@ +import wx +import re +import UI +import UI.EmotePicker +from UI.ControlGroup import ControlGroup +from UI.PowerPicker import PowerPicker +from Help import HelpButton +import wx.adv +from wx.adv import BitmapComboBox, EditableListBox +from pathlib import PureWindowsPath +import GameData +import Profile +from Icon import GetIcon + +class PowerBinderDialog(wx.Dialog): + def __init__(self, parent, button, init = {}): + wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) + + self.Page = parent.Page + self.EditDialog = PowerBinderEditDialog(self) + self.Button = button + self.AddStepMenu = self.makeAddStepMenu() + + sizer = wx.BoxSizer(wx.VERTICAL); + self.mainSizer = sizer + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) + # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) + # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) + #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) + AddStepButton = wx.Button(self, -1, 'Add Step') + AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) + AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) + choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) + choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) + sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) + + rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) + + self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) + self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) + self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) + rearrangeCtrl.Add(self.RearrangeList, 1) + + rearrangeButtons = wx.BoxSizer(wx.VERTICAL) + self.DelButton = wx.Button(self, -1, "Delete") + self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) + self.EditButton = wx.Button(self, -1, "Edit") + self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) + self.EditButton.Disable() + upButton = wx.Button(self, -1, "\u25B2") + upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) + downButton = wx.Button(self, -1, "\u25BC") + downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) + rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) + rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) + + sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.BindStringDisplay = wx.TextCtrl(self, -1) + self.BindStringDisplay.Disable() + choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, + wx.ALIGN_CENTER_VERTICAL) + choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) + + sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) + + sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) + + # need to dig around and get the OK button since we show this dialog modelessly now. + okButton = self.FindWindow(self.GetAffirmativeId()) + okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) + + # Wrap everything in a vbox to add some padding + vbox = wx.BoxSizer(wx.VERTICAL); + vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); + + self.SetSizerAndFit(vbox); + self.Layout() + self.Fit() + self.SetFocus() + + # if we are loading from profile, ie, have "init", build the list from it + if init: self.LoadFromData(init) + + def LoadFromData(self, init): + for item in init: + for type, data in item.items(): + commandClass = commandClasses.get(type, None) + if not commandClass: + commandClass = deprecatedCommandClasses.get(type, None) + if not commandClass: + wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") + continue + newCommand = commandClass(self.EditDialog, data) + index = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.SetClientData(index, newCommand) + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) + self.EditDialog.mainSizer.Hide(newCommand.UI) + self.UpdateBindStringDisplay() + + def SaveToData(self): + data = [] + index = 0 + for _ in self.RearrangeList.GetItems(): + # check whether we have an object already attached to this choice + cmdObject = self.RearrangeList.GetClientData(index) + commandClassName = commandRevClasses[type(cmdObject)] + data.append({commandClassName: cmdObject.Serialize()}) + index = index + 1 + return data + + def OnAddStepButton(self, evt): + button = evt.EventObject + if not self.AddStepMenu: + self.AddStepMenu = self.makeAddStepMenu() + button.PopupMenu(self.AddStepMenu) + + + def OnOKButton(self, _): + if self.Button.tgtTxtCtrl: + bindString = self.MakeBindString() + if bindString != self.Button.tgtTxtCtrl.GetValue(): + self.Button.tgtTxtCtrl.SetValue(bindString) + wx.App.Get().Main.Profile.SetModified() + self.Close() + + def OnRearrangeDelete(self, _): + current = self.RearrangeList.GetSelection() + if current == wx.NOT_FOUND: return + + self.RearrangeList.Delete(current) + self.UpdateBindStringDisplay() + + def OnRearrangeUp(self, _): + self.RearrangeList.MoveCurrentUp() + self.UpdateBindStringDisplay() + + def OnRearrangeDown(self, _): + self.RearrangeList.MoveCurrentDown() + self.UpdateBindStringDisplay() + + def OnRearrangeEdit(self, _): + index = self.RearrangeList.GetSelection() + + # check whether we have an object already attached to this choice + cmdObject = None + try: + cmdObject = self.RearrangeList.GetClientData(index) + except Exception: + pass + + if cmdObject: + self.ShowEditDialogFor(cmdObject) + self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) + else: + print("cmdObject was None") + self.UpdateBindStringDisplay() + + # OnAddStepMenu creates a new step and adds it to the rearrangelist + def OnAddStepMenu(self, evt): + menuitem = self.AddStepMenu.FindItemById(evt.GetId()) + chosenName = menuitem.GetItemLabel() + + # make a new command object, attached to the parent dialog + newCommandClass = commandClasses[chosenName] + newCommand = newCommandClass(self.EditDialog) + + # show the edit dialog if this command needs it + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) + if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): + self.EditDialog.mainSizer.Remove(newCommand.UI) + return + + newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.Select(newBindIndex) + self.RearrangeList.SetClientData(newBindIndex, newCommand) + + self.OnListSelect() + self.UpdateBindStringDisplay() + + def OnListSelect(self, _ = None): + selected = self.RearrangeList.GetSelection() + + if selected != wx.NOT_FOUND: + selCommand = self.RearrangeList.GetClientData(selected) + if selCommand.UI: + self.EditButton.Enable() + else: + self.EditButton.Disable() + + def UpdateBindStringDisplay(self): + self.BindStringDisplay.SetValue(self.MakeBindString()) + self.BindStringDisplay.SetToolTip(self.MakeBindString()) + + def MakeBindString(self): + cmdBindStrings = [] + for index in range(self.RearrangeList.GetCount()): + c = self.RearrangeList.GetClientData(index) + if c: cmdBindStrings.append(c.MakeBindString()) + + bindstring = ('$$'.join(cmdBindStrings)) + return bindstring + + def ShowEditDialogFor(self, command): + if not command.UI: return + + self.EditDialog.mainSizer.Show(command.UI) + + self.EditDialog.Layout() + self.EditDialog.Fit() + + self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') + returnval = self.EditDialog.ShowModal() + + self.EditDialog.mainSizer.Hide(command.UI) + + return returnval + + def makeAddStepMenu(self): + + stepMenu = wx.Menu() + + for subname in menuStructure: + submenu = wx.Menu() + stepMenu.AppendSubMenu(submenu, subname) + for classname in menuStructure[subname]: + submenu.Append(wx.ID_ANY, classname) + + stepMenu.Append(wx.ID_ANY, 'Custom Bind') + + return stepMenu + +class PowerBinderButton(wx.BitmapButton): + + def __init__(self, parent, tgtTxtCtrl, init = {}): + wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) + self.Init = init + self.Dialog = None + self.DialogParent = parent + + self.tgtTxtCtrl = tgtTxtCtrl + self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) + self.SetToolTip("Launch PowerBinder") + + def PowerBinderEventHandler(self, _): + self.PowerBinderDialog().Show() + + def LoadFromData(self, data): + self.PowerBinderDialog().LoadFromData(data) + + def SaveToData(self): + return self.PowerBinderDialog().SaveToData() + + def PowerBinderDialog(self): + if not self.Dialog: + self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) + return self.Dialog + + +class PowerBinderEditDialog(wx.Dialog): + def __init__(self, parent): + wx.Dialog.__init__(self, parent, -1, "Edit Step", + style = wx.DEFAULT_DIALOG_STYLE) + + outerSizer = wx.BoxSizer(wx.VERTICAL) + + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + self.mainSizer.SetMinSize([500, 150]) + + self.Page = parent.Page + + self.mainSizer.Add( + self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), + 0, wx.EXPAND|wx.ALL, 10) + + outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) + + self.SetSizerAndFit(outerSizer) + self.Layout() + self.Fit() + +########### Power Binder Command Objects +class PowerBindCmd(): + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + commandClassName = commandRevClasses[type(self)] + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{commandClassName} - {short_bindstr}" + + +####### Away From Keyboard +class AFKCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) + +####### Attribute Monitor +class AttributeMonitorCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.Groups = {} + self.AttributeTable = { + 'Base' : { + 'Current Hit Points' : 'NT H', + 'Max Hit Points' : 'X H', + 'Current Endurance' : 'T E', + 'Max Endurance' : 'X EN', + 'Regeneration Rate' : 'N RAT', + 'Recovery Rate' : 'Y RA', + 'Endurance Consumption' : 'SU', + 'ToHit Bonus' : 'T B', + 'Accuracy Bonus' : 'CC', + 'Last Hit Chance' : 'T C', + 'Damage Bonus' : 'DA', + 'Healing Bonus' : 'NG B', + 'Recharge Time Bonus' : 'ME B', + 'Endurance Discount' : 'CE DIS', + 'Stealth Radius (PvP)' : 'PVP', + 'Stealth Radius (PvE)' : 'PVE', + 'Perception Radius' : 'RC', + 'Range Bonus' : 'GE B', + 'Threat Level' : 'AT L', + 'Experience to Next Level' : 'XT', + 'Experience Debt' : 'XP', + 'Influence / Infamy' : 'INF', + 'Inherent' : 'NH', + }, + 'Movement Speed' : { + 'Flying Speed' : 'FL', + 'Jumping Speed' : 'PI', + 'Max Jump Height' : 'X J', + 'Run Speed' : 'RU', + }, + 'Damage Resistance' : { + 'Smashing Resistance' : 'G R', + 'Lethal Resistance' : 'L R', + 'Fire Resistance' : 'RE R', + 'Cold Resistance' : 'COLD R', + 'Energy Resistance' : 'DamageType[4]', + 'Negative Energy Resistance' : 'GY R', + 'Psyonic Resistance' : 'NIC R', + 'Toxic Resistance' : 'XIC R', + }, + 'Defense' : { + 'Base Defense' : 'BAS', + 'Ranged Defense' : 'ED', + 'Melee Defense' : 'MEL', + 'AoE Defense' : '2', + 'Smashing Defense' : '3', + 'Lethal Defense' : '4', + 'Fire Defense' : '5', + 'Cold Defense' : '6', + 'Energy Defense' : '7', + 'Negative Energy Defense' : '8', + 'Psionic Defense' : '9', + 'Toxic Defense' : '1', + }, + 'Debuff Resistance' : { + 'Regeneration Resistance' : 'ON R', + 'Recovery Resistance' : 'RY R', + 'To Hit Resistance' : 'IT R', + 'Defense Resistance' : 'NSE RES', + }, + 'Status Effect Protection' : { + 'Hold Protection' : 'D P', + 'Immobilize Protection' : 'LIZE P', + 'Stun Protection' : 'N P', + 'Sleep Protection' : 'P P', + 'Knockback Protection' : 'K P', + 'Confuse Protection' : 'SE P', + 'Terrorize Protection' : 'ZE P', + 'Repel Protection' : 'EL P', + 'Teleport Protection' : 'T P', + }, + 'Status Effect Resistance' : { + 'Hold Resistance' : 'D R', + 'Immobilize Resistance' : 'LIZE R', + 'Stun Resistance' : 'N R', + 'Sleep Resistance' : 'P R', + 'Knockback Resistance' : 'K R', + 'Confuse Resistance' : 'SE R', + 'Terrorize Resistance' : 'ZE R', + 'Placate Resistance' : 'TE R', + 'Taunt Resistance' : 'NT R', + }, + 'Miscellaneous' : { + 'Level Shift' : 'L S', + }, + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.AttributeMenu = wx.Menu() + for group, controls in self.AttributeTable.items(): + submenu = wx.Menu() + self.AttributeMenu.AppendSubMenu(submenu, group) + for cb in controls: + submenu.Append(wx.ID_ANY, cb) + + self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) + + self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) + groupSizer.Add(self.editbox) + + newButton = self.editbox.GetNewButton() + newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) + + return groupSizer + + def MakeBindString(self): + map = {} + bindstrings = [] + for _, controls in self.AttributeTable.items(): + for cb, data in controls.items(): + map[cb] = data + + for string in self.editbox.GetStrings(): + if string: + bindstrings.append(f'monitorattribute {map[string]}') + + return '$$'.join(bindstrings) + + def Serialize(self): + return { + 'attributes' : self.editbox.GetStrings() + } + + def Deserialize(self, init): + self.editbox.SetStrings(init.get('attributes', [])) + + def OnNewButton(self, evt): + evt.GetEventObject().PopupMenu(self.AttributeMenu) + + def OnMenuItem(self, evt): + menuitem = evt.EventObject.FindItemById(evt.GetId()) + existingstrings = self.editbox.GetStrings() + existingstrings.append(menuitem.GetItemLabel()) + self.editbox.SetStrings(existingstrings) + +####### Auto Power +class AutoPowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) + autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.autoPowerName = PowerPicker(dialog) + autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) + + return autoPowerSizer + + def MakeBindString(self): + return f"powexecauto {self.autoPowerName.GetLabel()}" + + def Serialize(self): + return { + 'pname' : self.autoPowerName.GetLabel(), + 'picon' : self.autoPowerName.IconFilename + } + + def Deserialize(self, init): + if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) + +####### Buff Display Command +class BuffDisplayCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.buffDisplayMap = { + 'Status Window' : { + 'Hide Auto' : 1, + 'Hide Toggles' : 2, + 'No Blinking' : 4, + 'No Stacking' : 8, + 'Numeric Stacking' : 16, + 'Hide Buff Numbers' : 32, + 'Stop Sending Buffs' : 64, + }, + 'Group Window' : { + 'Hide Auto' : 256, + 'Hide Toggles' : 512, + 'No Blinking' : 1024, + 'No Stacking' : 2048, + 'Numeric Stacking' : 4096, + 'Hide Buff Numbers' : 8192, + 'Stop Sending Buffs' : 16384, + }, + 'Pet Window' : { + 'Hide Auto' : 65536, + 'Hide Toggles' : 131072, + 'No Blinking' : 262144, + 'No Stacking' : 524288, + 'Numeric Stacking' : 1048576, + 'Hide Buff Numbers' : 2097152, + 'Stop Sending Buffs' : 4194304, + }, + } + self.Groups = {} + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + for group, controls in self.buffDisplayMap.items(): + self.Groups[group] = ControlGroup(dialog, self.Page, label = group) + groupid = self.Groups[group].GetStaticBox().GetId() + for cb, data in controls.items(): + self.Groups[group].AddControl( + ctlType = 'checkbox', + ctlName = f"{groupid}_{group}_{cb}", + label = cb, + data = data, + ) + + groupSizer.Add(self.Groups[group]) + + return groupSizer + + def CalculateValue(self): + page = wx.App.Get().Main.Profile.CustomBinds + + total = 0 + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] + if checkbox.IsChecked(): + total = total + checkbox.Data + return total + + def MakeBindString(self): + return f"optionset buffsettings {self.CalculateValue()}" + + def Serialize(self): + return { 'value' : self.CalculateValue() } + + def Deserialize(self, init): + value = init.get('value', 0) + + value = value or 0 # in case we had for some reason 'None' stashed in the init values + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] + checkbox.SetValue( checkbox.Data & value ) + +####### Chat Command +class ChatCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.chatChannelMap = { # before __init__ + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + chatCommandSizer = wx.GridBagSizer(5, 5) + self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") + chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) + # row 1 + self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) + self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) + self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) + # row 2 + self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) + self.chatCommandDuration.SetRange(1, 20) + self.chatCommandDuration.SetValue(7) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandDuration, (2,1)) + self.chatCommandChatSize = wx.Choice(dialog, -1, + choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) + self.chatCommandChatSize.SetSelection(5) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) + self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) + self.chatCommandChannel.SetSelection(0) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChannel, (2,5)) + # row 3 + self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") + chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) + self.chatCommandMessage = wx.TextCtrl(dialog, -1) + self.chatCommandMessage.SetHint('Chat Command Text') + chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) + + return chatCommandSizer + + def MakeBindString(self): + duration = self.chatCommandDuration.GetValue() + + choice = self.chatCommandChatSize + index = choice.GetSelection() + size = choice.GetString(index) + + duration = f"" if duration != 7 else "" + size = f"" if size != "1" else "" + + bdcolor = fgcolor = bgcolor = '' + if self.chatCommandUseColorsCB.IsChecked(): + bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + + bdcolor = f"" + fgcolor = f"" + bgcolor = f"" + + beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' + text = self.chatCommandMessage.GetValue() + + choice = self.chatCommandChannel + index = choice.GetSelection() + channel = choice.GetString(index) + + return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" + + def Serialize(self): + return { + 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), + 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), + 'channel' : self.chatCommandChannel .GetSelection(), + 'size' : self.chatCommandChatSize.GetSelection(), + 'duration' : self.chatCommandDuration.GetValue(), + 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'text' : self.chatCommandMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) + if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) + if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) + if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) + if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) + if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) + if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) + if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) + if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) + + +####### Chat Command Global +class ChatGlobalCmd(PowerBindCmd): + def BuildUI(self, dialog): + chatCommandGlobalSizer = wx.GridBagSizer(5,5) + + self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") + chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) + + self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalChannel.SetHint("Channel") + chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) + + self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') + chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) + + chatCommandGlobalSizer.AddGrowableCol(1) + + return chatCommandGlobalSizer + + def MakeBindString(self): + useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() + channel = self.chatCommandGlobalChannel.GetValue() + message = self.chatCommandGlobalMessage.GetValue() + + preface = "beginchat /" if useBeginchat else "" + + return f'{preface}send "{channel}" {message}' + + def Serialize(self): + return { + 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), + 'channel' : self.chatCommandGlobalChannel.GetValue(), + 'message' : self.chatCommandGlobalMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) + if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) + if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) + +#######Costume Change +class CostumeChangeCmd(PowerBindCmd): + def BuildUI(self, dialog): + costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeCostume = wx.Choice(dialog, -1, + choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) + self.costumeChangeCostume.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeEmote = wx.Choice(dialog, -1, + choices = GameData.Emotes['costumechange']) + self.costumeChangeEmote.Insert("- None -", 0) + self.costumeChangeEmote.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return costumeChangeSizer + + def MakeBindString(self): + costumeNumber = self.costumeChangeCostume.GetSelection() + costumeEmote = self.costumeChangeEmote.GetSelection() + + if costumeEmote: # None, or 0 == "- None -" + ccCmd = 'cce' + emoteName = self.costumeChangeEmote.GetString(costumeEmote) + emoteName = " CC" + emoteName.replace(" ","") + else: + ccCmd = 'cc' + emoteName = '' + + return f"{ccCmd} {costumeNumber}{emoteName}" + + def Serialize(self): + return{ + 'costumeNumber': self.costumeChangeCostume.GetSelection(), + 'costumeEmote' : self.costumeChangeEmote.GetSelection(), + } + + def Deserialize(self, init): + if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) + if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) + +####### Movement Command +class MovementCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + self.plusbutton.SetValue(True) + + self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.commandchoice = wx.Choice(dialog, choices = [ + "forward", "left", "right", "backward", "up", "down", + "turnleft", "turnright", "first", "autorun", "clicktomove", + ],) + sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) + self.commandchoice.SetSelection(0) + + self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + pre = post = '' + if self.plusbutton.GetValue() : pre = "+" + elif self.plusplusbutton.GetValue() : pre = "++" + elif self.minusbutton.GetValue() : pre = "-" + elif self.zerobutton.GetValue() : post = " 0" + elif self.onebutton.GetValue() : post = " 1" + + command = self.commandchoice.GetString(self.commandchoice.GetSelection()) + + return f"{pre}{command}{post}" + + def Serialize(self): + mod = '' + if self.plusbutton.GetValue() : mod = "plus" + elif self.plusplusbutton.GetValue() : mod = "plusplus" + elif self.minusbutton.GetValue() : mod = "minus" + elif self.zerobutton.GetValue() : mod = "zero" + elif self.onebutton.GetValue() : mod = "one" + + return { + 'mod' : mod, + 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), + } + + def Deserialize(self, init): + mod = init.get('mod', 'plus') + + if mod == 'plus' : self.plusbutton.SetValue(True) + elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) + elif mod == 'minus' : self.minusbutton.SetValue(True) + elif mod == 'zero' : self.zerobutton.SetValue(True) + elif mod == 'one' : self.onebutton.SetValue(True) + + self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) + +####### Graphics Command +class GraphicsCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.FlexGridSizer(2) + + self.visscalecb = wx.CheckBox(dialog, label = "visscale") + sizer.Add(self.visscalecb) + self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) + sizer.Add(self.visscalesc) + + self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") + sizer.Add(self.dofweightcb) + self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) + sizer.Add(self.dofweightsc) + + self.fsaacb = wx.CheckBox(dialog, label = "fsaa") + sizer.Add(self.fsaacb) + self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) + self.fsaach.SetSelection(0) + sizer.Add(self.fsaach) + + self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") + sizer.Add(self.bloomscalecb) + self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) + self.bloomscalech.SetSelection(0) + sizer.Add(self.bloomscalech) + + self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") + sizer.Add(self.bloomweightcb) + self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) + sizer.Add(self.bloomweightsc) + + self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") + sizer.Add(self.lodbiascb) + self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) + sizer.Add(self.lodbiassc) + + self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") + sizer.Add(self.renderscalecb) + self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) + sizer.Add(self.renderscalesc) + + return sizer + + def MakeBindString(self): + # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. + bindstrings = [] + if self.visscalecb.IsChecked(): + bindstrings.append("visscale " + str(self.visscalesc.GetValue())) + if self.dofweightcb.IsChecked(): + bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) + if self.fsaacb.IsChecked(): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bindstrings.append("fsaa " + fsaavalue) + if self.bloomscalecb.IsChecked(): + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + bindstrings.append("bloomscale " + bloomscalevalue) + if self.bloomweightcb.IsChecked(): + bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) + if self.lodbiascb.IsChecked(): + bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) + if self.renderscalecb.IsChecked(): + bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) + + return '$$'.join(bindstrings) + + def Serialize(self): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + return { + 'visscalecb' : self.visscalecb.IsChecked(), + 'visscalesc' : self.visscalesc.GetValue(), + 'dofweightcb' : self.dofweightcb.IsChecked(), + 'dofweightsc' : self.dofweightsc.GetValue(), + 'fsaacb' : self.fsaacb.IsChecked(), + 'fsaach' : fsaavalue, + 'bloomscalecb' : self.bloomscalecb.IsChecked(), + 'bloomscalech' : bloomscalevalue, + 'bloomweightcb' : self.bloomweightcb.IsChecked(), + 'bloomweightsc' : self.bloomweightsc.GetValue(), + 'lodbiascb' : self.lodbiascb.IsChecked(), + 'lodbiassc' : self.lodbiassc.GetValue(), + 'renderscalecb' : self.renderscalecb.IsChecked(), + 'renderscalesc' : self.renderscalesc.GetValue(), + } + + def Deserialize(self, init): + self.visscalecb.SetValue(init.get('visscalecb', False)) + self.visscalesc.SetValue(init.get('visscalesc', 1.0)) + self.dofweightcb.SetValue(init.get('dofweightcb', False)) + self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) + self.fsaacb.SetValue(init.get('fsaacb', False)) + self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) + self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) + self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) + self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) + self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) + self.lodbiascb.SetValue(init.get('lodbiascb', False)) + self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) + self.renderscalecb.SetValue(init.get('renderscalecb', False)) + self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) + +####### Custom Bind +class CustomBindCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.customBindName = wx.TextCtrl(dialog, -1) + self.customBindName.SetHint('Custom Bind Text') + sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + return self.customBindName.GetValue() + + def Serialize(self): + return { 'customBindName': self.customBindName.GetValue() } + + def Deserialize(self,init): + if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) + +####### Emote +class EmoteCmd(PowerBindCmd): + def BuildUI(self, dialog): + emoteSizer = wx.BoxSizer(wx.HORIZONTAL) + self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") + emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + self.emoteName = wx.Button(dialog, -1, "...") + self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) + emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) + + return emoteSizer + + def MakeBindString(self): + displayedEmoteName = self.emoteName.GetLabel() + actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] + + return actualEmotePayload + + def Serialize(self): + return {'emoteName': self.emoteName.GetLabel()} + + def Deserialize(self, init): + if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) + +####### Load Binds Directory +class LoadBindsDir(PowerBindCmd): + def BuildUI(self, dialog): + mainSizer = wx.BoxSizer(wx.VERTICAL) + + lbSizer = wx.BoxSizer(wx.HORIZONTAL) + lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") + lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + profiles = Profile.GetAllProfileBindsDirs() + + self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) + lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") + self.lbResetCB.SetValue(True) + + mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + return mainSizer + + def MakeBindString(self): + + # If the specified binds directory disappeared between runs, we'd crash, so handle that. + if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' + + config = wx.ConfigBase.Get() + if config.Exists('GameBindPath'): + bindpath = config.Read('GameBindPath') + else: + bindpath = config.Read('BindPath') + + reset = "" + if self.lbResetCB.GetValue(): + reset = "keybind_reset$$" + + resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' + return reset + 'bindloadfile ' + str(resetfilepath) + + def Serialize(self): + return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), + 'ResetKeybinds' : self.lbResetCB.GetValue(), + } + + def Deserialize(self, init): + if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) + self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) + +####### Power Abort +class PowerAbortCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecabort' + +####### Power Unqueue +class PowerUnqueueCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecunqueue' + +####### SG Mode +class SGModeCmd(PowerBindCmd): + def BuildUI(self, dialog): + sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) + sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") + self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") + + sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) + + return sgmodeSizer + + def MakeBindString(self): + if self.sgmodeOnRB.GetValue(): + return 'sgmodeset 1' + elif self.sgmodeOffRB.GetValue(): + return 'sgmodeset 0' + else: + return 'sgmode' + + def Serialize(self): + if self.sgmodeOnRB.GetValue(): + val = "On" + elif self.sgmodeOffRB.GetValue(): + val = "Off" + else: + val = "Toggle" + + return {"value" : val} + + def Deserialize(self, init): + val = init.get('value', '') + if val == "On": + self.sgmodeOnRB.SetValue(True) + elif val == "Off": + self.sgmodeOffRB.SetValue(True) + else: + self.sgmodeToggleRB.SetValue(True) + +####### Target Custom +class TargetCustomCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetCustomSizer = wx.GridBagSizer(5,5) + targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), + flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) + self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetCustomModeChoice.SetSelection(0) + targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) + self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) + self.targetCustomOptionalName.SetHint("Optional name to match") + targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) + self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") + targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) + self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") + targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) + self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") + targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) + self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") + targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) + self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") + targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) + self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") + targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) + self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") + targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) + self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") + targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) + + targetCustomSizer.AddGrowableCol(2) + + return targetCustomSizer + + def MakeBindString(self): + choice = self.targetCustomModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + targetCommand = "targetcustom" + mode.lower() + + enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" + friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" + defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" + alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" + mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" + notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" + base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" + notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" + + name = self.targetCustomOptionalName.GetValue() + + return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" + + def Serialize(self): + return { + 'mode' : self.targetCustomModeChoice.GetSelection(), + 'enemy' : self.targetCustomCBEnemies. IsChecked(), + 'friend' : self.targetCustomCBFriends. IsChecked(), + 'defeated' : self.targetCustomCBDefeated. IsChecked(), + 'alive' : self.targetCustomCBAlive. IsChecked(), + 'mypet' : self.targetCustomCBMyPets. IsChecked(), + 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), + 'base' : self.targetCustomCBBaseItems. IsChecked(), + 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), + 'name' : self.targetCustomOptionalName.GetValue(), + } + + def Deserialize(self, init): + if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) + if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) + if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) + if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) + if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) + if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) + if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) + if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) + if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) + if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) + + +####### Target Enemy +class TargetEnemyCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) + targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetEnemyModeChoice.SetSelection(0) + targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetEnemySizer + + def MakeBindString(self): + choice = self.targetEnemyModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetenemy" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetEnemyModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) + +####### Target Friend +class TargetFriendCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) + targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetFriendModeChoice.SetSelection(0) + targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetFriendSizer + + def MakeBindString(self): + choice = self.targetFriendModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetfriend" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetFriendModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) + +####### Team/Pet Select +class TeamPetSelectCmd(PowerBindCmd): + def BuildUI(self, dialog): + teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], + style=wx.ALIGN_CENTER_VERTICAL) + self.teamPetSelectNumber.SetSelection(0) + teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) + + return teamPetSelectSizer + + def MakeBindString(self): + teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' + targetNumber = self.teamPetSelectNumber.GetSelection()+1 + + return f"{teamOrPet}select {targetNumber}" + + def Serialize(self): + return { + 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', + 'targetNum': self.teamPetSelectNumber.GetSelection(), + } + + def Deserialize(self, init): + ToP = init.get('teamOrPet', '') + if ToP == 'pet': + self.teamPetSelectPetRB.SetValue(True) + else: + self.teamPetSelectTeamRB.SetValue(True) + if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) + +####### Unselect +class UnselectCmd(PowerBindCmd): + def MakeBindString(self): + return 'unselect' + +####### Use Insp By Name +class UseInspByNameCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) + for _, types in GameData.Inspirations.items(): + for _, info in types.items(): + for insp in info['tiers']: + name = re.sub(' ', '', str(insp)) + icon = GetIcon(f'Inspirations/{name}') + self.useInspByNameModeChoice.Append(insp, icon) + self.useInspByNameModeChoice.SetSelection(0) + useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) + + return useInspByNameSizer + + def MakeBindString(self): + choice = self.useInspByNameModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "inspexecname " + mode.lower() + + def GetAllInsps(self): + Insplist = [] + for _, info in GameData.Inspirations.items(): + for insp in info['tiers']: + Insplist.append(insp) + Insplist.append("---") + Insplist.pop(-1) # snip the terminal "---" + + return Insplist + + def Serialize(self): + return { 'insp' : self.useInspByNameModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) + +####### Use Insp From Row / Column +class UseInspRowColCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnRow.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) + self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnCol.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) + + return useInspRowColumnSizer + + def MakeBindString(self): + row = self.useInspRowColumnRow.GetSelection()+1 + col = self.useInspRowColumnCol.GetSelection()+1 + + return f"inspexectray {col} {row}" + + def Serialize(self): + return { + 'col' : self.useInspRowColumnCol.GetSelection(), + 'row' : self.useInspRowColumnRow.GetSelection(), + } + + def Deserialize(self, init): + if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) + if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) + +####### Use Power +class UsePowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + outerSizer = wx.BoxSizer(wx.HORIZONTAL) + + usePowerSizer = wx.GridBagSizer(5,5) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBToggle, (0,1)) + self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOn, (0,2)) + self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOff, (0,3)) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerName = PowerPicker(dialog) + usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) + usePowerSizer.AddGrowableCol(3) + + outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) + + return outerSizer + + def MakeBindString(self): + if self.usePowerRBToggle.GetValue(): + method = "powexecname" + elif self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') + return '' + + return f"{method} {self.usePowerName.GetLabel()}" + + def Serialize(self): + if self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + method = "powexecname" + return { + 'method': method, + 'pname' : self.usePowerName.GetLabel(), + 'picon' : self.usePowerName.IconFilename + } + + def Deserialize(self, init): + method = init.get('method', '') + if method == 'powexectoggleon': + self.usePowerRBOn.SetValue(True) + elif method == 'powexectoggleoff': + self.usePowerRBOff.SetValue(True) + else: + self.usePowerRBToggle.SetValue(True) + if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) + +####### Use Power From Tray +class UsePowerFromTrayCmd(PowerBindCmd): + def BuildUI(self, dialog): + usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTrayTray = wx.Choice(dialog, -1, + choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', + 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) + self.usePowerFromTrayTray.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) + self.usePowerFromTraySlot.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return usePowerFromTraySizer + + def MakeBindString(self): + choice = self.usePowerFromTrayTray + tray = choice.GetSelection() + + choice = self.usePowerFromTraySlot + slot = choice.GetSelection()+1 + + mode = "slot" + mode2 = '' + if tray > 3: + mode = "tray" + mode2 = f" {tray - 3}" + elif tray == 3: + mode = "alt2slot" + elif tray == 2: + mode = "altslot" + + return f"powexec{mode} {slot}{mode2}" + + def Serialize(self): + return { + 'tray' : self.usePowerFromTrayTray.GetSelection(), + 'slot' : self.usePowerFromTraySlot.GetSelection(), + } + + def Deserialize(self, init): + if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) + if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) + +####### Window Color +class WindowColorCmd(PowerBindCmd): + def BuildUI(self, dialog): + windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) + borderSizer = wx.BoxSizer(wx.VERTICAL) + self.ColorBorder.SetSizer(borderSizer) + self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) + borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) + + windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) + + RGBASizer = wx.FlexGridSizer(3, 4, 5) + + RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) + self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) + self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + windowColorSizer.Add(RGBASizer) + + self.UpdateFromSlider() + + return windowColorSizer + + def MakeBindString(self): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + return f"windowcolor {Rval} {Gval} {Bval} {Aval}" + + def Serialize(self): + return { + 'Rval' : self.RSlider.GetValue(), + 'Gval' : self.GSlider.GetValue(), + 'Bval' : self.BSlider.GetValue(), + 'Aval' : self.ASlider.GetValue(), + } + + def Deserialize(self, init): + self.RSlider.SetValue(init['Rval']) + self.GSlider.SetValue(init['Gval']) + self.BSlider.SetValue(init['Bval']) + self.ASlider.SetValue(init['Aval']) + self.UpdateFromSlider() + + def UpdateFromSlider(self, _ = None): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RReadout.SetValue(Rval) + self.GReadout.SetValue(Gval) + self.BReadout.SetValue(Bval) + self.AReadout.SetValue(Aval) + self.ColorBorder.Refresh() + + def UpdateFromText(self, _ = None): + Rval = self.RReadout.GetValue() + Gval = self.GReadout.GetValue() + Bval = self.BReadout.GetValue() + Aval = self.AReadout.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RSlider.SetValue(Rval) + self.GSlider.SetValue(Gval) + self.BSlider.SetValue(Bval) + self.ASlider.SetValue(Aval) + self.ColorBorder.Refresh() + +####### Window Save / Load +class WindowSaveLoadCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) + self.CommandChoice.SetSelection(0) + sizer.Add(self.CommandChoice, 0, wx.ALL, 5) + + self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), + value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) + sizer.Add(self.FilePath, 0, wx.ALL, 5) + + return sizer + + def MakeBindString(self): + command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] + return f'{command} "{self.FilePath.GetValue()}"' + + def Serialize(self): + return { + 'command' : self.CommandChoice.GetSelection(), + 'filename' : self.FilePath.GetValue(), + } + + def Deserialize(self, init): + self.CommandChoice.SetSelection(init.get('command', 0)) + self.FilePath.SetValue(init.get('filename', '')) + +####### Window Toggle +class WindowToggleCmd(PowerBindCmd): + def BuildUI(self, dialog): + self.WindowNames = { + 'Actions' : 'actions', + 'Auction House' : 'ah', + 'Badge' : 'badge', + 'Channel Search' : 'chansearch', + 'Chat' : 'chat', + 'Custom Chat 1' : 'chat1', + 'Custom Chat 2' : 'chat2', + 'Custom Chat 3' : 'chat3', + 'Custom Chat 4' : 'chat4', + 'Clues' : 'clue', + 'Combat Numbers' : 'combatnumbers', + 'Contacts' : 'contact', + 'Contact Finder' : 'contactfinder', + 'Costumes' : 'costume', + 'Email' : 'email', + 'Enhancements' : 'enhancements', + 'Friends' : 'friend', + 'Group' : 'group', + 'Help' : 'helpwindow', + 'Incarnate' : 'incarnate', + 'Inspirations' : 'insp', + 'League' : 'league', + 'LFG' : 'lfg', + 'Map' : 'map', + 'Mission' : 'mission', + 'Nav / Compass' : 'nav', + 'Options' : 'options', + 'Pets' : 'pet', + 'Petition' : 'petition', + 'Power Tray' : 'powers', + 'Power List' : 'powerlist', + 'Quit' : 'quit', + 'Recipes' : 'recipe', + 'Salvage' : 'salvage', + 'Search' : 'search', + 'Supergroup' : 'sg', + 'Target' : 'target', + 'Team' : 'team', + 'Tray' : 'tray', + 'Tray1' : 'tray1', + 'Tray2' : 'tray2', + 'Tray3' : 'tray3', + 'Tray4' : 'tray4', + 'Tray5' : 'tray5', + 'Tray6' : 'tray6', + 'Tray7' : 'tray7', + 'Tray8' : 'tray8', + 'Vault' : 'vault', + } + + self.ShortToggleCommands = { + 'Auction House' : 'ah', + 'Chat' : 'chat', + 'Help' : 'helpwindow', + 'Map' : 'map', + 'Nav / Compass' : 'nav', + 'Power Tray' : 'powers', + 'Target' : 'target', + 'Tray' : 'tray', + } + + windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) + windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) + self.windowToggleTray.SetSelection(0) + windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.windowShowRB = wx.RadioButton(dialog, -1, "Show") + self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") + + windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) + + return windowToggleSizer + + def MakeBindString(self): + choice = self.windowToggleTray + index = choice.GetSelection() + windowdesc = choice.GetString(index) + windowname = self.WindowNames[windowdesc] + + if self.windowShowRB.GetValue(): + return 'show ' + windowname + elif self.windowHideRB.GetValue(): + return 'windowhide ' + windowname + else: + if shortcmd := self.ShortToggleCommands.get(windowdesc, None): + return shortcmd + else: + return 'toggle ' + windowname + + + def Serialize(self): + choice = self.windowToggleTray + if self.windowShowRB.GetValue(): + action = "Show" + elif self.windowHideRB.GetValue(): + action = "Hide" + else: + action = "Toggle" + return { + 'window': choice.GetString(choice.GetSelection()), + 'action': action, + } + + def Deserialize(self, init): + choice = self.windowToggleTray + if window := init.get('window', ''): + if isinstance(window, int): + choice.SetSelection(window) + else: + choice.SetSelection(choice.FindString(window)) + + if choice.GetSelection() == wx.NOT_FOUND: + choice.SetSelection(0) + + action = init.get('action', '') + if action == "Show": + self.windowShowRB.SetValue(True) + elif action == "Hide": + self.windowHideRB.SetValue(True) + else: + self.windowToggleRB.SetValue(True) + + +# Must always add to this list when adding a new command class above +menuStructure = { + 'Graphics / UI' : [ + 'Attribute Monitor', + 'Buff Display Settings', + 'Graphics Settings', + 'Window Color', + 'Window Save / Load', + 'Window Toggle', + ], + 'Inspirations' : [ + 'Use Inspiration By Name', + 'Use Inspiration From Row/Column', + ], + 'Powers' : [ + 'Auto Power', + 'Power Abort', + 'Power Unqueue', + 'Use Power', + 'Use Power From Tray', + ], + 'Social' : [ + 'Away From Keyboard', + 'Chat Command', + 'Chat Command (Global)', + 'Costume Change', + 'Emote', + 'Supergroup Mode', + ], + 'Targeting' : [ + 'Target Custom', + 'Target Enemy', + 'Target Frield', + 'Team/Pet Select', + 'Unselect', + ], + 'Misc' : [ + 'Load Binds Directory', + 'Movement Commands', + ], + # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, + # but I'm leaving it here to remind myself that we do that. + } + +# Must always add to this list when adding a new command class above +commandClasses = { + 'Auto Power' : AutoPowerCmd, + 'Away From Keyboard' : AFKCmd, + 'Attribute Monitor' : AttributeMonitorCmd, + 'Buff Display Settings' : BuffDisplayCmd, + 'Chat Command' : ChatCmd, + 'Chat Command (Global)' : ChatGlobalCmd, + 'Costume Change' : CostumeChangeCmd, + 'Custom Bind' : CustomBindCmd, + 'Emote' : EmoteCmd, + 'Graphics Settings' : GraphicsCmd, + 'Load Binds Directory' : LoadBindsDir, + 'Movement Commands' : MovementCmd, + 'Power Abort' : PowerAbortCmd, + 'Power Unqueue' : PowerUnqueueCmd, + 'Supergroup Mode' : SGModeCmd, + 'Target Custom' : TargetCustomCmd, + 'Target Enemy' : TargetEnemyCmd, + 'Target Friend' : TargetFriendCmd, + 'Team/Pet Select' : TeamPetSelectCmd, + 'Unselect' : UnselectCmd, + 'Use Inspiration By Name' : UseInspByNameCmd, + 'Use Inspiration From Row/Column' : UseInspRowColCmd, + 'Use Power' : UsePowerCmd, + 'Use Power From Tray' : UsePowerFromTrayCmd, + 'Window Color' : WindowColorCmd, + 'Window Save / Load' : WindowSaveLoadCmd, + 'Window Toggle' : WindowToggleCmd, +} +# use these when we rename a commandClass so that old Profiles will still load correctly. +# If we've also updated the class, we need to try to make sure the new class will still +# Deserialize the legacy data, or at least not crash. +deprecatedCommandClasses = { + 'SG Mode Toggle' : SGModeCmd, + 'Use Insp By Name' : UseInspByNameCmd, + 'Use Insp From Row/Column' : UseInspRowColCmd, +} +commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/UsePowerFromTrayCmd.py b/UI/PowerBinderCommand/UsePowerFromTrayCmd.py new file mode 100644 index 0000000..4c02ab7 --- /dev/null +++ b/UI/PowerBinderCommand/UsePowerFromTrayCmd.py @@ -0,0 +1,1800 @@ +import wx +import re +import UI +import UI.EmotePicker +from UI.ControlGroup import ControlGroup +from UI.PowerPicker import PowerPicker +from Help import HelpButton +import wx.adv +from wx.adv import BitmapComboBox, EditableListBox +from pathlib import PureWindowsPath +import GameData +import Profile +from Icon import GetIcon + +class PowerBinderDialog(wx.Dialog): + def __init__(self, parent, button, init = {}): + wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) + + self.Page = parent.Page + self.EditDialog = PowerBinderEditDialog(self) + self.Button = button + self.AddStepMenu = self.makeAddStepMenu() + + sizer = wx.BoxSizer(wx.VERTICAL); + self.mainSizer = sizer + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) + # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) + # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) + #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) + AddStepButton = wx.Button(self, -1, 'Add Step') + AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) + AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) + choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) + choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) + sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) + + rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) + + self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) + self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) + self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) + rearrangeCtrl.Add(self.RearrangeList, 1) + + rearrangeButtons = wx.BoxSizer(wx.VERTICAL) + self.DelButton = wx.Button(self, -1, "Delete") + self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) + self.EditButton = wx.Button(self, -1, "Edit") + self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) + self.EditButton.Disable() + upButton = wx.Button(self, -1, "\u25B2") + upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) + downButton = wx.Button(self, -1, "\u25BC") + downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) + rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) + rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) + + sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.BindStringDisplay = wx.TextCtrl(self, -1) + self.BindStringDisplay.Disable() + choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, + wx.ALIGN_CENTER_VERTICAL) + choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) + + sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) + + sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) + + # need to dig around and get the OK button since we show this dialog modelessly now. + okButton = self.FindWindow(self.GetAffirmativeId()) + okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) + + # Wrap everything in a vbox to add some padding + vbox = wx.BoxSizer(wx.VERTICAL); + vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); + + self.SetSizerAndFit(vbox); + self.Layout() + self.Fit() + self.SetFocus() + + # if we are loading from profile, ie, have "init", build the list from it + if init: self.LoadFromData(init) + + def LoadFromData(self, init): + for item in init: + for type, data in item.items(): + commandClass = commandClasses.get(type, None) + if not commandClass: + commandClass = deprecatedCommandClasses.get(type, None) + if not commandClass: + wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") + continue + newCommand = commandClass(self.EditDialog, data) + index = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.SetClientData(index, newCommand) + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) + self.EditDialog.mainSizer.Hide(newCommand.UI) + self.UpdateBindStringDisplay() + + def SaveToData(self): + data = [] + index = 0 + for _ in self.RearrangeList.GetItems(): + # check whether we have an object already attached to this choice + cmdObject = self.RearrangeList.GetClientData(index) + commandClassName = commandRevClasses[type(cmdObject)] + data.append({commandClassName: cmdObject.Serialize()}) + index = index + 1 + return data + + def OnAddStepButton(self, evt): + button = evt.EventObject + if not self.AddStepMenu: + self.AddStepMenu = self.makeAddStepMenu() + button.PopupMenu(self.AddStepMenu) + + + def OnOKButton(self, _): + if self.Button.tgtTxtCtrl: + bindString = self.MakeBindString() + if bindString != self.Button.tgtTxtCtrl.GetValue(): + self.Button.tgtTxtCtrl.SetValue(bindString) + wx.App.Get().Main.Profile.SetModified() + self.Close() + + def OnRearrangeDelete(self, _): + current = self.RearrangeList.GetSelection() + if current == wx.NOT_FOUND: return + + self.RearrangeList.Delete(current) + self.UpdateBindStringDisplay() + + def OnRearrangeUp(self, _): + self.RearrangeList.MoveCurrentUp() + self.UpdateBindStringDisplay() + + def OnRearrangeDown(self, _): + self.RearrangeList.MoveCurrentDown() + self.UpdateBindStringDisplay() + + def OnRearrangeEdit(self, _): + index = self.RearrangeList.GetSelection() + + # check whether we have an object already attached to this choice + cmdObject = None + try: + cmdObject = self.RearrangeList.GetClientData(index) + except Exception: + pass + + if cmdObject: + self.ShowEditDialogFor(cmdObject) + self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) + else: + print("cmdObject was None") + self.UpdateBindStringDisplay() + + # OnAddStepMenu creates a new step and adds it to the rearrangelist + def OnAddStepMenu(self, evt): + menuitem = self.AddStepMenu.FindItemById(evt.GetId()) + chosenName = menuitem.GetItemLabel() + + # make a new command object, attached to the parent dialog + newCommandClass = commandClasses[chosenName] + newCommand = newCommandClass(self.EditDialog) + + # show the edit dialog if this command needs it + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) + if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): + self.EditDialog.mainSizer.Remove(newCommand.UI) + return + + newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.Select(newBindIndex) + self.RearrangeList.SetClientData(newBindIndex, newCommand) + + self.OnListSelect() + self.UpdateBindStringDisplay() + + def OnListSelect(self, _ = None): + selected = self.RearrangeList.GetSelection() + + if selected != wx.NOT_FOUND: + selCommand = self.RearrangeList.GetClientData(selected) + if selCommand.UI: + self.EditButton.Enable() + else: + self.EditButton.Disable() + + def UpdateBindStringDisplay(self): + self.BindStringDisplay.SetValue(self.MakeBindString()) + self.BindStringDisplay.SetToolTip(self.MakeBindString()) + + def MakeBindString(self): + cmdBindStrings = [] + for index in range(self.RearrangeList.GetCount()): + c = self.RearrangeList.GetClientData(index) + if c: cmdBindStrings.append(c.MakeBindString()) + + bindstring = ('$$'.join(cmdBindStrings)) + return bindstring + + def ShowEditDialogFor(self, command): + if not command.UI: return + + self.EditDialog.mainSizer.Show(command.UI) + + self.EditDialog.Layout() + self.EditDialog.Fit() + + self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') + returnval = self.EditDialog.ShowModal() + + self.EditDialog.mainSizer.Hide(command.UI) + + return returnval + + def makeAddStepMenu(self): + + stepMenu = wx.Menu() + + for subname in menuStructure: + submenu = wx.Menu() + stepMenu.AppendSubMenu(submenu, subname) + for classname in menuStructure[subname]: + submenu.Append(wx.ID_ANY, classname) + + stepMenu.Append(wx.ID_ANY, 'Custom Bind') + + return stepMenu + +class PowerBinderButton(wx.BitmapButton): + + def __init__(self, parent, tgtTxtCtrl, init = {}): + wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) + self.Init = init + self.Dialog = None + self.DialogParent = parent + + self.tgtTxtCtrl = tgtTxtCtrl + self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) + self.SetToolTip("Launch PowerBinder") + + def PowerBinderEventHandler(self, _): + self.PowerBinderDialog().Show() + + def LoadFromData(self, data): + self.PowerBinderDialog().LoadFromData(data) + + def SaveToData(self): + return self.PowerBinderDialog().SaveToData() + + def PowerBinderDialog(self): + if not self.Dialog: + self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) + return self.Dialog + + +class PowerBinderEditDialog(wx.Dialog): + def __init__(self, parent): + wx.Dialog.__init__(self, parent, -1, "Edit Step", + style = wx.DEFAULT_DIALOG_STYLE) + + outerSizer = wx.BoxSizer(wx.VERTICAL) + + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + self.mainSizer.SetMinSize([500, 150]) + + self.Page = parent.Page + + self.mainSizer.Add( + self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), + 0, wx.EXPAND|wx.ALL, 10) + + outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) + + self.SetSizerAndFit(outerSizer) + self.Layout() + self.Fit() + +########### Power Binder Command Objects +class PowerBindCmd(): + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + commandClassName = commandRevClasses[type(self)] + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{commandClassName} - {short_bindstr}" + + +####### Away From Keyboard +class AFKCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) + +####### Attribute Monitor +class AttributeMonitorCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.Groups = {} + self.AttributeTable = { + 'Base' : { + 'Current Hit Points' : 'NT H', + 'Max Hit Points' : 'X H', + 'Current Endurance' : 'T E', + 'Max Endurance' : 'X EN', + 'Regeneration Rate' : 'N RAT', + 'Recovery Rate' : 'Y RA', + 'Endurance Consumption' : 'SU', + 'ToHit Bonus' : 'T B', + 'Accuracy Bonus' : 'CC', + 'Last Hit Chance' : 'T C', + 'Damage Bonus' : 'DA', + 'Healing Bonus' : 'NG B', + 'Recharge Time Bonus' : 'ME B', + 'Endurance Discount' : 'CE DIS', + 'Stealth Radius (PvP)' : 'PVP', + 'Stealth Radius (PvE)' : 'PVE', + 'Perception Radius' : 'RC', + 'Range Bonus' : 'GE B', + 'Threat Level' : 'AT L', + 'Experience to Next Level' : 'XT', + 'Experience Debt' : 'XP', + 'Influence / Infamy' : 'INF', + 'Inherent' : 'NH', + }, + 'Movement Speed' : { + 'Flying Speed' : 'FL', + 'Jumping Speed' : 'PI', + 'Max Jump Height' : 'X J', + 'Run Speed' : 'RU', + }, + 'Damage Resistance' : { + 'Smashing Resistance' : 'G R', + 'Lethal Resistance' : 'L R', + 'Fire Resistance' : 'RE R', + 'Cold Resistance' : 'COLD R', + 'Energy Resistance' : 'DamageType[4]', + 'Negative Energy Resistance' : 'GY R', + 'Psyonic Resistance' : 'NIC R', + 'Toxic Resistance' : 'XIC R', + }, + 'Defense' : { + 'Base Defense' : 'BAS', + 'Ranged Defense' : 'ED', + 'Melee Defense' : 'MEL', + 'AoE Defense' : '2', + 'Smashing Defense' : '3', + 'Lethal Defense' : '4', + 'Fire Defense' : '5', + 'Cold Defense' : '6', + 'Energy Defense' : '7', + 'Negative Energy Defense' : '8', + 'Psionic Defense' : '9', + 'Toxic Defense' : '1', + }, + 'Debuff Resistance' : { + 'Regeneration Resistance' : 'ON R', + 'Recovery Resistance' : 'RY R', + 'To Hit Resistance' : 'IT R', + 'Defense Resistance' : 'NSE RES', + }, + 'Status Effect Protection' : { + 'Hold Protection' : 'D P', + 'Immobilize Protection' : 'LIZE P', + 'Stun Protection' : 'N P', + 'Sleep Protection' : 'P P', + 'Knockback Protection' : 'K P', + 'Confuse Protection' : 'SE P', + 'Terrorize Protection' : 'ZE P', + 'Repel Protection' : 'EL P', + 'Teleport Protection' : 'T P', + }, + 'Status Effect Resistance' : { + 'Hold Resistance' : 'D R', + 'Immobilize Resistance' : 'LIZE R', + 'Stun Resistance' : 'N R', + 'Sleep Resistance' : 'P R', + 'Knockback Resistance' : 'K R', + 'Confuse Resistance' : 'SE R', + 'Terrorize Resistance' : 'ZE R', + 'Placate Resistance' : 'TE R', + 'Taunt Resistance' : 'NT R', + }, + 'Miscellaneous' : { + 'Level Shift' : 'L S', + }, + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.AttributeMenu = wx.Menu() + for group, controls in self.AttributeTable.items(): + submenu = wx.Menu() + self.AttributeMenu.AppendSubMenu(submenu, group) + for cb in controls: + submenu.Append(wx.ID_ANY, cb) + + self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) + + self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) + groupSizer.Add(self.editbox) + + newButton = self.editbox.GetNewButton() + newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) + + return groupSizer + + def MakeBindString(self): + map = {} + bindstrings = [] + for _, controls in self.AttributeTable.items(): + for cb, data in controls.items(): + map[cb] = data + + for string in self.editbox.GetStrings(): + if string: + bindstrings.append(f'monitorattribute {map[string]}') + + return '$$'.join(bindstrings) + + def Serialize(self): + return { + 'attributes' : self.editbox.GetStrings() + } + + def Deserialize(self, init): + self.editbox.SetStrings(init.get('attributes', [])) + + def OnNewButton(self, evt): + evt.GetEventObject().PopupMenu(self.AttributeMenu) + + def OnMenuItem(self, evt): + menuitem = evt.EventObject.FindItemById(evt.GetId()) + existingstrings = self.editbox.GetStrings() + existingstrings.append(menuitem.GetItemLabel()) + self.editbox.SetStrings(existingstrings) + +####### Auto Power +class AutoPowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) + autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.autoPowerName = PowerPicker(dialog) + autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) + + return autoPowerSizer + + def MakeBindString(self): + return f"powexecauto {self.autoPowerName.GetLabel()}" + + def Serialize(self): + return { + 'pname' : self.autoPowerName.GetLabel(), + 'picon' : self.autoPowerName.IconFilename + } + + def Deserialize(self, init): + if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) + +####### Buff Display Command +class BuffDisplayCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.buffDisplayMap = { + 'Status Window' : { + 'Hide Auto' : 1, + 'Hide Toggles' : 2, + 'No Blinking' : 4, + 'No Stacking' : 8, + 'Numeric Stacking' : 16, + 'Hide Buff Numbers' : 32, + 'Stop Sending Buffs' : 64, + }, + 'Group Window' : { + 'Hide Auto' : 256, + 'Hide Toggles' : 512, + 'No Blinking' : 1024, + 'No Stacking' : 2048, + 'Numeric Stacking' : 4096, + 'Hide Buff Numbers' : 8192, + 'Stop Sending Buffs' : 16384, + }, + 'Pet Window' : { + 'Hide Auto' : 65536, + 'Hide Toggles' : 131072, + 'No Blinking' : 262144, + 'No Stacking' : 524288, + 'Numeric Stacking' : 1048576, + 'Hide Buff Numbers' : 2097152, + 'Stop Sending Buffs' : 4194304, + }, + } + self.Groups = {} + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + for group, controls in self.buffDisplayMap.items(): + self.Groups[group] = ControlGroup(dialog, self.Page, label = group) + groupid = self.Groups[group].GetStaticBox().GetId() + for cb, data in controls.items(): + self.Groups[group].AddControl( + ctlType = 'checkbox', + ctlName = f"{groupid}_{group}_{cb}", + label = cb, + data = data, + ) + + groupSizer.Add(self.Groups[group]) + + return groupSizer + + def CalculateValue(self): + page = wx.App.Get().Main.Profile.CustomBinds + + total = 0 + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] + if checkbox.IsChecked(): + total = total + checkbox.Data + return total + + def MakeBindString(self): + return f"optionset buffsettings {self.CalculateValue()}" + + def Serialize(self): + return { 'value' : self.CalculateValue() } + + def Deserialize(self, init): + value = init.get('value', 0) + + value = value or 0 # in case we had for some reason 'None' stashed in the init values + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] + checkbox.SetValue( checkbox.Data & value ) + +####### Chat Command +class ChatCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.chatChannelMap = { # before __init__ + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + chatCommandSizer = wx.GridBagSizer(5, 5) + self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") + chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) + # row 1 + self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) + self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) + self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) + # row 2 + self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) + self.chatCommandDuration.SetRange(1, 20) + self.chatCommandDuration.SetValue(7) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandDuration, (2,1)) + self.chatCommandChatSize = wx.Choice(dialog, -1, + choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) + self.chatCommandChatSize.SetSelection(5) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) + self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) + self.chatCommandChannel.SetSelection(0) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChannel, (2,5)) + # row 3 + self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") + chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) + self.chatCommandMessage = wx.TextCtrl(dialog, -1) + self.chatCommandMessage.SetHint('Chat Command Text') + chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) + + return chatCommandSizer + + def MakeBindString(self): + duration = self.chatCommandDuration.GetValue() + + choice = self.chatCommandChatSize + index = choice.GetSelection() + size = choice.GetString(index) + + duration = f"" if duration != 7 else "" + size = f"" if size != "1" else "" + + bdcolor = fgcolor = bgcolor = '' + if self.chatCommandUseColorsCB.IsChecked(): + bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + + bdcolor = f"" + fgcolor = f"" + bgcolor = f"" + + beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' + text = self.chatCommandMessage.GetValue() + + choice = self.chatCommandChannel + index = choice.GetSelection() + channel = choice.GetString(index) + + return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" + + def Serialize(self): + return { + 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), + 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), + 'channel' : self.chatCommandChannel .GetSelection(), + 'size' : self.chatCommandChatSize.GetSelection(), + 'duration' : self.chatCommandDuration.GetValue(), + 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'text' : self.chatCommandMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) + if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) + if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) + if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) + if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) + if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) + if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) + if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) + if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) + + +####### Chat Command Global +class ChatGlobalCmd(PowerBindCmd): + def BuildUI(self, dialog): + chatCommandGlobalSizer = wx.GridBagSizer(5,5) + + self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") + chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) + + self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalChannel.SetHint("Channel") + chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) + + self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') + chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) + + chatCommandGlobalSizer.AddGrowableCol(1) + + return chatCommandGlobalSizer + + def MakeBindString(self): + useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() + channel = self.chatCommandGlobalChannel.GetValue() + message = self.chatCommandGlobalMessage.GetValue() + + preface = "beginchat /" if useBeginchat else "" + + return f'{preface}send "{channel}" {message}' + + def Serialize(self): + return { + 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), + 'channel' : self.chatCommandGlobalChannel.GetValue(), + 'message' : self.chatCommandGlobalMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) + if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) + if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) + +#######Costume Change +class CostumeChangeCmd(PowerBindCmd): + def BuildUI(self, dialog): + costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeCostume = wx.Choice(dialog, -1, + choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) + self.costumeChangeCostume.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeEmote = wx.Choice(dialog, -1, + choices = GameData.Emotes['costumechange']) + self.costumeChangeEmote.Insert("- None -", 0) + self.costumeChangeEmote.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return costumeChangeSizer + + def MakeBindString(self): + costumeNumber = self.costumeChangeCostume.GetSelection() + costumeEmote = self.costumeChangeEmote.GetSelection() + + if costumeEmote: # None, or 0 == "- None -" + ccCmd = 'cce' + emoteName = self.costumeChangeEmote.GetString(costumeEmote) + emoteName = " CC" + emoteName.replace(" ","") + else: + ccCmd = 'cc' + emoteName = '' + + return f"{ccCmd} {costumeNumber}{emoteName}" + + def Serialize(self): + return{ + 'costumeNumber': self.costumeChangeCostume.GetSelection(), + 'costumeEmote' : self.costumeChangeEmote.GetSelection(), + } + + def Deserialize(self, init): + if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) + if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) + +####### Movement Command +class MovementCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + self.plusbutton.SetValue(True) + + self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.commandchoice = wx.Choice(dialog, choices = [ + "forward", "left", "right", "backward", "up", "down", + "turnleft", "turnright", "first", "autorun", "clicktomove", + ],) + sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) + self.commandchoice.SetSelection(0) + + self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + pre = post = '' + if self.plusbutton.GetValue() : pre = "+" + elif self.plusplusbutton.GetValue() : pre = "++" + elif self.minusbutton.GetValue() : pre = "-" + elif self.zerobutton.GetValue() : post = " 0" + elif self.onebutton.GetValue() : post = " 1" + + command = self.commandchoice.GetString(self.commandchoice.GetSelection()) + + return f"{pre}{command}{post}" + + def Serialize(self): + mod = '' + if self.plusbutton.GetValue() : mod = "plus" + elif self.plusplusbutton.GetValue() : mod = "plusplus" + elif self.minusbutton.GetValue() : mod = "minus" + elif self.zerobutton.GetValue() : mod = "zero" + elif self.onebutton.GetValue() : mod = "one" + + return { + 'mod' : mod, + 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), + } + + def Deserialize(self, init): + mod = init.get('mod', 'plus') + + if mod == 'plus' : self.plusbutton.SetValue(True) + elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) + elif mod == 'minus' : self.minusbutton.SetValue(True) + elif mod == 'zero' : self.zerobutton.SetValue(True) + elif mod == 'one' : self.onebutton.SetValue(True) + + self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) + +####### Graphics Command +class GraphicsCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.FlexGridSizer(2) + + self.visscalecb = wx.CheckBox(dialog, label = "visscale") + sizer.Add(self.visscalecb) + self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) + sizer.Add(self.visscalesc) + + self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") + sizer.Add(self.dofweightcb) + self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) + sizer.Add(self.dofweightsc) + + self.fsaacb = wx.CheckBox(dialog, label = "fsaa") + sizer.Add(self.fsaacb) + self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) + self.fsaach.SetSelection(0) + sizer.Add(self.fsaach) + + self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") + sizer.Add(self.bloomscalecb) + self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) + self.bloomscalech.SetSelection(0) + sizer.Add(self.bloomscalech) + + self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") + sizer.Add(self.bloomweightcb) + self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) + sizer.Add(self.bloomweightsc) + + self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") + sizer.Add(self.lodbiascb) + self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) + sizer.Add(self.lodbiassc) + + self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") + sizer.Add(self.renderscalecb) + self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) + sizer.Add(self.renderscalesc) + + return sizer + + def MakeBindString(self): + # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. + bindstrings = [] + if self.visscalecb.IsChecked(): + bindstrings.append("visscale " + str(self.visscalesc.GetValue())) + if self.dofweightcb.IsChecked(): + bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) + if self.fsaacb.IsChecked(): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bindstrings.append("fsaa " + fsaavalue) + if self.bloomscalecb.IsChecked(): + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + bindstrings.append("bloomscale " + bloomscalevalue) + if self.bloomweightcb.IsChecked(): + bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) + if self.lodbiascb.IsChecked(): + bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) + if self.renderscalecb.IsChecked(): + bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) + + return '$$'.join(bindstrings) + + def Serialize(self): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + return { + 'visscalecb' : self.visscalecb.IsChecked(), + 'visscalesc' : self.visscalesc.GetValue(), + 'dofweightcb' : self.dofweightcb.IsChecked(), + 'dofweightsc' : self.dofweightsc.GetValue(), + 'fsaacb' : self.fsaacb.IsChecked(), + 'fsaach' : fsaavalue, + 'bloomscalecb' : self.bloomscalecb.IsChecked(), + 'bloomscalech' : bloomscalevalue, + 'bloomweightcb' : self.bloomweightcb.IsChecked(), + 'bloomweightsc' : self.bloomweightsc.GetValue(), + 'lodbiascb' : self.lodbiascb.IsChecked(), + 'lodbiassc' : self.lodbiassc.GetValue(), + 'renderscalecb' : self.renderscalecb.IsChecked(), + 'renderscalesc' : self.renderscalesc.GetValue(), + } + + def Deserialize(self, init): + self.visscalecb.SetValue(init.get('visscalecb', False)) + self.visscalesc.SetValue(init.get('visscalesc', 1.0)) + self.dofweightcb.SetValue(init.get('dofweightcb', False)) + self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) + self.fsaacb.SetValue(init.get('fsaacb', False)) + self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) + self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) + self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) + self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) + self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) + self.lodbiascb.SetValue(init.get('lodbiascb', False)) + self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) + self.renderscalecb.SetValue(init.get('renderscalecb', False)) + self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) + +####### Custom Bind +class CustomBindCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.customBindName = wx.TextCtrl(dialog, -1) + self.customBindName.SetHint('Custom Bind Text') + sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + return self.customBindName.GetValue() + + def Serialize(self): + return { 'customBindName': self.customBindName.GetValue() } + + def Deserialize(self,init): + if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) + +####### Emote +class EmoteCmd(PowerBindCmd): + def BuildUI(self, dialog): + emoteSizer = wx.BoxSizer(wx.HORIZONTAL) + self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") + emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + self.emoteName = wx.Button(dialog, -1, "...") + self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) + emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) + + return emoteSizer + + def MakeBindString(self): + displayedEmoteName = self.emoteName.GetLabel() + actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] + + return actualEmotePayload + + def Serialize(self): + return {'emoteName': self.emoteName.GetLabel()} + + def Deserialize(self, init): + if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) + +####### Load Binds Directory +class LoadBindsDir(PowerBindCmd): + def BuildUI(self, dialog): + mainSizer = wx.BoxSizer(wx.VERTICAL) + + lbSizer = wx.BoxSizer(wx.HORIZONTAL) + lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") + lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + profiles = Profile.GetAllProfileBindsDirs() + + self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) + lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") + self.lbResetCB.SetValue(True) + + mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + return mainSizer + + def MakeBindString(self): + + # If the specified binds directory disappeared between runs, we'd crash, so handle that. + if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' + + config = wx.ConfigBase.Get() + if config.Exists('GameBindPath'): + bindpath = config.Read('GameBindPath') + else: + bindpath = config.Read('BindPath') + + reset = "" + if self.lbResetCB.GetValue(): + reset = "keybind_reset$$" + + resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' + return reset + 'bindloadfile ' + str(resetfilepath) + + def Serialize(self): + return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), + 'ResetKeybinds' : self.lbResetCB.GetValue(), + } + + def Deserialize(self, init): + if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) + self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) + +####### Power Abort +class PowerAbortCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecabort' + +####### Power Unqueue +class PowerUnqueueCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecunqueue' + +####### SG Mode +class SGModeCmd(PowerBindCmd): + def BuildUI(self, dialog): + sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) + sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") + self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") + + sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) + + return sgmodeSizer + + def MakeBindString(self): + if self.sgmodeOnRB.GetValue(): + return 'sgmodeset 1' + elif self.sgmodeOffRB.GetValue(): + return 'sgmodeset 0' + else: + return 'sgmode' + + def Serialize(self): + if self.sgmodeOnRB.GetValue(): + val = "On" + elif self.sgmodeOffRB.GetValue(): + val = "Off" + else: + val = "Toggle" + + return {"value" : val} + + def Deserialize(self, init): + val = init.get('value', '') + if val == "On": + self.sgmodeOnRB.SetValue(True) + elif val == "Off": + self.sgmodeOffRB.SetValue(True) + else: + self.sgmodeToggleRB.SetValue(True) + +####### Target Custom +class TargetCustomCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetCustomSizer = wx.GridBagSizer(5,5) + targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), + flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) + self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetCustomModeChoice.SetSelection(0) + targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) + self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) + self.targetCustomOptionalName.SetHint("Optional name to match") + targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) + self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") + targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) + self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") + targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) + self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") + targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) + self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") + targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) + self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") + targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) + self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") + targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) + self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") + targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) + self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") + targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) + + targetCustomSizer.AddGrowableCol(2) + + return targetCustomSizer + + def MakeBindString(self): + choice = self.targetCustomModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + targetCommand = "targetcustom" + mode.lower() + + enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" + friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" + defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" + alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" + mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" + notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" + base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" + notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" + + name = self.targetCustomOptionalName.GetValue() + + return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" + + def Serialize(self): + return { + 'mode' : self.targetCustomModeChoice.GetSelection(), + 'enemy' : self.targetCustomCBEnemies. IsChecked(), + 'friend' : self.targetCustomCBFriends. IsChecked(), + 'defeated' : self.targetCustomCBDefeated. IsChecked(), + 'alive' : self.targetCustomCBAlive. IsChecked(), + 'mypet' : self.targetCustomCBMyPets. IsChecked(), + 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), + 'base' : self.targetCustomCBBaseItems. IsChecked(), + 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), + 'name' : self.targetCustomOptionalName.GetValue(), + } + + def Deserialize(self, init): + if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) + if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) + if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) + if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) + if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) + if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) + if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) + if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) + if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) + if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) + + +####### Target Enemy +class TargetEnemyCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) + targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetEnemyModeChoice.SetSelection(0) + targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetEnemySizer + + def MakeBindString(self): + choice = self.targetEnemyModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetenemy" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetEnemyModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) + +####### Target Friend +class TargetFriendCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) + targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetFriendModeChoice.SetSelection(0) + targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetFriendSizer + + def MakeBindString(self): + choice = self.targetFriendModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetfriend" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetFriendModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) + +####### Team/Pet Select +class TeamPetSelectCmd(PowerBindCmd): + def BuildUI(self, dialog): + teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], + style=wx.ALIGN_CENTER_VERTICAL) + self.teamPetSelectNumber.SetSelection(0) + teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) + + return teamPetSelectSizer + + def MakeBindString(self): + teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' + targetNumber = self.teamPetSelectNumber.GetSelection()+1 + + return f"{teamOrPet}select {targetNumber}" + + def Serialize(self): + return { + 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', + 'targetNum': self.teamPetSelectNumber.GetSelection(), + } + + def Deserialize(self, init): + ToP = init.get('teamOrPet', '') + if ToP == 'pet': + self.teamPetSelectPetRB.SetValue(True) + else: + self.teamPetSelectTeamRB.SetValue(True) + if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) + +####### Unselect +class UnselectCmd(PowerBindCmd): + def MakeBindString(self): + return 'unselect' + +####### Use Insp By Name +class UseInspByNameCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) + for _, types in GameData.Inspirations.items(): + for _, info in types.items(): + for insp in info['tiers']: + name = re.sub(' ', '', str(insp)) + icon = GetIcon(f'Inspirations/{name}') + self.useInspByNameModeChoice.Append(insp, icon) + self.useInspByNameModeChoice.SetSelection(0) + useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) + + return useInspByNameSizer + + def MakeBindString(self): + choice = self.useInspByNameModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "inspexecname " + mode.lower() + + def GetAllInsps(self): + Insplist = [] + for _, info in GameData.Inspirations.items(): + for insp in info['tiers']: + Insplist.append(insp) + Insplist.append("---") + Insplist.pop(-1) # snip the terminal "---" + + return Insplist + + def Serialize(self): + return { 'insp' : self.useInspByNameModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) + +####### Use Insp From Row / Column +class UseInspRowColCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnRow.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) + self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnCol.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) + + return useInspRowColumnSizer + + def MakeBindString(self): + row = self.useInspRowColumnRow.GetSelection()+1 + col = self.useInspRowColumnCol.GetSelection()+1 + + return f"inspexectray {col} {row}" + + def Serialize(self): + return { + 'col' : self.useInspRowColumnCol.GetSelection(), + 'row' : self.useInspRowColumnRow.GetSelection(), + } + + def Deserialize(self, init): + if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) + if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) + +####### Use Power +class UsePowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + outerSizer = wx.BoxSizer(wx.HORIZONTAL) + + usePowerSizer = wx.GridBagSizer(5,5) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBToggle, (0,1)) + self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOn, (0,2)) + self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOff, (0,3)) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerName = PowerPicker(dialog) + usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) + usePowerSizer.AddGrowableCol(3) + + outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) + + return outerSizer + + def MakeBindString(self): + if self.usePowerRBToggle.GetValue(): + method = "powexecname" + elif self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') + return '' + + return f"{method} {self.usePowerName.GetLabel()}" + + def Serialize(self): + if self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + method = "powexecname" + return { + 'method': method, + 'pname' : self.usePowerName.GetLabel(), + 'picon' : self.usePowerName.IconFilename + } + + def Deserialize(self, init): + method = init.get('method', '') + if method == 'powexectoggleon': + self.usePowerRBOn.SetValue(True) + elif method == 'powexectoggleoff': + self.usePowerRBOff.SetValue(True) + else: + self.usePowerRBToggle.SetValue(True) + if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) + +####### Use Power From Tray +class UsePowerFromTrayCmd(PowerBindCmd): + def BuildUI(self, dialog): + usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTrayTray = wx.Choice(dialog, -1, + choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', + 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) + self.usePowerFromTrayTray.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) + self.usePowerFromTraySlot.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return usePowerFromTraySizer + + def MakeBindString(self): + choice = self.usePowerFromTrayTray + tray = choice.GetSelection() + + choice = self.usePowerFromTraySlot + slot = choice.GetSelection()+1 + + mode = "slot" + mode2 = '' + if tray > 3: + mode = "tray" + mode2 = f" {tray - 3}" + elif tray == 3: + mode = "alt2slot" + elif tray == 2: + mode = "altslot" + + return f"powexec{mode} {slot}{mode2}" + + def Serialize(self): + return { + 'tray' : self.usePowerFromTrayTray.GetSelection(), + 'slot' : self.usePowerFromTraySlot.GetSelection(), + } + + def Deserialize(self, init): + if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) + if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) + +####### Window Color +class WindowColorCmd(PowerBindCmd): + def BuildUI(self, dialog): + windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) + borderSizer = wx.BoxSizer(wx.VERTICAL) + self.ColorBorder.SetSizer(borderSizer) + self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) + borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) + + windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) + + RGBASizer = wx.FlexGridSizer(3, 4, 5) + + RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) + self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) + self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + windowColorSizer.Add(RGBASizer) + + self.UpdateFromSlider() + + return windowColorSizer + + def MakeBindString(self): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + return f"windowcolor {Rval} {Gval} {Bval} {Aval}" + + def Serialize(self): + return { + 'Rval' : self.RSlider.GetValue(), + 'Gval' : self.GSlider.GetValue(), + 'Bval' : self.BSlider.GetValue(), + 'Aval' : self.ASlider.GetValue(), + } + + def Deserialize(self, init): + self.RSlider.SetValue(init['Rval']) + self.GSlider.SetValue(init['Gval']) + self.BSlider.SetValue(init['Bval']) + self.ASlider.SetValue(init['Aval']) + self.UpdateFromSlider() + + def UpdateFromSlider(self, _ = None): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RReadout.SetValue(Rval) + self.GReadout.SetValue(Gval) + self.BReadout.SetValue(Bval) + self.AReadout.SetValue(Aval) + self.ColorBorder.Refresh() + + def UpdateFromText(self, _ = None): + Rval = self.RReadout.GetValue() + Gval = self.GReadout.GetValue() + Bval = self.BReadout.GetValue() + Aval = self.AReadout.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RSlider.SetValue(Rval) + self.GSlider.SetValue(Gval) + self.BSlider.SetValue(Bval) + self.ASlider.SetValue(Aval) + self.ColorBorder.Refresh() + +####### Window Save / Load +class WindowSaveLoadCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) + self.CommandChoice.SetSelection(0) + sizer.Add(self.CommandChoice, 0, wx.ALL, 5) + + self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), + value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) + sizer.Add(self.FilePath, 0, wx.ALL, 5) + + return sizer + + def MakeBindString(self): + command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] + return f'{command} "{self.FilePath.GetValue()}"' + + def Serialize(self): + return { + 'command' : self.CommandChoice.GetSelection(), + 'filename' : self.FilePath.GetValue(), + } + + def Deserialize(self, init): + self.CommandChoice.SetSelection(init.get('command', 0)) + self.FilePath.SetValue(init.get('filename', '')) + +####### Window Toggle +class WindowToggleCmd(PowerBindCmd): + def BuildUI(self, dialog): + self.WindowNames = { + 'Actions' : 'actions', + 'Auction House' : 'ah', + 'Badge' : 'badge', + 'Channel Search' : 'chansearch', + 'Chat' : 'chat', + 'Custom Chat 1' : 'chat1', + 'Custom Chat 2' : 'chat2', + 'Custom Chat 3' : 'chat3', + 'Custom Chat 4' : 'chat4', + 'Clues' : 'clue', + 'Combat Numbers' : 'combatnumbers', + 'Contacts' : 'contact', + 'Contact Finder' : 'contactfinder', + 'Costumes' : 'costume', + 'Email' : 'email', + 'Enhancements' : 'enhancements', + 'Friends' : 'friend', + 'Group' : 'group', + 'Help' : 'helpwindow', + 'Incarnate' : 'incarnate', + 'Inspirations' : 'insp', + 'League' : 'league', + 'LFG' : 'lfg', + 'Map' : 'map', + 'Mission' : 'mission', + 'Nav / Compass' : 'nav', + 'Options' : 'options', + 'Pets' : 'pet', + 'Petition' : 'petition', + 'Power Tray' : 'powers', + 'Power List' : 'powerlist', + 'Quit' : 'quit', + 'Recipes' : 'recipe', + 'Salvage' : 'salvage', + 'Search' : 'search', + 'Supergroup' : 'sg', + 'Target' : 'target', + 'Team' : 'team', + 'Tray' : 'tray', + 'Tray1' : 'tray1', + 'Tray2' : 'tray2', + 'Tray3' : 'tray3', + 'Tray4' : 'tray4', + 'Tray5' : 'tray5', + 'Tray6' : 'tray6', + 'Tray7' : 'tray7', + 'Tray8' : 'tray8', + 'Vault' : 'vault', + } + + self.ShortToggleCommands = { + 'Auction House' : 'ah', + 'Chat' : 'chat', + 'Help' : 'helpwindow', + 'Map' : 'map', + 'Nav / Compass' : 'nav', + 'Power Tray' : 'powers', + 'Target' : 'target', + 'Tray' : 'tray', + } + + windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) + windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) + self.windowToggleTray.SetSelection(0) + windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.windowShowRB = wx.RadioButton(dialog, -1, "Show") + self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") + + windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) + + return windowToggleSizer + + def MakeBindString(self): + choice = self.windowToggleTray + index = choice.GetSelection() + windowdesc = choice.GetString(index) + windowname = self.WindowNames[windowdesc] + + if self.windowShowRB.GetValue(): + return 'show ' + windowname + elif self.windowHideRB.GetValue(): + return 'windowhide ' + windowname + else: + if shortcmd := self.ShortToggleCommands.get(windowdesc, None): + return shortcmd + else: + return 'toggle ' + windowname + + + def Serialize(self): + choice = self.windowToggleTray + if self.windowShowRB.GetValue(): + action = "Show" + elif self.windowHideRB.GetValue(): + action = "Hide" + else: + action = "Toggle" + return { + 'window': choice.GetString(choice.GetSelection()), + 'action': action, + } + + def Deserialize(self, init): + choice = self.windowToggleTray + if window := init.get('window', ''): + if isinstance(window, int): + choice.SetSelection(window) + else: + choice.SetSelection(choice.FindString(window)) + + if choice.GetSelection() == wx.NOT_FOUND: + choice.SetSelection(0) + + action = init.get('action', '') + if action == "Show": + self.windowShowRB.SetValue(True) + elif action == "Hide": + self.windowHideRB.SetValue(True) + else: + self.windowToggleRB.SetValue(True) + + +# Must always add to this list when adding a new command class above +menuStructure = { + 'Graphics / UI' : [ + 'Attribute Monitor', + 'Buff Display Settings', + 'Graphics Settings', + 'Window Color', + 'Window Save / Load', + 'Window Toggle', + ], + 'Inspirations' : [ + 'Use Inspiration By Name', + 'Use Inspiration From Row/Column', + ], + 'Powers' : [ + 'Auto Power', + 'Power Abort', + 'Power Unqueue', + 'Use Power', + 'Use Power From Tray', + ], + 'Social' : [ + 'Away From Keyboard', + 'Chat Command', + 'Chat Command (Global)', + 'Costume Change', + 'Emote', + 'Supergroup Mode', + ], + 'Targeting' : [ + 'Target Custom', + 'Target Enemy', + 'Target Frield', + 'Team/Pet Select', + 'Unselect', + ], + 'Misc' : [ + 'Load Binds Directory', + 'Movement Commands', + ], + # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, + # but I'm leaving it here to remind myself that we do that. + } + +# Must always add to this list when adding a new command class above +commandClasses = { + 'Auto Power' : AutoPowerCmd, + 'Away From Keyboard' : AFKCmd, + 'Attribute Monitor' : AttributeMonitorCmd, + 'Buff Display Settings' : BuffDisplayCmd, + 'Chat Command' : ChatCmd, + 'Chat Command (Global)' : ChatGlobalCmd, + 'Costume Change' : CostumeChangeCmd, + 'Custom Bind' : CustomBindCmd, + 'Emote' : EmoteCmd, + 'Graphics Settings' : GraphicsCmd, + 'Load Binds Directory' : LoadBindsDir, + 'Movement Commands' : MovementCmd, + 'Power Abort' : PowerAbortCmd, + 'Power Unqueue' : PowerUnqueueCmd, + 'Supergroup Mode' : SGModeCmd, + 'Target Custom' : TargetCustomCmd, + 'Target Enemy' : TargetEnemyCmd, + 'Target Friend' : TargetFriendCmd, + 'Team/Pet Select' : TeamPetSelectCmd, + 'Unselect' : UnselectCmd, + 'Use Inspiration By Name' : UseInspByNameCmd, + 'Use Inspiration From Row/Column' : UseInspRowColCmd, + 'Use Power' : UsePowerCmd, + 'Use Power From Tray' : UsePowerFromTrayCmd, + 'Window Color' : WindowColorCmd, + 'Window Save / Load' : WindowSaveLoadCmd, + 'Window Toggle' : WindowToggleCmd, +} +# use these when we rename a commandClass so that old Profiles will still load correctly. +# If we've also updated the class, we need to try to make sure the new class will still +# Deserialize the legacy data, or at least not crash. +deprecatedCommandClasses = { + 'SG Mode Toggle' : SGModeCmd, + 'Use Insp By Name' : UseInspByNameCmd, + 'Use Insp From Row/Column' : UseInspRowColCmd, +} +commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/WindowColorCmd.py b/UI/PowerBinderCommand/WindowColorCmd.py new file mode 100644 index 0000000..4c02ab7 --- /dev/null +++ b/UI/PowerBinderCommand/WindowColorCmd.py @@ -0,0 +1,1800 @@ +import wx +import re +import UI +import UI.EmotePicker +from UI.ControlGroup import ControlGroup +from UI.PowerPicker import PowerPicker +from Help import HelpButton +import wx.adv +from wx.adv import BitmapComboBox, EditableListBox +from pathlib import PureWindowsPath +import GameData +import Profile +from Icon import GetIcon + +class PowerBinderDialog(wx.Dialog): + def __init__(self, parent, button, init = {}): + wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) + + self.Page = parent.Page + self.EditDialog = PowerBinderEditDialog(self) + self.Button = button + self.AddStepMenu = self.makeAddStepMenu() + + sizer = wx.BoxSizer(wx.VERTICAL); + self.mainSizer = sizer + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) + # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) + # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) + #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) + AddStepButton = wx.Button(self, -1, 'Add Step') + AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) + AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) + choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) + choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) + sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) + + rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) + + self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) + self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) + self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) + rearrangeCtrl.Add(self.RearrangeList, 1) + + rearrangeButtons = wx.BoxSizer(wx.VERTICAL) + self.DelButton = wx.Button(self, -1, "Delete") + self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) + self.EditButton = wx.Button(self, -1, "Edit") + self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) + self.EditButton.Disable() + upButton = wx.Button(self, -1, "\u25B2") + upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) + downButton = wx.Button(self, -1, "\u25BC") + downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) + rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) + rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) + + sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.BindStringDisplay = wx.TextCtrl(self, -1) + self.BindStringDisplay.Disable() + choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, + wx.ALIGN_CENTER_VERTICAL) + choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) + + sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) + + sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) + + # need to dig around and get the OK button since we show this dialog modelessly now. + okButton = self.FindWindow(self.GetAffirmativeId()) + okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) + + # Wrap everything in a vbox to add some padding + vbox = wx.BoxSizer(wx.VERTICAL); + vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); + + self.SetSizerAndFit(vbox); + self.Layout() + self.Fit() + self.SetFocus() + + # if we are loading from profile, ie, have "init", build the list from it + if init: self.LoadFromData(init) + + def LoadFromData(self, init): + for item in init: + for type, data in item.items(): + commandClass = commandClasses.get(type, None) + if not commandClass: + commandClass = deprecatedCommandClasses.get(type, None) + if not commandClass: + wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") + continue + newCommand = commandClass(self.EditDialog, data) + index = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.SetClientData(index, newCommand) + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) + self.EditDialog.mainSizer.Hide(newCommand.UI) + self.UpdateBindStringDisplay() + + def SaveToData(self): + data = [] + index = 0 + for _ in self.RearrangeList.GetItems(): + # check whether we have an object already attached to this choice + cmdObject = self.RearrangeList.GetClientData(index) + commandClassName = commandRevClasses[type(cmdObject)] + data.append({commandClassName: cmdObject.Serialize()}) + index = index + 1 + return data + + def OnAddStepButton(self, evt): + button = evt.EventObject + if not self.AddStepMenu: + self.AddStepMenu = self.makeAddStepMenu() + button.PopupMenu(self.AddStepMenu) + + + def OnOKButton(self, _): + if self.Button.tgtTxtCtrl: + bindString = self.MakeBindString() + if bindString != self.Button.tgtTxtCtrl.GetValue(): + self.Button.tgtTxtCtrl.SetValue(bindString) + wx.App.Get().Main.Profile.SetModified() + self.Close() + + def OnRearrangeDelete(self, _): + current = self.RearrangeList.GetSelection() + if current == wx.NOT_FOUND: return + + self.RearrangeList.Delete(current) + self.UpdateBindStringDisplay() + + def OnRearrangeUp(self, _): + self.RearrangeList.MoveCurrentUp() + self.UpdateBindStringDisplay() + + def OnRearrangeDown(self, _): + self.RearrangeList.MoveCurrentDown() + self.UpdateBindStringDisplay() + + def OnRearrangeEdit(self, _): + index = self.RearrangeList.GetSelection() + + # check whether we have an object already attached to this choice + cmdObject = None + try: + cmdObject = self.RearrangeList.GetClientData(index) + except Exception: + pass + + if cmdObject: + self.ShowEditDialogFor(cmdObject) + self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) + else: + print("cmdObject was None") + self.UpdateBindStringDisplay() + + # OnAddStepMenu creates a new step and adds it to the rearrangelist + def OnAddStepMenu(self, evt): + menuitem = self.AddStepMenu.FindItemById(evt.GetId()) + chosenName = menuitem.GetItemLabel() + + # make a new command object, attached to the parent dialog + newCommandClass = commandClasses[chosenName] + newCommand = newCommandClass(self.EditDialog) + + # show the edit dialog if this command needs it + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) + if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): + self.EditDialog.mainSizer.Remove(newCommand.UI) + return + + newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.Select(newBindIndex) + self.RearrangeList.SetClientData(newBindIndex, newCommand) + + self.OnListSelect() + self.UpdateBindStringDisplay() + + def OnListSelect(self, _ = None): + selected = self.RearrangeList.GetSelection() + + if selected != wx.NOT_FOUND: + selCommand = self.RearrangeList.GetClientData(selected) + if selCommand.UI: + self.EditButton.Enable() + else: + self.EditButton.Disable() + + def UpdateBindStringDisplay(self): + self.BindStringDisplay.SetValue(self.MakeBindString()) + self.BindStringDisplay.SetToolTip(self.MakeBindString()) + + def MakeBindString(self): + cmdBindStrings = [] + for index in range(self.RearrangeList.GetCount()): + c = self.RearrangeList.GetClientData(index) + if c: cmdBindStrings.append(c.MakeBindString()) + + bindstring = ('$$'.join(cmdBindStrings)) + return bindstring + + def ShowEditDialogFor(self, command): + if not command.UI: return + + self.EditDialog.mainSizer.Show(command.UI) + + self.EditDialog.Layout() + self.EditDialog.Fit() + + self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') + returnval = self.EditDialog.ShowModal() + + self.EditDialog.mainSizer.Hide(command.UI) + + return returnval + + def makeAddStepMenu(self): + + stepMenu = wx.Menu() + + for subname in menuStructure: + submenu = wx.Menu() + stepMenu.AppendSubMenu(submenu, subname) + for classname in menuStructure[subname]: + submenu.Append(wx.ID_ANY, classname) + + stepMenu.Append(wx.ID_ANY, 'Custom Bind') + + return stepMenu + +class PowerBinderButton(wx.BitmapButton): + + def __init__(self, parent, tgtTxtCtrl, init = {}): + wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) + self.Init = init + self.Dialog = None + self.DialogParent = parent + + self.tgtTxtCtrl = tgtTxtCtrl + self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) + self.SetToolTip("Launch PowerBinder") + + def PowerBinderEventHandler(self, _): + self.PowerBinderDialog().Show() + + def LoadFromData(self, data): + self.PowerBinderDialog().LoadFromData(data) + + def SaveToData(self): + return self.PowerBinderDialog().SaveToData() + + def PowerBinderDialog(self): + if not self.Dialog: + self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) + return self.Dialog + + +class PowerBinderEditDialog(wx.Dialog): + def __init__(self, parent): + wx.Dialog.__init__(self, parent, -1, "Edit Step", + style = wx.DEFAULT_DIALOG_STYLE) + + outerSizer = wx.BoxSizer(wx.VERTICAL) + + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + self.mainSizer.SetMinSize([500, 150]) + + self.Page = parent.Page + + self.mainSizer.Add( + self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), + 0, wx.EXPAND|wx.ALL, 10) + + outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) + + self.SetSizerAndFit(outerSizer) + self.Layout() + self.Fit() + +########### Power Binder Command Objects +class PowerBindCmd(): + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + commandClassName = commandRevClasses[type(self)] + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{commandClassName} - {short_bindstr}" + + +####### Away From Keyboard +class AFKCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) + +####### Attribute Monitor +class AttributeMonitorCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.Groups = {} + self.AttributeTable = { + 'Base' : { + 'Current Hit Points' : 'NT H', + 'Max Hit Points' : 'X H', + 'Current Endurance' : 'T E', + 'Max Endurance' : 'X EN', + 'Regeneration Rate' : 'N RAT', + 'Recovery Rate' : 'Y RA', + 'Endurance Consumption' : 'SU', + 'ToHit Bonus' : 'T B', + 'Accuracy Bonus' : 'CC', + 'Last Hit Chance' : 'T C', + 'Damage Bonus' : 'DA', + 'Healing Bonus' : 'NG B', + 'Recharge Time Bonus' : 'ME B', + 'Endurance Discount' : 'CE DIS', + 'Stealth Radius (PvP)' : 'PVP', + 'Stealth Radius (PvE)' : 'PVE', + 'Perception Radius' : 'RC', + 'Range Bonus' : 'GE B', + 'Threat Level' : 'AT L', + 'Experience to Next Level' : 'XT', + 'Experience Debt' : 'XP', + 'Influence / Infamy' : 'INF', + 'Inherent' : 'NH', + }, + 'Movement Speed' : { + 'Flying Speed' : 'FL', + 'Jumping Speed' : 'PI', + 'Max Jump Height' : 'X J', + 'Run Speed' : 'RU', + }, + 'Damage Resistance' : { + 'Smashing Resistance' : 'G R', + 'Lethal Resistance' : 'L R', + 'Fire Resistance' : 'RE R', + 'Cold Resistance' : 'COLD R', + 'Energy Resistance' : 'DamageType[4]', + 'Negative Energy Resistance' : 'GY R', + 'Psyonic Resistance' : 'NIC R', + 'Toxic Resistance' : 'XIC R', + }, + 'Defense' : { + 'Base Defense' : 'BAS', + 'Ranged Defense' : 'ED', + 'Melee Defense' : 'MEL', + 'AoE Defense' : '2', + 'Smashing Defense' : '3', + 'Lethal Defense' : '4', + 'Fire Defense' : '5', + 'Cold Defense' : '6', + 'Energy Defense' : '7', + 'Negative Energy Defense' : '8', + 'Psionic Defense' : '9', + 'Toxic Defense' : '1', + }, + 'Debuff Resistance' : { + 'Regeneration Resistance' : 'ON R', + 'Recovery Resistance' : 'RY R', + 'To Hit Resistance' : 'IT R', + 'Defense Resistance' : 'NSE RES', + }, + 'Status Effect Protection' : { + 'Hold Protection' : 'D P', + 'Immobilize Protection' : 'LIZE P', + 'Stun Protection' : 'N P', + 'Sleep Protection' : 'P P', + 'Knockback Protection' : 'K P', + 'Confuse Protection' : 'SE P', + 'Terrorize Protection' : 'ZE P', + 'Repel Protection' : 'EL P', + 'Teleport Protection' : 'T P', + }, + 'Status Effect Resistance' : { + 'Hold Resistance' : 'D R', + 'Immobilize Resistance' : 'LIZE R', + 'Stun Resistance' : 'N R', + 'Sleep Resistance' : 'P R', + 'Knockback Resistance' : 'K R', + 'Confuse Resistance' : 'SE R', + 'Terrorize Resistance' : 'ZE R', + 'Placate Resistance' : 'TE R', + 'Taunt Resistance' : 'NT R', + }, + 'Miscellaneous' : { + 'Level Shift' : 'L S', + }, + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.AttributeMenu = wx.Menu() + for group, controls in self.AttributeTable.items(): + submenu = wx.Menu() + self.AttributeMenu.AppendSubMenu(submenu, group) + for cb in controls: + submenu.Append(wx.ID_ANY, cb) + + self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) + + self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) + groupSizer.Add(self.editbox) + + newButton = self.editbox.GetNewButton() + newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) + + return groupSizer + + def MakeBindString(self): + map = {} + bindstrings = [] + for _, controls in self.AttributeTable.items(): + for cb, data in controls.items(): + map[cb] = data + + for string in self.editbox.GetStrings(): + if string: + bindstrings.append(f'monitorattribute {map[string]}') + + return '$$'.join(bindstrings) + + def Serialize(self): + return { + 'attributes' : self.editbox.GetStrings() + } + + def Deserialize(self, init): + self.editbox.SetStrings(init.get('attributes', [])) + + def OnNewButton(self, evt): + evt.GetEventObject().PopupMenu(self.AttributeMenu) + + def OnMenuItem(self, evt): + menuitem = evt.EventObject.FindItemById(evt.GetId()) + existingstrings = self.editbox.GetStrings() + existingstrings.append(menuitem.GetItemLabel()) + self.editbox.SetStrings(existingstrings) + +####### Auto Power +class AutoPowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) + autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.autoPowerName = PowerPicker(dialog) + autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) + + return autoPowerSizer + + def MakeBindString(self): + return f"powexecauto {self.autoPowerName.GetLabel()}" + + def Serialize(self): + return { + 'pname' : self.autoPowerName.GetLabel(), + 'picon' : self.autoPowerName.IconFilename + } + + def Deserialize(self, init): + if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) + +####### Buff Display Command +class BuffDisplayCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.buffDisplayMap = { + 'Status Window' : { + 'Hide Auto' : 1, + 'Hide Toggles' : 2, + 'No Blinking' : 4, + 'No Stacking' : 8, + 'Numeric Stacking' : 16, + 'Hide Buff Numbers' : 32, + 'Stop Sending Buffs' : 64, + }, + 'Group Window' : { + 'Hide Auto' : 256, + 'Hide Toggles' : 512, + 'No Blinking' : 1024, + 'No Stacking' : 2048, + 'Numeric Stacking' : 4096, + 'Hide Buff Numbers' : 8192, + 'Stop Sending Buffs' : 16384, + }, + 'Pet Window' : { + 'Hide Auto' : 65536, + 'Hide Toggles' : 131072, + 'No Blinking' : 262144, + 'No Stacking' : 524288, + 'Numeric Stacking' : 1048576, + 'Hide Buff Numbers' : 2097152, + 'Stop Sending Buffs' : 4194304, + }, + } + self.Groups = {} + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + for group, controls in self.buffDisplayMap.items(): + self.Groups[group] = ControlGroup(dialog, self.Page, label = group) + groupid = self.Groups[group].GetStaticBox().GetId() + for cb, data in controls.items(): + self.Groups[group].AddControl( + ctlType = 'checkbox', + ctlName = f"{groupid}_{group}_{cb}", + label = cb, + data = data, + ) + + groupSizer.Add(self.Groups[group]) + + return groupSizer + + def CalculateValue(self): + page = wx.App.Get().Main.Profile.CustomBinds + + total = 0 + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] + if checkbox.IsChecked(): + total = total + checkbox.Data + return total + + def MakeBindString(self): + return f"optionset buffsettings {self.CalculateValue()}" + + def Serialize(self): + return { 'value' : self.CalculateValue() } + + def Deserialize(self, init): + value = init.get('value', 0) + + value = value or 0 # in case we had for some reason 'None' stashed in the init values + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] + checkbox.SetValue( checkbox.Data & value ) + +####### Chat Command +class ChatCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.chatChannelMap = { # before __init__ + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + chatCommandSizer = wx.GridBagSizer(5, 5) + self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") + chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) + # row 1 + self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) + self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) + self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) + # row 2 + self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) + self.chatCommandDuration.SetRange(1, 20) + self.chatCommandDuration.SetValue(7) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandDuration, (2,1)) + self.chatCommandChatSize = wx.Choice(dialog, -1, + choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) + self.chatCommandChatSize.SetSelection(5) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) + self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) + self.chatCommandChannel.SetSelection(0) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChannel, (2,5)) + # row 3 + self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") + chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) + self.chatCommandMessage = wx.TextCtrl(dialog, -1) + self.chatCommandMessage.SetHint('Chat Command Text') + chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) + + return chatCommandSizer + + def MakeBindString(self): + duration = self.chatCommandDuration.GetValue() + + choice = self.chatCommandChatSize + index = choice.GetSelection() + size = choice.GetString(index) + + duration = f"" if duration != 7 else "" + size = f"" if size != "1" else "" + + bdcolor = fgcolor = bgcolor = '' + if self.chatCommandUseColorsCB.IsChecked(): + bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + + bdcolor = f"" + fgcolor = f"" + bgcolor = f"" + + beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' + text = self.chatCommandMessage.GetValue() + + choice = self.chatCommandChannel + index = choice.GetSelection() + channel = choice.GetString(index) + + return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" + + def Serialize(self): + return { + 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), + 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), + 'channel' : self.chatCommandChannel .GetSelection(), + 'size' : self.chatCommandChatSize.GetSelection(), + 'duration' : self.chatCommandDuration.GetValue(), + 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'text' : self.chatCommandMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) + if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) + if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) + if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) + if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) + if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) + if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) + if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) + if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) + + +####### Chat Command Global +class ChatGlobalCmd(PowerBindCmd): + def BuildUI(self, dialog): + chatCommandGlobalSizer = wx.GridBagSizer(5,5) + + self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") + chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) + + self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalChannel.SetHint("Channel") + chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) + + self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') + chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) + + chatCommandGlobalSizer.AddGrowableCol(1) + + return chatCommandGlobalSizer + + def MakeBindString(self): + useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() + channel = self.chatCommandGlobalChannel.GetValue() + message = self.chatCommandGlobalMessage.GetValue() + + preface = "beginchat /" if useBeginchat else "" + + return f'{preface}send "{channel}" {message}' + + def Serialize(self): + return { + 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), + 'channel' : self.chatCommandGlobalChannel.GetValue(), + 'message' : self.chatCommandGlobalMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) + if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) + if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) + +#######Costume Change +class CostumeChangeCmd(PowerBindCmd): + def BuildUI(self, dialog): + costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeCostume = wx.Choice(dialog, -1, + choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) + self.costumeChangeCostume.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeEmote = wx.Choice(dialog, -1, + choices = GameData.Emotes['costumechange']) + self.costumeChangeEmote.Insert("- None -", 0) + self.costumeChangeEmote.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return costumeChangeSizer + + def MakeBindString(self): + costumeNumber = self.costumeChangeCostume.GetSelection() + costumeEmote = self.costumeChangeEmote.GetSelection() + + if costumeEmote: # None, or 0 == "- None -" + ccCmd = 'cce' + emoteName = self.costumeChangeEmote.GetString(costumeEmote) + emoteName = " CC" + emoteName.replace(" ","") + else: + ccCmd = 'cc' + emoteName = '' + + return f"{ccCmd} {costumeNumber}{emoteName}" + + def Serialize(self): + return{ + 'costumeNumber': self.costumeChangeCostume.GetSelection(), + 'costumeEmote' : self.costumeChangeEmote.GetSelection(), + } + + def Deserialize(self, init): + if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) + if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) + +####### Movement Command +class MovementCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + self.plusbutton.SetValue(True) + + self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.commandchoice = wx.Choice(dialog, choices = [ + "forward", "left", "right", "backward", "up", "down", + "turnleft", "turnright", "first", "autorun", "clicktomove", + ],) + sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) + self.commandchoice.SetSelection(0) + + self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + pre = post = '' + if self.plusbutton.GetValue() : pre = "+" + elif self.plusplusbutton.GetValue() : pre = "++" + elif self.minusbutton.GetValue() : pre = "-" + elif self.zerobutton.GetValue() : post = " 0" + elif self.onebutton.GetValue() : post = " 1" + + command = self.commandchoice.GetString(self.commandchoice.GetSelection()) + + return f"{pre}{command}{post}" + + def Serialize(self): + mod = '' + if self.plusbutton.GetValue() : mod = "plus" + elif self.plusplusbutton.GetValue() : mod = "plusplus" + elif self.minusbutton.GetValue() : mod = "minus" + elif self.zerobutton.GetValue() : mod = "zero" + elif self.onebutton.GetValue() : mod = "one" + + return { + 'mod' : mod, + 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), + } + + def Deserialize(self, init): + mod = init.get('mod', 'plus') + + if mod == 'plus' : self.plusbutton.SetValue(True) + elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) + elif mod == 'minus' : self.minusbutton.SetValue(True) + elif mod == 'zero' : self.zerobutton.SetValue(True) + elif mod == 'one' : self.onebutton.SetValue(True) + + self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) + +####### Graphics Command +class GraphicsCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.FlexGridSizer(2) + + self.visscalecb = wx.CheckBox(dialog, label = "visscale") + sizer.Add(self.visscalecb) + self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) + sizer.Add(self.visscalesc) + + self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") + sizer.Add(self.dofweightcb) + self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) + sizer.Add(self.dofweightsc) + + self.fsaacb = wx.CheckBox(dialog, label = "fsaa") + sizer.Add(self.fsaacb) + self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) + self.fsaach.SetSelection(0) + sizer.Add(self.fsaach) + + self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") + sizer.Add(self.bloomscalecb) + self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) + self.bloomscalech.SetSelection(0) + sizer.Add(self.bloomscalech) + + self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") + sizer.Add(self.bloomweightcb) + self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) + sizer.Add(self.bloomweightsc) + + self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") + sizer.Add(self.lodbiascb) + self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) + sizer.Add(self.lodbiassc) + + self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") + sizer.Add(self.renderscalecb) + self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) + sizer.Add(self.renderscalesc) + + return sizer + + def MakeBindString(self): + # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. + bindstrings = [] + if self.visscalecb.IsChecked(): + bindstrings.append("visscale " + str(self.visscalesc.GetValue())) + if self.dofweightcb.IsChecked(): + bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) + if self.fsaacb.IsChecked(): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bindstrings.append("fsaa " + fsaavalue) + if self.bloomscalecb.IsChecked(): + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + bindstrings.append("bloomscale " + bloomscalevalue) + if self.bloomweightcb.IsChecked(): + bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) + if self.lodbiascb.IsChecked(): + bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) + if self.renderscalecb.IsChecked(): + bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) + + return '$$'.join(bindstrings) + + def Serialize(self): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + return { + 'visscalecb' : self.visscalecb.IsChecked(), + 'visscalesc' : self.visscalesc.GetValue(), + 'dofweightcb' : self.dofweightcb.IsChecked(), + 'dofweightsc' : self.dofweightsc.GetValue(), + 'fsaacb' : self.fsaacb.IsChecked(), + 'fsaach' : fsaavalue, + 'bloomscalecb' : self.bloomscalecb.IsChecked(), + 'bloomscalech' : bloomscalevalue, + 'bloomweightcb' : self.bloomweightcb.IsChecked(), + 'bloomweightsc' : self.bloomweightsc.GetValue(), + 'lodbiascb' : self.lodbiascb.IsChecked(), + 'lodbiassc' : self.lodbiassc.GetValue(), + 'renderscalecb' : self.renderscalecb.IsChecked(), + 'renderscalesc' : self.renderscalesc.GetValue(), + } + + def Deserialize(self, init): + self.visscalecb.SetValue(init.get('visscalecb', False)) + self.visscalesc.SetValue(init.get('visscalesc', 1.0)) + self.dofweightcb.SetValue(init.get('dofweightcb', False)) + self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) + self.fsaacb.SetValue(init.get('fsaacb', False)) + self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) + self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) + self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) + self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) + self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) + self.lodbiascb.SetValue(init.get('lodbiascb', False)) + self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) + self.renderscalecb.SetValue(init.get('renderscalecb', False)) + self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) + +####### Custom Bind +class CustomBindCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.customBindName = wx.TextCtrl(dialog, -1) + self.customBindName.SetHint('Custom Bind Text') + sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + return self.customBindName.GetValue() + + def Serialize(self): + return { 'customBindName': self.customBindName.GetValue() } + + def Deserialize(self,init): + if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) + +####### Emote +class EmoteCmd(PowerBindCmd): + def BuildUI(self, dialog): + emoteSizer = wx.BoxSizer(wx.HORIZONTAL) + self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") + emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + self.emoteName = wx.Button(dialog, -1, "...") + self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) + emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) + + return emoteSizer + + def MakeBindString(self): + displayedEmoteName = self.emoteName.GetLabel() + actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] + + return actualEmotePayload + + def Serialize(self): + return {'emoteName': self.emoteName.GetLabel()} + + def Deserialize(self, init): + if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) + +####### Load Binds Directory +class LoadBindsDir(PowerBindCmd): + def BuildUI(self, dialog): + mainSizer = wx.BoxSizer(wx.VERTICAL) + + lbSizer = wx.BoxSizer(wx.HORIZONTAL) + lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") + lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + profiles = Profile.GetAllProfileBindsDirs() + + self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) + lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") + self.lbResetCB.SetValue(True) + + mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + return mainSizer + + def MakeBindString(self): + + # If the specified binds directory disappeared between runs, we'd crash, so handle that. + if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' + + config = wx.ConfigBase.Get() + if config.Exists('GameBindPath'): + bindpath = config.Read('GameBindPath') + else: + bindpath = config.Read('BindPath') + + reset = "" + if self.lbResetCB.GetValue(): + reset = "keybind_reset$$" + + resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' + return reset + 'bindloadfile ' + str(resetfilepath) + + def Serialize(self): + return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), + 'ResetKeybinds' : self.lbResetCB.GetValue(), + } + + def Deserialize(self, init): + if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) + self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) + +####### Power Abort +class PowerAbortCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecabort' + +####### Power Unqueue +class PowerUnqueueCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecunqueue' + +####### SG Mode +class SGModeCmd(PowerBindCmd): + def BuildUI(self, dialog): + sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) + sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") + self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") + + sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) + + return sgmodeSizer + + def MakeBindString(self): + if self.sgmodeOnRB.GetValue(): + return 'sgmodeset 1' + elif self.sgmodeOffRB.GetValue(): + return 'sgmodeset 0' + else: + return 'sgmode' + + def Serialize(self): + if self.sgmodeOnRB.GetValue(): + val = "On" + elif self.sgmodeOffRB.GetValue(): + val = "Off" + else: + val = "Toggle" + + return {"value" : val} + + def Deserialize(self, init): + val = init.get('value', '') + if val == "On": + self.sgmodeOnRB.SetValue(True) + elif val == "Off": + self.sgmodeOffRB.SetValue(True) + else: + self.sgmodeToggleRB.SetValue(True) + +####### Target Custom +class TargetCustomCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetCustomSizer = wx.GridBagSizer(5,5) + targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), + flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) + self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetCustomModeChoice.SetSelection(0) + targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) + self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) + self.targetCustomOptionalName.SetHint("Optional name to match") + targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) + self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") + targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) + self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") + targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) + self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") + targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) + self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") + targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) + self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") + targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) + self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") + targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) + self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") + targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) + self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") + targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) + + targetCustomSizer.AddGrowableCol(2) + + return targetCustomSizer + + def MakeBindString(self): + choice = self.targetCustomModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + targetCommand = "targetcustom" + mode.lower() + + enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" + friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" + defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" + alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" + mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" + notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" + base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" + notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" + + name = self.targetCustomOptionalName.GetValue() + + return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" + + def Serialize(self): + return { + 'mode' : self.targetCustomModeChoice.GetSelection(), + 'enemy' : self.targetCustomCBEnemies. IsChecked(), + 'friend' : self.targetCustomCBFriends. IsChecked(), + 'defeated' : self.targetCustomCBDefeated. IsChecked(), + 'alive' : self.targetCustomCBAlive. IsChecked(), + 'mypet' : self.targetCustomCBMyPets. IsChecked(), + 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), + 'base' : self.targetCustomCBBaseItems. IsChecked(), + 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), + 'name' : self.targetCustomOptionalName.GetValue(), + } + + def Deserialize(self, init): + if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) + if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) + if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) + if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) + if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) + if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) + if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) + if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) + if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) + if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) + + +####### Target Enemy +class TargetEnemyCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) + targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetEnemyModeChoice.SetSelection(0) + targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetEnemySizer + + def MakeBindString(self): + choice = self.targetEnemyModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetenemy" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetEnemyModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) + +####### Target Friend +class TargetFriendCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) + targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetFriendModeChoice.SetSelection(0) + targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetFriendSizer + + def MakeBindString(self): + choice = self.targetFriendModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetfriend" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetFriendModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) + +####### Team/Pet Select +class TeamPetSelectCmd(PowerBindCmd): + def BuildUI(self, dialog): + teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], + style=wx.ALIGN_CENTER_VERTICAL) + self.teamPetSelectNumber.SetSelection(0) + teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) + + return teamPetSelectSizer + + def MakeBindString(self): + teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' + targetNumber = self.teamPetSelectNumber.GetSelection()+1 + + return f"{teamOrPet}select {targetNumber}" + + def Serialize(self): + return { + 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', + 'targetNum': self.teamPetSelectNumber.GetSelection(), + } + + def Deserialize(self, init): + ToP = init.get('teamOrPet', '') + if ToP == 'pet': + self.teamPetSelectPetRB.SetValue(True) + else: + self.teamPetSelectTeamRB.SetValue(True) + if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) + +####### Unselect +class UnselectCmd(PowerBindCmd): + def MakeBindString(self): + return 'unselect' + +####### Use Insp By Name +class UseInspByNameCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) + for _, types in GameData.Inspirations.items(): + for _, info in types.items(): + for insp in info['tiers']: + name = re.sub(' ', '', str(insp)) + icon = GetIcon(f'Inspirations/{name}') + self.useInspByNameModeChoice.Append(insp, icon) + self.useInspByNameModeChoice.SetSelection(0) + useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) + + return useInspByNameSizer + + def MakeBindString(self): + choice = self.useInspByNameModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "inspexecname " + mode.lower() + + def GetAllInsps(self): + Insplist = [] + for _, info in GameData.Inspirations.items(): + for insp in info['tiers']: + Insplist.append(insp) + Insplist.append("---") + Insplist.pop(-1) # snip the terminal "---" + + return Insplist + + def Serialize(self): + return { 'insp' : self.useInspByNameModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) + +####### Use Insp From Row / Column +class UseInspRowColCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnRow.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) + self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnCol.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) + + return useInspRowColumnSizer + + def MakeBindString(self): + row = self.useInspRowColumnRow.GetSelection()+1 + col = self.useInspRowColumnCol.GetSelection()+1 + + return f"inspexectray {col} {row}" + + def Serialize(self): + return { + 'col' : self.useInspRowColumnCol.GetSelection(), + 'row' : self.useInspRowColumnRow.GetSelection(), + } + + def Deserialize(self, init): + if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) + if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) + +####### Use Power +class UsePowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + outerSizer = wx.BoxSizer(wx.HORIZONTAL) + + usePowerSizer = wx.GridBagSizer(5,5) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBToggle, (0,1)) + self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOn, (0,2)) + self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOff, (0,3)) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerName = PowerPicker(dialog) + usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) + usePowerSizer.AddGrowableCol(3) + + outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) + + return outerSizer + + def MakeBindString(self): + if self.usePowerRBToggle.GetValue(): + method = "powexecname" + elif self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') + return '' + + return f"{method} {self.usePowerName.GetLabel()}" + + def Serialize(self): + if self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + method = "powexecname" + return { + 'method': method, + 'pname' : self.usePowerName.GetLabel(), + 'picon' : self.usePowerName.IconFilename + } + + def Deserialize(self, init): + method = init.get('method', '') + if method == 'powexectoggleon': + self.usePowerRBOn.SetValue(True) + elif method == 'powexectoggleoff': + self.usePowerRBOff.SetValue(True) + else: + self.usePowerRBToggle.SetValue(True) + if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) + +####### Use Power From Tray +class UsePowerFromTrayCmd(PowerBindCmd): + def BuildUI(self, dialog): + usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTrayTray = wx.Choice(dialog, -1, + choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', + 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) + self.usePowerFromTrayTray.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) + self.usePowerFromTraySlot.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return usePowerFromTraySizer + + def MakeBindString(self): + choice = self.usePowerFromTrayTray + tray = choice.GetSelection() + + choice = self.usePowerFromTraySlot + slot = choice.GetSelection()+1 + + mode = "slot" + mode2 = '' + if tray > 3: + mode = "tray" + mode2 = f" {tray - 3}" + elif tray == 3: + mode = "alt2slot" + elif tray == 2: + mode = "altslot" + + return f"powexec{mode} {slot}{mode2}" + + def Serialize(self): + return { + 'tray' : self.usePowerFromTrayTray.GetSelection(), + 'slot' : self.usePowerFromTraySlot.GetSelection(), + } + + def Deserialize(self, init): + if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) + if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) + +####### Window Color +class WindowColorCmd(PowerBindCmd): + def BuildUI(self, dialog): + windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) + borderSizer = wx.BoxSizer(wx.VERTICAL) + self.ColorBorder.SetSizer(borderSizer) + self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) + borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) + + windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) + + RGBASizer = wx.FlexGridSizer(3, 4, 5) + + RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) + self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) + self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + windowColorSizer.Add(RGBASizer) + + self.UpdateFromSlider() + + return windowColorSizer + + def MakeBindString(self): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + return f"windowcolor {Rval} {Gval} {Bval} {Aval}" + + def Serialize(self): + return { + 'Rval' : self.RSlider.GetValue(), + 'Gval' : self.GSlider.GetValue(), + 'Bval' : self.BSlider.GetValue(), + 'Aval' : self.ASlider.GetValue(), + } + + def Deserialize(self, init): + self.RSlider.SetValue(init['Rval']) + self.GSlider.SetValue(init['Gval']) + self.BSlider.SetValue(init['Bval']) + self.ASlider.SetValue(init['Aval']) + self.UpdateFromSlider() + + def UpdateFromSlider(self, _ = None): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RReadout.SetValue(Rval) + self.GReadout.SetValue(Gval) + self.BReadout.SetValue(Bval) + self.AReadout.SetValue(Aval) + self.ColorBorder.Refresh() + + def UpdateFromText(self, _ = None): + Rval = self.RReadout.GetValue() + Gval = self.GReadout.GetValue() + Bval = self.BReadout.GetValue() + Aval = self.AReadout.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RSlider.SetValue(Rval) + self.GSlider.SetValue(Gval) + self.BSlider.SetValue(Bval) + self.ASlider.SetValue(Aval) + self.ColorBorder.Refresh() + +####### Window Save / Load +class WindowSaveLoadCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) + self.CommandChoice.SetSelection(0) + sizer.Add(self.CommandChoice, 0, wx.ALL, 5) + + self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), + value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) + sizer.Add(self.FilePath, 0, wx.ALL, 5) + + return sizer + + def MakeBindString(self): + command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] + return f'{command} "{self.FilePath.GetValue()}"' + + def Serialize(self): + return { + 'command' : self.CommandChoice.GetSelection(), + 'filename' : self.FilePath.GetValue(), + } + + def Deserialize(self, init): + self.CommandChoice.SetSelection(init.get('command', 0)) + self.FilePath.SetValue(init.get('filename', '')) + +####### Window Toggle +class WindowToggleCmd(PowerBindCmd): + def BuildUI(self, dialog): + self.WindowNames = { + 'Actions' : 'actions', + 'Auction House' : 'ah', + 'Badge' : 'badge', + 'Channel Search' : 'chansearch', + 'Chat' : 'chat', + 'Custom Chat 1' : 'chat1', + 'Custom Chat 2' : 'chat2', + 'Custom Chat 3' : 'chat3', + 'Custom Chat 4' : 'chat4', + 'Clues' : 'clue', + 'Combat Numbers' : 'combatnumbers', + 'Contacts' : 'contact', + 'Contact Finder' : 'contactfinder', + 'Costumes' : 'costume', + 'Email' : 'email', + 'Enhancements' : 'enhancements', + 'Friends' : 'friend', + 'Group' : 'group', + 'Help' : 'helpwindow', + 'Incarnate' : 'incarnate', + 'Inspirations' : 'insp', + 'League' : 'league', + 'LFG' : 'lfg', + 'Map' : 'map', + 'Mission' : 'mission', + 'Nav / Compass' : 'nav', + 'Options' : 'options', + 'Pets' : 'pet', + 'Petition' : 'petition', + 'Power Tray' : 'powers', + 'Power List' : 'powerlist', + 'Quit' : 'quit', + 'Recipes' : 'recipe', + 'Salvage' : 'salvage', + 'Search' : 'search', + 'Supergroup' : 'sg', + 'Target' : 'target', + 'Team' : 'team', + 'Tray' : 'tray', + 'Tray1' : 'tray1', + 'Tray2' : 'tray2', + 'Tray3' : 'tray3', + 'Tray4' : 'tray4', + 'Tray5' : 'tray5', + 'Tray6' : 'tray6', + 'Tray7' : 'tray7', + 'Tray8' : 'tray8', + 'Vault' : 'vault', + } + + self.ShortToggleCommands = { + 'Auction House' : 'ah', + 'Chat' : 'chat', + 'Help' : 'helpwindow', + 'Map' : 'map', + 'Nav / Compass' : 'nav', + 'Power Tray' : 'powers', + 'Target' : 'target', + 'Tray' : 'tray', + } + + windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) + windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) + self.windowToggleTray.SetSelection(0) + windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.windowShowRB = wx.RadioButton(dialog, -1, "Show") + self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") + + windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) + + return windowToggleSizer + + def MakeBindString(self): + choice = self.windowToggleTray + index = choice.GetSelection() + windowdesc = choice.GetString(index) + windowname = self.WindowNames[windowdesc] + + if self.windowShowRB.GetValue(): + return 'show ' + windowname + elif self.windowHideRB.GetValue(): + return 'windowhide ' + windowname + else: + if shortcmd := self.ShortToggleCommands.get(windowdesc, None): + return shortcmd + else: + return 'toggle ' + windowname + + + def Serialize(self): + choice = self.windowToggleTray + if self.windowShowRB.GetValue(): + action = "Show" + elif self.windowHideRB.GetValue(): + action = "Hide" + else: + action = "Toggle" + return { + 'window': choice.GetString(choice.GetSelection()), + 'action': action, + } + + def Deserialize(self, init): + choice = self.windowToggleTray + if window := init.get('window', ''): + if isinstance(window, int): + choice.SetSelection(window) + else: + choice.SetSelection(choice.FindString(window)) + + if choice.GetSelection() == wx.NOT_FOUND: + choice.SetSelection(0) + + action = init.get('action', '') + if action == "Show": + self.windowShowRB.SetValue(True) + elif action == "Hide": + self.windowHideRB.SetValue(True) + else: + self.windowToggleRB.SetValue(True) + + +# Must always add to this list when adding a new command class above +menuStructure = { + 'Graphics / UI' : [ + 'Attribute Monitor', + 'Buff Display Settings', + 'Graphics Settings', + 'Window Color', + 'Window Save / Load', + 'Window Toggle', + ], + 'Inspirations' : [ + 'Use Inspiration By Name', + 'Use Inspiration From Row/Column', + ], + 'Powers' : [ + 'Auto Power', + 'Power Abort', + 'Power Unqueue', + 'Use Power', + 'Use Power From Tray', + ], + 'Social' : [ + 'Away From Keyboard', + 'Chat Command', + 'Chat Command (Global)', + 'Costume Change', + 'Emote', + 'Supergroup Mode', + ], + 'Targeting' : [ + 'Target Custom', + 'Target Enemy', + 'Target Frield', + 'Team/Pet Select', + 'Unselect', + ], + 'Misc' : [ + 'Load Binds Directory', + 'Movement Commands', + ], + # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, + # but I'm leaving it here to remind myself that we do that. + } + +# Must always add to this list when adding a new command class above +commandClasses = { + 'Auto Power' : AutoPowerCmd, + 'Away From Keyboard' : AFKCmd, + 'Attribute Monitor' : AttributeMonitorCmd, + 'Buff Display Settings' : BuffDisplayCmd, + 'Chat Command' : ChatCmd, + 'Chat Command (Global)' : ChatGlobalCmd, + 'Costume Change' : CostumeChangeCmd, + 'Custom Bind' : CustomBindCmd, + 'Emote' : EmoteCmd, + 'Graphics Settings' : GraphicsCmd, + 'Load Binds Directory' : LoadBindsDir, + 'Movement Commands' : MovementCmd, + 'Power Abort' : PowerAbortCmd, + 'Power Unqueue' : PowerUnqueueCmd, + 'Supergroup Mode' : SGModeCmd, + 'Target Custom' : TargetCustomCmd, + 'Target Enemy' : TargetEnemyCmd, + 'Target Friend' : TargetFriendCmd, + 'Team/Pet Select' : TeamPetSelectCmd, + 'Unselect' : UnselectCmd, + 'Use Inspiration By Name' : UseInspByNameCmd, + 'Use Inspiration From Row/Column' : UseInspRowColCmd, + 'Use Power' : UsePowerCmd, + 'Use Power From Tray' : UsePowerFromTrayCmd, + 'Window Color' : WindowColorCmd, + 'Window Save / Load' : WindowSaveLoadCmd, + 'Window Toggle' : WindowToggleCmd, +} +# use these when we rename a commandClass so that old Profiles will still load correctly. +# If we've also updated the class, we need to try to make sure the new class will still +# Deserialize the legacy data, or at least not crash. +deprecatedCommandClasses = { + 'SG Mode Toggle' : SGModeCmd, + 'Use Insp By Name' : UseInspByNameCmd, + 'Use Insp From Row/Column' : UseInspRowColCmd, +} +commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/WindowSaveLoadCmd.py b/UI/PowerBinderCommand/WindowSaveLoadCmd.py new file mode 100644 index 0000000..4c02ab7 --- /dev/null +++ b/UI/PowerBinderCommand/WindowSaveLoadCmd.py @@ -0,0 +1,1800 @@ +import wx +import re +import UI +import UI.EmotePicker +from UI.ControlGroup import ControlGroup +from UI.PowerPicker import PowerPicker +from Help import HelpButton +import wx.adv +from wx.adv import BitmapComboBox, EditableListBox +from pathlib import PureWindowsPath +import GameData +import Profile +from Icon import GetIcon + +class PowerBinderDialog(wx.Dialog): + def __init__(self, parent, button, init = {}): + wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) + + self.Page = parent.Page + self.EditDialog = PowerBinderEditDialog(self) + self.Button = button + self.AddStepMenu = self.makeAddStepMenu() + + sizer = wx.BoxSizer(wx.VERTICAL); + self.mainSizer = sizer + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) + # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) + # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) + #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) + AddStepButton = wx.Button(self, -1, 'Add Step') + AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) + AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) + choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) + choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) + sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) + + rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) + + self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) + self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) + self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) + rearrangeCtrl.Add(self.RearrangeList, 1) + + rearrangeButtons = wx.BoxSizer(wx.VERTICAL) + self.DelButton = wx.Button(self, -1, "Delete") + self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) + self.EditButton = wx.Button(self, -1, "Edit") + self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) + self.EditButton.Disable() + upButton = wx.Button(self, -1, "\u25B2") + upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) + downButton = wx.Button(self, -1, "\u25BC") + downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) + rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) + rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) + + sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.BindStringDisplay = wx.TextCtrl(self, -1) + self.BindStringDisplay.Disable() + choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, + wx.ALIGN_CENTER_VERTICAL) + choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) + + sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) + + sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) + + # need to dig around and get the OK button since we show this dialog modelessly now. + okButton = self.FindWindow(self.GetAffirmativeId()) + okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) + + # Wrap everything in a vbox to add some padding + vbox = wx.BoxSizer(wx.VERTICAL); + vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); + + self.SetSizerAndFit(vbox); + self.Layout() + self.Fit() + self.SetFocus() + + # if we are loading from profile, ie, have "init", build the list from it + if init: self.LoadFromData(init) + + def LoadFromData(self, init): + for item in init: + for type, data in item.items(): + commandClass = commandClasses.get(type, None) + if not commandClass: + commandClass = deprecatedCommandClasses.get(type, None) + if not commandClass: + wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") + continue + newCommand = commandClass(self.EditDialog, data) + index = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.SetClientData(index, newCommand) + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) + self.EditDialog.mainSizer.Hide(newCommand.UI) + self.UpdateBindStringDisplay() + + def SaveToData(self): + data = [] + index = 0 + for _ in self.RearrangeList.GetItems(): + # check whether we have an object already attached to this choice + cmdObject = self.RearrangeList.GetClientData(index) + commandClassName = commandRevClasses[type(cmdObject)] + data.append({commandClassName: cmdObject.Serialize()}) + index = index + 1 + return data + + def OnAddStepButton(self, evt): + button = evt.EventObject + if not self.AddStepMenu: + self.AddStepMenu = self.makeAddStepMenu() + button.PopupMenu(self.AddStepMenu) + + + def OnOKButton(self, _): + if self.Button.tgtTxtCtrl: + bindString = self.MakeBindString() + if bindString != self.Button.tgtTxtCtrl.GetValue(): + self.Button.tgtTxtCtrl.SetValue(bindString) + wx.App.Get().Main.Profile.SetModified() + self.Close() + + def OnRearrangeDelete(self, _): + current = self.RearrangeList.GetSelection() + if current == wx.NOT_FOUND: return + + self.RearrangeList.Delete(current) + self.UpdateBindStringDisplay() + + def OnRearrangeUp(self, _): + self.RearrangeList.MoveCurrentUp() + self.UpdateBindStringDisplay() + + def OnRearrangeDown(self, _): + self.RearrangeList.MoveCurrentDown() + self.UpdateBindStringDisplay() + + def OnRearrangeEdit(self, _): + index = self.RearrangeList.GetSelection() + + # check whether we have an object already attached to this choice + cmdObject = None + try: + cmdObject = self.RearrangeList.GetClientData(index) + except Exception: + pass + + if cmdObject: + self.ShowEditDialogFor(cmdObject) + self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) + else: + print("cmdObject was None") + self.UpdateBindStringDisplay() + + # OnAddStepMenu creates a new step and adds it to the rearrangelist + def OnAddStepMenu(self, evt): + menuitem = self.AddStepMenu.FindItemById(evt.GetId()) + chosenName = menuitem.GetItemLabel() + + # make a new command object, attached to the parent dialog + newCommandClass = commandClasses[chosenName] + newCommand = newCommandClass(self.EditDialog) + + # show the edit dialog if this command needs it + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) + if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): + self.EditDialog.mainSizer.Remove(newCommand.UI) + return + + newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.Select(newBindIndex) + self.RearrangeList.SetClientData(newBindIndex, newCommand) + + self.OnListSelect() + self.UpdateBindStringDisplay() + + def OnListSelect(self, _ = None): + selected = self.RearrangeList.GetSelection() + + if selected != wx.NOT_FOUND: + selCommand = self.RearrangeList.GetClientData(selected) + if selCommand.UI: + self.EditButton.Enable() + else: + self.EditButton.Disable() + + def UpdateBindStringDisplay(self): + self.BindStringDisplay.SetValue(self.MakeBindString()) + self.BindStringDisplay.SetToolTip(self.MakeBindString()) + + def MakeBindString(self): + cmdBindStrings = [] + for index in range(self.RearrangeList.GetCount()): + c = self.RearrangeList.GetClientData(index) + if c: cmdBindStrings.append(c.MakeBindString()) + + bindstring = ('$$'.join(cmdBindStrings)) + return bindstring + + def ShowEditDialogFor(self, command): + if not command.UI: return + + self.EditDialog.mainSizer.Show(command.UI) + + self.EditDialog.Layout() + self.EditDialog.Fit() + + self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') + returnval = self.EditDialog.ShowModal() + + self.EditDialog.mainSizer.Hide(command.UI) + + return returnval + + def makeAddStepMenu(self): + + stepMenu = wx.Menu() + + for subname in menuStructure: + submenu = wx.Menu() + stepMenu.AppendSubMenu(submenu, subname) + for classname in menuStructure[subname]: + submenu.Append(wx.ID_ANY, classname) + + stepMenu.Append(wx.ID_ANY, 'Custom Bind') + + return stepMenu + +class PowerBinderButton(wx.BitmapButton): + + def __init__(self, parent, tgtTxtCtrl, init = {}): + wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) + self.Init = init + self.Dialog = None + self.DialogParent = parent + + self.tgtTxtCtrl = tgtTxtCtrl + self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) + self.SetToolTip("Launch PowerBinder") + + def PowerBinderEventHandler(self, _): + self.PowerBinderDialog().Show() + + def LoadFromData(self, data): + self.PowerBinderDialog().LoadFromData(data) + + def SaveToData(self): + return self.PowerBinderDialog().SaveToData() + + def PowerBinderDialog(self): + if not self.Dialog: + self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) + return self.Dialog + + +class PowerBinderEditDialog(wx.Dialog): + def __init__(self, parent): + wx.Dialog.__init__(self, parent, -1, "Edit Step", + style = wx.DEFAULT_DIALOG_STYLE) + + outerSizer = wx.BoxSizer(wx.VERTICAL) + + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + self.mainSizer.SetMinSize([500, 150]) + + self.Page = parent.Page + + self.mainSizer.Add( + self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), + 0, wx.EXPAND|wx.ALL, 10) + + outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) + + self.SetSizerAndFit(outerSizer) + self.Layout() + self.Fit() + +########### Power Binder Command Objects +class PowerBindCmd(): + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + commandClassName = commandRevClasses[type(self)] + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{commandClassName} - {short_bindstr}" + + +####### Away From Keyboard +class AFKCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) + +####### Attribute Monitor +class AttributeMonitorCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.Groups = {} + self.AttributeTable = { + 'Base' : { + 'Current Hit Points' : 'NT H', + 'Max Hit Points' : 'X H', + 'Current Endurance' : 'T E', + 'Max Endurance' : 'X EN', + 'Regeneration Rate' : 'N RAT', + 'Recovery Rate' : 'Y RA', + 'Endurance Consumption' : 'SU', + 'ToHit Bonus' : 'T B', + 'Accuracy Bonus' : 'CC', + 'Last Hit Chance' : 'T C', + 'Damage Bonus' : 'DA', + 'Healing Bonus' : 'NG B', + 'Recharge Time Bonus' : 'ME B', + 'Endurance Discount' : 'CE DIS', + 'Stealth Radius (PvP)' : 'PVP', + 'Stealth Radius (PvE)' : 'PVE', + 'Perception Radius' : 'RC', + 'Range Bonus' : 'GE B', + 'Threat Level' : 'AT L', + 'Experience to Next Level' : 'XT', + 'Experience Debt' : 'XP', + 'Influence / Infamy' : 'INF', + 'Inherent' : 'NH', + }, + 'Movement Speed' : { + 'Flying Speed' : 'FL', + 'Jumping Speed' : 'PI', + 'Max Jump Height' : 'X J', + 'Run Speed' : 'RU', + }, + 'Damage Resistance' : { + 'Smashing Resistance' : 'G R', + 'Lethal Resistance' : 'L R', + 'Fire Resistance' : 'RE R', + 'Cold Resistance' : 'COLD R', + 'Energy Resistance' : 'DamageType[4]', + 'Negative Energy Resistance' : 'GY R', + 'Psyonic Resistance' : 'NIC R', + 'Toxic Resistance' : 'XIC R', + }, + 'Defense' : { + 'Base Defense' : 'BAS', + 'Ranged Defense' : 'ED', + 'Melee Defense' : 'MEL', + 'AoE Defense' : '2', + 'Smashing Defense' : '3', + 'Lethal Defense' : '4', + 'Fire Defense' : '5', + 'Cold Defense' : '6', + 'Energy Defense' : '7', + 'Negative Energy Defense' : '8', + 'Psionic Defense' : '9', + 'Toxic Defense' : '1', + }, + 'Debuff Resistance' : { + 'Regeneration Resistance' : 'ON R', + 'Recovery Resistance' : 'RY R', + 'To Hit Resistance' : 'IT R', + 'Defense Resistance' : 'NSE RES', + }, + 'Status Effect Protection' : { + 'Hold Protection' : 'D P', + 'Immobilize Protection' : 'LIZE P', + 'Stun Protection' : 'N P', + 'Sleep Protection' : 'P P', + 'Knockback Protection' : 'K P', + 'Confuse Protection' : 'SE P', + 'Terrorize Protection' : 'ZE P', + 'Repel Protection' : 'EL P', + 'Teleport Protection' : 'T P', + }, + 'Status Effect Resistance' : { + 'Hold Resistance' : 'D R', + 'Immobilize Resistance' : 'LIZE R', + 'Stun Resistance' : 'N R', + 'Sleep Resistance' : 'P R', + 'Knockback Resistance' : 'K R', + 'Confuse Resistance' : 'SE R', + 'Terrorize Resistance' : 'ZE R', + 'Placate Resistance' : 'TE R', + 'Taunt Resistance' : 'NT R', + }, + 'Miscellaneous' : { + 'Level Shift' : 'L S', + }, + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.AttributeMenu = wx.Menu() + for group, controls in self.AttributeTable.items(): + submenu = wx.Menu() + self.AttributeMenu.AppendSubMenu(submenu, group) + for cb in controls: + submenu.Append(wx.ID_ANY, cb) + + self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) + + self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) + groupSizer.Add(self.editbox) + + newButton = self.editbox.GetNewButton() + newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) + + return groupSizer + + def MakeBindString(self): + map = {} + bindstrings = [] + for _, controls in self.AttributeTable.items(): + for cb, data in controls.items(): + map[cb] = data + + for string in self.editbox.GetStrings(): + if string: + bindstrings.append(f'monitorattribute {map[string]}') + + return '$$'.join(bindstrings) + + def Serialize(self): + return { + 'attributes' : self.editbox.GetStrings() + } + + def Deserialize(self, init): + self.editbox.SetStrings(init.get('attributes', [])) + + def OnNewButton(self, evt): + evt.GetEventObject().PopupMenu(self.AttributeMenu) + + def OnMenuItem(self, evt): + menuitem = evt.EventObject.FindItemById(evt.GetId()) + existingstrings = self.editbox.GetStrings() + existingstrings.append(menuitem.GetItemLabel()) + self.editbox.SetStrings(existingstrings) + +####### Auto Power +class AutoPowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) + autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.autoPowerName = PowerPicker(dialog) + autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) + + return autoPowerSizer + + def MakeBindString(self): + return f"powexecauto {self.autoPowerName.GetLabel()}" + + def Serialize(self): + return { + 'pname' : self.autoPowerName.GetLabel(), + 'picon' : self.autoPowerName.IconFilename + } + + def Deserialize(self, init): + if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) + +####### Buff Display Command +class BuffDisplayCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.buffDisplayMap = { + 'Status Window' : { + 'Hide Auto' : 1, + 'Hide Toggles' : 2, + 'No Blinking' : 4, + 'No Stacking' : 8, + 'Numeric Stacking' : 16, + 'Hide Buff Numbers' : 32, + 'Stop Sending Buffs' : 64, + }, + 'Group Window' : { + 'Hide Auto' : 256, + 'Hide Toggles' : 512, + 'No Blinking' : 1024, + 'No Stacking' : 2048, + 'Numeric Stacking' : 4096, + 'Hide Buff Numbers' : 8192, + 'Stop Sending Buffs' : 16384, + }, + 'Pet Window' : { + 'Hide Auto' : 65536, + 'Hide Toggles' : 131072, + 'No Blinking' : 262144, + 'No Stacking' : 524288, + 'Numeric Stacking' : 1048576, + 'Hide Buff Numbers' : 2097152, + 'Stop Sending Buffs' : 4194304, + }, + } + self.Groups = {} + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + for group, controls in self.buffDisplayMap.items(): + self.Groups[group] = ControlGroup(dialog, self.Page, label = group) + groupid = self.Groups[group].GetStaticBox().GetId() + for cb, data in controls.items(): + self.Groups[group].AddControl( + ctlType = 'checkbox', + ctlName = f"{groupid}_{group}_{cb}", + label = cb, + data = data, + ) + + groupSizer.Add(self.Groups[group]) + + return groupSizer + + def CalculateValue(self): + page = wx.App.Get().Main.Profile.CustomBinds + + total = 0 + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] + if checkbox.IsChecked(): + total = total + checkbox.Data + return total + + def MakeBindString(self): + return f"optionset buffsettings {self.CalculateValue()}" + + def Serialize(self): + return { 'value' : self.CalculateValue() } + + def Deserialize(self, init): + value = init.get('value', 0) + + value = value or 0 # in case we had for some reason 'None' stashed in the init values + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] + checkbox.SetValue( checkbox.Data & value ) + +####### Chat Command +class ChatCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.chatChannelMap = { # before __init__ + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + chatCommandSizer = wx.GridBagSizer(5, 5) + self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") + chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) + # row 1 + self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) + self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) + self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) + # row 2 + self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) + self.chatCommandDuration.SetRange(1, 20) + self.chatCommandDuration.SetValue(7) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandDuration, (2,1)) + self.chatCommandChatSize = wx.Choice(dialog, -1, + choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) + self.chatCommandChatSize.SetSelection(5) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) + self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) + self.chatCommandChannel.SetSelection(0) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChannel, (2,5)) + # row 3 + self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") + chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) + self.chatCommandMessage = wx.TextCtrl(dialog, -1) + self.chatCommandMessage.SetHint('Chat Command Text') + chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) + + return chatCommandSizer + + def MakeBindString(self): + duration = self.chatCommandDuration.GetValue() + + choice = self.chatCommandChatSize + index = choice.GetSelection() + size = choice.GetString(index) + + duration = f"" if duration != 7 else "" + size = f"" if size != "1" else "" + + bdcolor = fgcolor = bgcolor = '' + if self.chatCommandUseColorsCB.IsChecked(): + bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + + bdcolor = f"" + fgcolor = f"" + bgcolor = f"" + + beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' + text = self.chatCommandMessage.GetValue() + + choice = self.chatCommandChannel + index = choice.GetSelection() + channel = choice.GetString(index) + + return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" + + def Serialize(self): + return { + 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), + 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), + 'channel' : self.chatCommandChannel .GetSelection(), + 'size' : self.chatCommandChatSize.GetSelection(), + 'duration' : self.chatCommandDuration.GetValue(), + 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'text' : self.chatCommandMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) + if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) + if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) + if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) + if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) + if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) + if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) + if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) + if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) + + +####### Chat Command Global +class ChatGlobalCmd(PowerBindCmd): + def BuildUI(self, dialog): + chatCommandGlobalSizer = wx.GridBagSizer(5,5) + + self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") + chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) + + self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalChannel.SetHint("Channel") + chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) + + self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') + chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) + + chatCommandGlobalSizer.AddGrowableCol(1) + + return chatCommandGlobalSizer + + def MakeBindString(self): + useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() + channel = self.chatCommandGlobalChannel.GetValue() + message = self.chatCommandGlobalMessage.GetValue() + + preface = "beginchat /" if useBeginchat else "" + + return f'{preface}send "{channel}" {message}' + + def Serialize(self): + return { + 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), + 'channel' : self.chatCommandGlobalChannel.GetValue(), + 'message' : self.chatCommandGlobalMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) + if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) + if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) + +#######Costume Change +class CostumeChangeCmd(PowerBindCmd): + def BuildUI(self, dialog): + costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeCostume = wx.Choice(dialog, -1, + choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) + self.costumeChangeCostume.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeEmote = wx.Choice(dialog, -1, + choices = GameData.Emotes['costumechange']) + self.costumeChangeEmote.Insert("- None -", 0) + self.costumeChangeEmote.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return costumeChangeSizer + + def MakeBindString(self): + costumeNumber = self.costumeChangeCostume.GetSelection() + costumeEmote = self.costumeChangeEmote.GetSelection() + + if costumeEmote: # None, or 0 == "- None -" + ccCmd = 'cce' + emoteName = self.costumeChangeEmote.GetString(costumeEmote) + emoteName = " CC" + emoteName.replace(" ","") + else: + ccCmd = 'cc' + emoteName = '' + + return f"{ccCmd} {costumeNumber}{emoteName}" + + def Serialize(self): + return{ + 'costumeNumber': self.costumeChangeCostume.GetSelection(), + 'costumeEmote' : self.costumeChangeEmote.GetSelection(), + } + + def Deserialize(self, init): + if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) + if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) + +####### Movement Command +class MovementCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + self.plusbutton.SetValue(True) + + self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.commandchoice = wx.Choice(dialog, choices = [ + "forward", "left", "right", "backward", "up", "down", + "turnleft", "turnright", "first", "autorun", "clicktomove", + ],) + sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) + self.commandchoice.SetSelection(0) + + self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + pre = post = '' + if self.plusbutton.GetValue() : pre = "+" + elif self.plusplusbutton.GetValue() : pre = "++" + elif self.minusbutton.GetValue() : pre = "-" + elif self.zerobutton.GetValue() : post = " 0" + elif self.onebutton.GetValue() : post = " 1" + + command = self.commandchoice.GetString(self.commandchoice.GetSelection()) + + return f"{pre}{command}{post}" + + def Serialize(self): + mod = '' + if self.plusbutton.GetValue() : mod = "plus" + elif self.plusplusbutton.GetValue() : mod = "plusplus" + elif self.minusbutton.GetValue() : mod = "minus" + elif self.zerobutton.GetValue() : mod = "zero" + elif self.onebutton.GetValue() : mod = "one" + + return { + 'mod' : mod, + 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), + } + + def Deserialize(self, init): + mod = init.get('mod', 'plus') + + if mod == 'plus' : self.plusbutton.SetValue(True) + elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) + elif mod == 'minus' : self.minusbutton.SetValue(True) + elif mod == 'zero' : self.zerobutton.SetValue(True) + elif mod == 'one' : self.onebutton.SetValue(True) + + self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) + +####### Graphics Command +class GraphicsCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.FlexGridSizer(2) + + self.visscalecb = wx.CheckBox(dialog, label = "visscale") + sizer.Add(self.visscalecb) + self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) + sizer.Add(self.visscalesc) + + self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") + sizer.Add(self.dofweightcb) + self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) + sizer.Add(self.dofweightsc) + + self.fsaacb = wx.CheckBox(dialog, label = "fsaa") + sizer.Add(self.fsaacb) + self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) + self.fsaach.SetSelection(0) + sizer.Add(self.fsaach) + + self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") + sizer.Add(self.bloomscalecb) + self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) + self.bloomscalech.SetSelection(0) + sizer.Add(self.bloomscalech) + + self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") + sizer.Add(self.bloomweightcb) + self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) + sizer.Add(self.bloomweightsc) + + self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") + sizer.Add(self.lodbiascb) + self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) + sizer.Add(self.lodbiassc) + + self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") + sizer.Add(self.renderscalecb) + self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) + sizer.Add(self.renderscalesc) + + return sizer + + def MakeBindString(self): + # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. + bindstrings = [] + if self.visscalecb.IsChecked(): + bindstrings.append("visscale " + str(self.visscalesc.GetValue())) + if self.dofweightcb.IsChecked(): + bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) + if self.fsaacb.IsChecked(): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bindstrings.append("fsaa " + fsaavalue) + if self.bloomscalecb.IsChecked(): + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + bindstrings.append("bloomscale " + bloomscalevalue) + if self.bloomweightcb.IsChecked(): + bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) + if self.lodbiascb.IsChecked(): + bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) + if self.renderscalecb.IsChecked(): + bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) + + return '$$'.join(bindstrings) + + def Serialize(self): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + return { + 'visscalecb' : self.visscalecb.IsChecked(), + 'visscalesc' : self.visscalesc.GetValue(), + 'dofweightcb' : self.dofweightcb.IsChecked(), + 'dofweightsc' : self.dofweightsc.GetValue(), + 'fsaacb' : self.fsaacb.IsChecked(), + 'fsaach' : fsaavalue, + 'bloomscalecb' : self.bloomscalecb.IsChecked(), + 'bloomscalech' : bloomscalevalue, + 'bloomweightcb' : self.bloomweightcb.IsChecked(), + 'bloomweightsc' : self.bloomweightsc.GetValue(), + 'lodbiascb' : self.lodbiascb.IsChecked(), + 'lodbiassc' : self.lodbiassc.GetValue(), + 'renderscalecb' : self.renderscalecb.IsChecked(), + 'renderscalesc' : self.renderscalesc.GetValue(), + } + + def Deserialize(self, init): + self.visscalecb.SetValue(init.get('visscalecb', False)) + self.visscalesc.SetValue(init.get('visscalesc', 1.0)) + self.dofweightcb.SetValue(init.get('dofweightcb', False)) + self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) + self.fsaacb.SetValue(init.get('fsaacb', False)) + self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) + self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) + self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) + self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) + self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) + self.lodbiascb.SetValue(init.get('lodbiascb', False)) + self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) + self.renderscalecb.SetValue(init.get('renderscalecb', False)) + self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) + +####### Custom Bind +class CustomBindCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.customBindName = wx.TextCtrl(dialog, -1) + self.customBindName.SetHint('Custom Bind Text') + sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + return self.customBindName.GetValue() + + def Serialize(self): + return { 'customBindName': self.customBindName.GetValue() } + + def Deserialize(self,init): + if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) + +####### Emote +class EmoteCmd(PowerBindCmd): + def BuildUI(self, dialog): + emoteSizer = wx.BoxSizer(wx.HORIZONTAL) + self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") + emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + self.emoteName = wx.Button(dialog, -1, "...") + self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) + emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) + + return emoteSizer + + def MakeBindString(self): + displayedEmoteName = self.emoteName.GetLabel() + actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] + + return actualEmotePayload + + def Serialize(self): + return {'emoteName': self.emoteName.GetLabel()} + + def Deserialize(self, init): + if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) + +####### Load Binds Directory +class LoadBindsDir(PowerBindCmd): + def BuildUI(self, dialog): + mainSizer = wx.BoxSizer(wx.VERTICAL) + + lbSizer = wx.BoxSizer(wx.HORIZONTAL) + lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") + lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + profiles = Profile.GetAllProfileBindsDirs() + + self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) + lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") + self.lbResetCB.SetValue(True) + + mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + return mainSizer + + def MakeBindString(self): + + # If the specified binds directory disappeared between runs, we'd crash, so handle that. + if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' + + config = wx.ConfigBase.Get() + if config.Exists('GameBindPath'): + bindpath = config.Read('GameBindPath') + else: + bindpath = config.Read('BindPath') + + reset = "" + if self.lbResetCB.GetValue(): + reset = "keybind_reset$$" + + resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' + return reset + 'bindloadfile ' + str(resetfilepath) + + def Serialize(self): + return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), + 'ResetKeybinds' : self.lbResetCB.GetValue(), + } + + def Deserialize(self, init): + if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) + self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) + +####### Power Abort +class PowerAbortCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecabort' + +####### Power Unqueue +class PowerUnqueueCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecunqueue' + +####### SG Mode +class SGModeCmd(PowerBindCmd): + def BuildUI(self, dialog): + sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) + sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") + self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") + + sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) + + return sgmodeSizer + + def MakeBindString(self): + if self.sgmodeOnRB.GetValue(): + return 'sgmodeset 1' + elif self.sgmodeOffRB.GetValue(): + return 'sgmodeset 0' + else: + return 'sgmode' + + def Serialize(self): + if self.sgmodeOnRB.GetValue(): + val = "On" + elif self.sgmodeOffRB.GetValue(): + val = "Off" + else: + val = "Toggle" + + return {"value" : val} + + def Deserialize(self, init): + val = init.get('value', '') + if val == "On": + self.sgmodeOnRB.SetValue(True) + elif val == "Off": + self.sgmodeOffRB.SetValue(True) + else: + self.sgmodeToggleRB.SetValue(True) + +####### Target Custom +class TargetCustomCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetCustomSizer = wx.GridBagSizer(5,5) + targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), + flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) + self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetCustomModeChoice.SetSelection(0) + targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) + self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) + self.targetCustomOptionalName.SetHint("Optional name to match") + targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) + self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") + targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) + self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") + targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) + self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") + targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) + self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") + targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) + self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") + targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) + self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") + targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) + self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") + targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) + self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") + targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) + + targetCustomSizer.AddGrowableCol(2) + + return targetCustomSizer + + def MakeBindString(self): + choice = self.targetCustomModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + targetCommand = "targetcustom" + mode.lower() + + enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" + friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" + defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" + alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" + mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" + notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" + base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" + notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" + + name = self.targetCustomOptionalName.GetValue() + + return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" + + def Serialize(self): + return { + 'mode' : self.targetCustomModeChoice.GetSelection(), + 'enemy' : self.targetCustomCBEnemies. IsChecked(), + 'friend' : self.targetCustomCBFriends. IsChecked(), + 'defeated' : self.targetCustomCBDefeated. IsChecked(), + 'alive' : self.targetCustomCBAlive. IsChecked(), + 'mypet' : self.targetCustomCBMyPets. IsChecked(), + 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), + 'base' : self.targetCustomCBBaseItems. IsChecked(), + 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), + 'name' : self.targetCustomOptionalName.GetValue(), + } + + def Deserialize(self, init): + if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) + if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) + if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) + if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) + if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) + if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) + if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) + if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) + if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) + if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) + + +####### Target Enemy +class TargetEnemyCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) + targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetEnemyModeChoice.SetSelection(0) + targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetEnemySizer + + def MakeBindString(self): + choice = self.targetEnemyModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetenemy" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetEnemyModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) + +####### Target Friend +class TargetFriendCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) + targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetFriendModeChoice.SetSelection(0) + targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetFriendSizer + + def MakeBindString(self): + choice = self.targetFriendModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetfriend" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetFriendModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) + +####### Team/Pet Select +class TeamPetSelectCmd(PowerBindCmd): + def BuildUI(self, dialog): + teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], + style=wx.ALIGN_CENTER_VERTICAL) + self.teamPetSelectNumber.SetSelection(0) + teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) + + return teamPetSelectSizer + + def MakeBindString(self): + teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' + targetNumber = self.teamPetSelectNumber.GetSelection()+1 + + return f"{teamOrPet}select {targetNumber}" + + def Serialize(self): + return { + 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', + 'targetNum': self.teamPetSelectNumber.GetSelection(), + } + + def Deserialize(self, init): + ToP = init.get('teamOrPet', '') + if ToP == 'pet': + self.teamPetSelectPetRB.SetValue(True) + else: + self.teamPetSelectTeamRB.SetValue(True) + if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) + +####### Unselect +class UnselectCmd(PowerBindCmd): + def MakeBindString(self): + return 'unselect' + +####### Use Insp By Name +class UseInspByNameCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) + for _, types in GameData.Inspirations.items(): + for _, info in types.items(): + for insp in info['tiers']: + name = re.sub(' ', '', str(insp)) + icon = GetIcon(f'Inspirations/{name}') + self.useInspByNameModeChoice.Append(insp, icon) + self.useInspByNameModeChoice.SetSelection(0) + useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) + + return useInspByNameSizer + + def MakeBindString(self): + choice = self.useInspByNameModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "inspexecname " + mode.lower() + + def GetAllInsps(self): + Insplist = [] + for _, info in GameData.Inspirations.items(): + for insp in info['tiers']: + Insplist.append(insp) + Insplist.append("---") + Insplist.pop(-1) # snip the terminal "---" + + return Insplist + + def Serialize(self): + return { 'insp' : self.useInspByNameModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) + +####### Use Insp From Row / Column +class UseInspRowColCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnRow.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) + self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnCol.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) + + return useInspRowColumnSizer + + def MakeBindString(self): + row = self.useInspRowColumnRow.GetSelection()+1 + col = self.useInspRowColumnCol.GetSelection()+1 + + return f"inspexectray {col} {row}" + + def Serialize(self): + return { + 'col' : self.useInspRowColumnCol.GetSelection(), + 'row' : self.useInspRowColumnRow.GetSelection(), + } + + def Deserialize(self, init): + if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) + if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) + +####### Use Power +class UsePowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + outerSizer = wx.BoxSizer(wx.HORIZONTAL) + + usePowerSizer = wx.GridBagSizer(5,5) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBToggle, (0,1)) + self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOn, (0,2)) + self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOff, (0,3)) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerName = PowerPicker(dialog) + usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) + usePowerSizer.AddGrowableCol(3) + + outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) + + return outerSizer + + def MakeBindString(self): + if self.usePowerRBToggle.GetValue(): + method = "powexecname" + elif self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') + return '' + + return f"{method} {self.usePowerName.GetLabel()}" + + def Serialize(self): + if self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + method = "powexecname" + return { + 'method': method, + 'pname' : self.usePowerName.GetLabel(), + 'picon' : self.usePowerName.IconFilename + } + + def Deserialize(self, init): + method = init.get('method', '') + if method == 'powexectoggleon': + self.usePowerRBOn.SetValue(True) + elif method == 'powexectoggleoff': + self.usePowerRBOff.SetValue(True) + else: + self.usePowerRBToggle.SetValue(True) + if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) + +####### Use Power From Tray +class UsePowerFromTrayCmd(PowerBindCmd): + def BuildUI(self, dialog): + usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTrayTray = wx.Choice(dialog, -1, + choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', + 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) + self.usePowerFromTrayTray.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) + self.usePowerFromTraySlot.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return usePowerFromTraySizer + + def MakeBindString(self): + choice = self.usePowerFromTrayTray + tray = choice.GetSelection() + + choice = self.usePowerFromTraySlot + slot = choice.GetSelection()+1 + + mode = "slot" + mode2 = '' + if tray > 3: + mode = "tray" + mode2 = f" {tray - 3}" + elif tray == 3: + mode = "alt2slot" + elif tray == 2: + mode = "altslot" + + return f"powexec{mode} {slot}{mode2}" + + def Serialize(self): + return { + 'tray' : self.usePowerFromTrayTray.GetSelection(), + 'slot' : self.usePowerFromTraySlot.GetSelection(), + } + + def Deserialize(self, init): + if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) + if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) + +####### Window Color +class WindowColorCmd(PowerBindCmd): + def BuildUI(self, dialog): + windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) + borderSizer = wx.BoxSizer(wx.VERTICAL) + self.ColorBorder.SetSizer(borderSizer) + self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) + borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) + + windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) + + RGBASizer = wx.FlexGridSizer(3, 4, 5) + + RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) + self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) + self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + windowColorSizer.Add(RGBASizer) + + self.UpdateFromSlider() + + return windowColorSizer + + def MakeBindString(self): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + return f"windowcolor {Rval} {Gval} {Bval} {Aval}" + + def Serialize(self): + return { + 'Rval' : self.RSlider.GetValue(), + 'Gval' : self.GSlider.GetValue(), + 'Bval' : self.BSlider.GetValue(), + 'Aval' : self.ASlider.GetValue(), + } + + def Deserialize(self, init): + self.RSlider.SetValue(init['Rval']) + self.GSlider.SetValue(init['Gval']) + self.BSlider.SetValue(init['Bval']) + self.ASlider.SetValue(init['Aval']) + self.UpdateFromSlider() + + def UpdateFromSlider(self, _ = None): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RReadout.SetValue(Rval) + self.GReadout.SetValue(Gval) + self.BReadout.SetValue(Bval) + self.AReadout.SetValue(Aval) + self.ColorBorder.Refresh() + + def UpdateFromText(self, _ = None): + Rval = self.RReadout.GetValue() + Gval = self.GReadout.GetValue() + Bval = self.BReadout.GetValue() + Aval = self.AReadout.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RSlider.SetValue(Rval) + self.GSlider.SetValue(Gval) + self.BSlider.SetValue(Bval) + self.ASlider.SetValue(Aval) + self.ColorBorder.Refresh() + +####### Window Save / Load +class WindowSaveLoadCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) + self.CommandChoice.SetSelection(0) + sizer.Add(self.CommandChoice, 0, wx.ALL, 5) + + self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), + value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) + sizer.Add(self.FilePath, 0, wx.ALL, 5) + + return sizer + + def MakeBindString(self): + command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] + return f'{command} "{self.FilePath.GetValue()}"' + + def Serialize(self): + return { + 'command' : self.CommandChoice.GetSelection(), + 'filename' : self.FilePath.GetValue(), + } + + def Deserialize(self, init): + self.CommandChoice.SetSelection(init.get('command', 0)) + self.FilePath.SetValue(init.get('filename', '')) + +####### Window Toggle +class WindowToggleCmd(PowerBindCmd): + def BuildUI(self, dialog): + self.WindowNames = { + 'Actions' : 'actions', + 'Auction House' : 'ah', + 'Badge' : 'badge', + 'Channel Search' : 'chansearch', + 'Chat' : 'chat', + 'Custom Chat 1' : 'chat1', + 'Custom Chat 2' : 'chat2', + 'Custom Chat 3' : 'chat3', + 'Custom Chat 4' : 'chat4', + 'Clues' : 'clue', + 'Combat Numbers' : 'combatnumbers', + 'Contacts' : 'contact', + 'Contact Finder' : 'contactfinder', + 'Costumes' : 'costume', + 'Email' : 'email', + 'Enhancements' : 'enhancements', + 'Friends' : 'friend', + 'Group' : 'group', + 'Help' : 'helpwindow', + 'Incarnate' : 'incarnate', + 'Inspirations' : 'insp', + 'League' : 'league', + 'LFG' : 'lfg', + 'Map' : 'map', + 'Mission' : 'mission', + 'Nav / Compass' : 'nav', + 'Options' : 'options', + 'Pets' : 'pet', + 'Petition' : 'petition', + 'Power Tray' : 'powers', + 'Power List' : 'powerlist', + 'Quit' : 'quit', + 'Recipes' : 'recipe', + 'Salvage' : 'salvage', + 'Search' : 'search', + 'Supergroup' : 'sg', + 'Target' : 'target', + 'Team' : 'team', + 'Tray' : 'tray', + 'Tray1' : 'tray1', + 'Tray2' : 'tray2', + 'Tray3' : 'tray3', + 'Tray4' : 'tray4', + 'Tray5' : 'tray5', + 'Tray6' : 'tray6', + 'Tray7' : 'tray7', + 'Tray8' : 'tray8', + 'Vault' : 'vault', + } + + self.ShortToggleCommands = { + 'Auction House' : 'ah', + 'Chat' : 'chat', + 'Help' : 'helpwindow', + 'Map' : 'map', + 'Nav / Compass' : 'nav', + 'Power Tray' : 'powers', + 'Target' : 'target', + 'Tray' : 'tray', + } + + windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) + windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) + self.windowToggleTray.SetSelection(0) + windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.windowShowRB = wx.RadioButton(dialog, -1, "Show") + self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") + + windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) + + return windowToggleSizer + + def MakeBindString(self): + choice = self.windowToggleTray + index = choice.GetSelection() + windowdesc = choice.GetString(index) + windowname = self.WindowNames[windowdesc] + + if self.windowShowRB.GetValue(): + return 'show ' + windowname + elif self.windowHideRB.GetValue(): + return 'windowhide ' + windowname + else: + if shortcmd := self.ShortToggleCommands.get(windowdesc, None): + return shortcmd + else: + return 'toggle ' + windowname + + + def Serialize(self): + choice = self.windowToggleTray + if self.windowShowRB.GetValue(): + action = "Show" + elif self.windowHideRB.GetValue(): + action = "Hide" + else: + action = "Toggle" + return { + 'window': choice.GetString(choice.GetSelection()), + 'action': action, + } + + def Deserialize(self, init): + choice = self.windowToggleTray + if window := init.get('window', ''): + if isinstance(window, int): + choice.SetSelection(window) + else: + choice.SetSelection(choice.FindString(window)) + + if choice.GetSelection() == wx.NOT_FOUND: + choice.SetSelection(0) + + action = init.get('action', '') + if action == "Show": + self.windowShowRB.SetValue(True) + elif action == "Hide": + self.windowHideRB.SetValue(True) + else: + self.windowToggleRB.SetValue(True) + + +# Must always add to this list when adding a new command class above +menuStructure = { + 'Graphics / UI' : [ + 'Attribute Monitor', + 'Buff Display Settings', + 'Graphics Settings', + 'Window Color', + 'Window Save / Load', + 'Window Toggle', + ], + 'Inspirations' : [ + 'Use Inspiration By Name', + 'Use Inspiration From Row/Column', + ], + 'Powers' : [ + 'Auto Power', + 'Power Abort', + 'Power Unqueue', + 'Use Power', + 'Use Power From Tray', + ], + 'Social' : [ + 'Away From Keyboard', + 'Chat Command', + 'Chat Command (Global)', + 'Costume Change', + 'Emote', + 'Supergroup Mode', + ], + 'Targeting' : [ + 'Target Custom', + 'Target Enemy', + 'Target Frield', + 'Team/Pet Select', + 'Unselect', + ], + 'Misc' : [ + 'Load Binds Directory', + 'Movement Commands', + ], + # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, + # but I'm leaving it here to remind myself that we do that. + } + +# Must always add to this list when adding a new command class above +commandClasses = { + 'Auto Power' : AutoPowerCmd, + 'Away From Keyboard' : AFKCmd, + 'Attribute Monitor' : AttributeMonitorCmd, + 'Buff Display Settings' : BuffDisplayCmd, + 'Chat Command' : ChatCmd, + 'Chat Command (Global)' : ChatGlobalCmd, + 'Costume Change' : CostumeChangeCmd, + 'Custom Bind' : CustomBindCmd, + 'Emote' : EmoteCmd, + 'Graphics Settings' : GraphicsCmd, + 'Load Binds Directory' : LoadBindsDir, + 'Movement Commands' : MovementCmd, + 'Power Abort' : PowerAbortCmd, + 'Power Unqueue' : PowerUnqueueCmd, + 'Supergroup Mode' : SGModeCmd, + 'Target Custom' : TargetCustomCmd, + 'Target Enemy' : TargetEnemyCmd, + 'Target Friend' : TargetFriendCmd, + 'Team/Pet Select' : TeamPetSelectCmd, + 'Unselect' : UnselectCmd, + 'Use Inspiration By Name' : UseInspByNameCmd, + 'Use Inspiration From Row/Column' : UseInspRowColCmd, + 'Use Power' : UsePowerCmd, + 'Use Power From Tray' : UsePowerFromTrayCmd, + 'Window Color' : WindowColorCmd, + 'Window Save / Load' : WindowSaveLoadCmd, + 'Window Toggle' : WindowToggleCmd, +} +# use these when we rename a commandClass so that old Profiles will still load correctly. +# If we've also updated the class, we need to try to make sure the new class will still +# Deserialize the legacy data, or at least not crash. +deprecatedCommandClasses = { + 'SG Mode Toggle' : SGModeCmd, + 'Use Insp By Name' : UseInspByNameCmd, + 'Use Insp From Row/Column' : UseInspRowColCmd, +} +commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/WindowToggleCmd.py b/UI/PowerBinderCommand/WindowToggleCmd.py new file mode 100644 index 0000000..4c02ab7 --- /dev/null +++ b/UI/PowerBinderCommand/WindowToggleCmd.py @@ -0,0 +1,1800 @@ +import wx +import re +import UI +import UI.EmotePicker +from UI.ControlGroup import ControlGroup +from UI.PowerPicker import PowerPicker +from Help import HelpButton +import wx.adv +from wx.adv import BitmapComboBox, EditableListBox +from pathlib import PureWindowsPath +import GameData +import Profile +from Icon import GetIcon + +class PowerBinderDialog(wx.Dialog): + def __init__(self, parent, button, init = {}): + wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) + + self.Page = parent.Page + self.EditDialog = PowerBinderEditDialog(self) + self.Button = button + self.AddStepMenu = self.makeAddStepMenu() + + sizer = wx.BoxSizer(wx.VERTICAL); + self.mainSizer = sizer + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) + # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) + # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) + #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) + AddStepButton = wx.Button(self, -1, 'Add Step') + AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) + AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) + choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) + choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) + sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) + + rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) + + self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) + self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) + self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) + rearrangeCtrl.Add(self.RearrangeList, 1) + + rearrangeButtons = wx.BoxSizer(wx.VERTICAL) + self.DelButton = wx.Button(self, -1, "Delete") + self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) + self.EditButton = wx.Button(self, -1, "Edit") + self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) + self.EditButton.Disable() + upButton = wx.Button(self, -1, "\u25B2") + upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) + downButton = wx.Button(self, -1, "\u25BC") + downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) + rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) + rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) + rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) + + sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) + + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.BindStringDisplay = wx.TextCtrl(self, -1) + self.BindStringDisplay.Disable() + choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, + wx.ALIGN_CENTER_VERTICAL) + choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) + + sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) + + sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) + + # need to dig around and get the OK button since we show this dialog modelessly now. + okButton = self.FindWindow(self.GetAffirmativeId()) + okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) + + # Wrap everything in a vbox to add some padding + vbox = wx.BoxSizer(wx.VERTICAL); + vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); + + self.SetSizerAndFit(vbox); + self.Layout() + self.Fit() + self.SetFocus() + + # if we are loading from profile, ie, have "init", build the list from it + if init: self.LoadFromData(init) + + def LoadFromData(self, init): + for item in init: + for type, data in item.items(): + commandClass = commandClasses.get(type, None) + if not commandClass: + commandClass = deprecatedCommandClasses.get(type, None) + if not commandClass: + wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") + continue + newCommand = commandClass(self.EditDialog, data) + index = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.SetClientData(index, newCommand) + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) + self.EditDialog.mainSizer.Hide(newCommand.UI) + self.UpdateBindStringDisplay() + + def SaveToData(self): + data = [] + index = 0 + for _ in self.RearrangeList.GetItems(): + # check whether we have an object already attached to this choice + cmdObject = self.RearrangeList.GetClientData(index) + commandClassName = commandRevClasses[type(cmdObject)] + data.append({commandClassName: cmdObject.Serialize()}) + index = index + 1 + return data + + def OnAddStepButton(self, evt): + button = evt.EventObject + if not self.AddStepMenu: + self.AddStepMenu = self.makeAddStepMenu() + button.PopupMenu(self.AddStepMenu) + + + def OnOKButton(self, _): + if self.Button.tgtTxtCtrl: + bindString = self.MakeBindString() + if bindString != self.Button.tgtTxtCtrl.GetValue(): + self.Button.tgtTxtCtrl.SetValue(bindString) + wx.App.Get().Main.Profile.SetModified() + self.Close() + + def OnRearrangeDelete(self, _): + current = self.RearrangeList.GetSelection() + if current == wx.NOT_FOUND: return + + self.RearrangeList.Delete(current) + self.UpdateBindStringDisplay() + + def OnRearrangeUp(self, _): + self.RearrangeList.MoveCurrentUp() + self.UpdateBindStringDisplay() + + def OnRearrangeDown(self, _): + self.RearrangeList.MoveCurrentDown() + self.UpdateBindStringDisplay() + + def OnRearrangeEdit(self, _): + index = self.RearrangeList.GetSelection() + + # check whether we have an object already attached to this choice + cmdObject = None + try: + cmdObject = self.RearrangeList.GetClientData(index) + except Exception: + pass + + if cmdObject: + self.ShowEditDialogFor(cmdObject) + self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) + else: + print("cmdObject was None") + self.UpdateBindStringDisplay() + + # OnAddStepMenu creates a new step and adds it to the rearrangelist + def OnAddStepMenu(self, evt): + menuitem = self.AddStepMenu.FindItemById(evt.GetId()) + chosenName = menuitem.GetItemLabel() + + # make a new command object, attached to the parent dialog + newCommandClass = commandClasses[chosenName] + newCommand = newCommandClass(self.EditDialog) + + # show the edit dialog if this command needs it + if newCommand.UI: + self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) + if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): + self.EditDialog.mainSizer.Remove(newCommand.UI) + return + + newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) + self.RearrangeList.Select(newBindIndex) + self.RearrangeList.SetClientData(newBindIndex, newCommand) + + self.OnListSelect() + self.UpdateBindStringDisplay() + + def OnListSelect(self, _ = None): + selected = self.RearrangeList.GetSelection() + + if selected != wx.NOT_FOUND: + selCommand = self.RearrangeList.GetClientData(selected) + if selCommand.UI: + self.EditButton.Enable() + else: + self.EditButton.Disable() + + def UpdateBindStringDisplay(self): + self.BindStringDisplay.SetValue(self.MakeBindString()) + self.BindStringDisplay.SetToolTip(self.MakeBindString()) + + def MakeBindString(self): + cmdBindStrings = [] + for index in range(self.RearrangeList.GetCount()): + c = self.RearrangeList.GetClientData(index) + if c: cmdBindStrings.append(c.MakeBindString()) + + bindstring = ('$$'.join(cmdBindStrings)) + return bindstring + + def ShowEditDialogFor(self, command): + if not command.UI: return + + self.EditDialog.mainSizer.Show(command.UI) + + self.EditDialog.Layout() + self.EditDialog.Fit() + + self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') + returnval = self.EditDialog.ShowModal() + + self.EditDialog.mainSizer.Hide(command.UI) + + return returnval + + def makeAddStepMenu(self): + + stepMenu = wx.Menu() + + for subname in menuStructure: + submenu = wx.Menu() + stepMenu.AppendSubMenu(submenu, subname) + for classname in menuStructure[subname]: + submenu.Append(wx.ID_ANY, classname) + + stepMenu.Append(wx.ID_ANY, 'Custom Bind') + + return stepMenu + +class PowerBinderButton(wx.BitmapButton): + + def __init__(self, parent, tgtTxtCtrl, init = {}): + wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) + self.Init = init + self.Dialog = None + self.DialogParent = parent + + self.tgtTxtCtrl = tgtTxtCtrl + self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) + self.SetToolTip("Launch PowerBinder") + + def PowerBinderEventHandler(self, _): + self.PowerBinderDialog().Show() + + def LoadFromData(self, data): + self.PowerBinderDialog().LoadFromData(data) + + def SaveToData(self): + return self.PowerBinderDialog().SaveToData() + + def PowerBinderDialog(self): + if not self.Dialog: + self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) + return self.Dialog + + +class PowerBinderEditDialog(wx.Dialog): + def __init__(self, parent): + wx.Dialog.__init__(self, parent, -1, "Edit Step", + style = wx.DEFAULT_DIALOG_STYLE) + + outerSizer = wx.BoxSizer(wx.VERTICAL) + + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + self.mainSizer.SetMinSize([500, 150]) + + self.Page = parent.Page + + self.mainSizer.Add( + self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), + 0, wx.EXPAND|wx.ALL, 10) + + outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) + + self.SetSizerAndFit(outerSizer) + self.Layout() + self.Fit() + +########### Power Binder Command Objects +class PowerBindCmd(): + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + commandClassName = commandRevClasses[type(self)] + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{commandClassName} - {short_bindstr}" + + +####### Away From Keyboard +class AFKCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.AFKName = wx.TextCtrl(dialog, -1) + self.AFKName.SetHint('Away From Keyboard Text') + sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + message = self.AFKName.GetValue() + return f"afk {message}" if message else "afk" + + def Serialize(self): + return {'message': self.AFKName.GetValue()} + + def Deserialize(self, init): + if init['message']: + self.AFKName.SetValue(init['message']) + +####### Attribute Monitor +class AttributeMonitorCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.Groups = {} + self.AttributeTable = { + 'Base' : { + 'Current Hit Points' : 'NT H', + 'Max Hit Points' : 'X H', + 'Current Endurance' : 'T E', + 'Max Endurance' : 'X EN', + 'Regeneration Rate' : 'N RAT', + 'Recovery Rate' : 'Y RA', + 'Endurance Consumption' : 'SU', + 'ToHit Bonus' : 'T B', + 'Accuracy Bonus' : 'CC', + 'Last Hit Chance' : 'T C', + 'Damage Bonus' : 'DA', + 'Healing Bonus' : 'NG B', + 'Recharge Time Bonus' : 'ME B', + 'Endurance Discount' : 'CE DIS', + 'Stealth Radius (PvP)' : 'PVP', + 'Stealth Radius (PvE)' : 'PVE', + 'Perception Radius' : 'RC', + 'Range Bonus' : 'GE B', + 'Threat Level' : 'AT L', + 'Experience to Next Level' : 'XT', + 'Experience Debt' : 'XP', + 'Influence / Infamy' : 'INF', + 'Inherent' : 'NH', + }, + 'Movement Speed' : { + 'Flying Speed' : 'FL', + 'Jumping Speed' : 'PI', + 'Max Jump Height' : 'X J', + 'Run Speed' : 'RU', + }, + 'Damage Resistance' : { + 'Smashing Resistance' : 'G R', + 'Lethal Resistance' : 'L R', + 'Fire Resistance' : 'RE R', + 'Cold Resistance' : 'COLD R', + 'Energy Resistance' : 'DamageType[4]', + 'Negative Energy Resistance' : 'GY R', + 'Psyonic Resistance' : 'NIC R', + 'Toxic Resistance' : 'XIC R', + }, + 'Defense' : { + 'Base Defense' : 'BAS', + 'Ranged Defense' : 'ED', + 'Melee Defense' : 'MEL', + 'AoE Defense' : '2', + 'Smashing Defense' : '3', + 'Lethal Defense' : '4', + 'Fire Defense' : '5', + 'Cold Defense' : '6', + 'Energy Defense' : '7', + 'Negative Energy Defense' : '8', + 'Psionic Defense' : '9', + 'Toxic Defense' : '1', + }, + 'Debuff Resistance' : { + 'Regeneration Resistance' : 'ON R', + 'Recovery Resistance' : 'RY R', + 'To Hit Resistance' : 'IT R', + 'Defense Resistance' : 'NSE RES', + }, + 'Status Effect Protection' : { + 'Hold Protection' : 'D P', + 'Immobilize Protection' : 'LIZE P', + 'Stun Protection' : 'N P', + 'Sleep Protection' : 'P P', + 'Knockback Protection' : 'K P', + 'Confuse Protection' : 'SE P', + 'Terrorize Protection' : 'ZE P', + 'Repel Protection' : 'EL P', + 'Teleport Protection' : 'T P', + }, + 'Status Effect Resistance' : { + 'Hold Resistance' : 'D R', + 'Immobilize Resistance' : 'LIZE R', + 'Stun Resistance' : 'N R', + 'Sleep Resistance' : 'P R', + 'Knockback Resistance' : 'K R', + 'Confuse Resistance' : 'SE R', + 'Terrorize Resistance' : 'ZE R', + 'Placate Resistance' : 'TE R', + 'Taunt Resistance' : 'NT R', + }, + 'Miscellaneous' : { + 'Level Shift' : 'L S', + }, + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.AttributeMenu = wx.Menu() + for group, controls in self.AttributeTable.items(): + submenu = wx.Menu() + self.AttributeMenu.AppendSubMenu(submenu, group) + for cb in controls: + submenu.Append(wx.ID_ANY, cb) + + self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) + + self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) + groupSizer.Add(self.editbox) + + newButton = self.editbox.GetNewButton() + newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) + + return groupSizer + + def MakeBindString(self): + map = {} + bindstrings = [] + for _, controls in self.AttributeTable.items(): + for cb, data in controls.items(): + map[cb] = data + + for string in self.editbox.GetStrings(): + if string: + bindstrings.append(f'monitorattribute {map[string]}') + + return '$$'.join(bindstrings) + + def Serialize(self): + return { + 'attributes' : self.editbox.GetStrings() + } + + def Deserialize(self, init): + self.editbox.SetStrings(init.get('attributes', [])) + + def OnNewButton(self, evt): + evt.GetEventObject().PopupMenu(self.AttributeMenu) + + def OnMenuItem(self, evt): + menuitem = evt.EventObject.FindItemById(evt.GetId()) + existingstrings = self.editbox.GetStrings() + existingstrings.append(menuitem.GetItemLabel()) + self.editbox.SetStrings(existingstrings) + +####### Auto Power +class AutoPowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) + autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.autoPowerName = PowerPicker(dialog) + autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) + + return autoPowerSizer + + def MakeBindString(self): + return f"powexecauto {self.autoPowerName.GetLabel()}" + + def Serialize(self): + return { + 'pname' : self.autoPowerName.GetLabel(), + 'picon' : self.autoPowerName.IconFilename + } + + def Deserialize(self, init): + if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) + +####### Buff Display Command +class BuffDisplayCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.Page = dialog.Page + self.buffDisplayMap = { + 'Status Window' : { + 'Hide Auto' : 1, + 'Hide Toggles' : 2, + 'No Blinking' : 4, + 'No Stacking' : 8, + 'Numeric Stacking' : 16, + 'Hide Buff Numbers' : 32, + 'Stop Sending Buffs' : 64, + }, + 'Group Window' : { + 'Hide Auto' : 256, + 'Hide Toggles' : 512, + 'No Blinking' : 1024, + 'No Stacking' : 2048, + 'Numeric Stacking' : 4096, + 'Hide Buff Numbers' : 8192, + 'Stop Sending Buffs' : 16384, + }, + 'Pet Window' : { + 'Hide Auto' : 65536, + 'Hide Toggles' : 131072, + 'No Blinking' : 262144, + 'No Stacking' : 524288, + 'Numeric Stacking' : 1048576, + 'Hide Buff Numbers' : 2097152, + 'Stop Sending Buffs' : 4194304, + }, + } + self.Groups = {} + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + groupSizer = wx.BoxSizer(wx.HORIZONTAL) + + for group, controls in self.buffDisplayMap.items(): + self.Groups[group] = ControlGroup(dialog, self.Page, label = group) + groupid = self.Groups[group].GetStaticBox().GetId() + for cb, data in controls.items(): + self.Groups[group].AddControl( + ctlType = 'checkbox', + ctlName = f"{groupid}_{group}_{cb}", + label = cb, + data = data, + ) + + groupSizer.Add(self.Groups[group]) + + return groupSizer + + def CalculateValue(self): + page = wx.App.Get().Main.Profile.CustomBinds + + total = 0 + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] + if checkbox.IsChecked(): + total = total + checkbox.Data + return total + + def MakeBindString(self): + return f"optionset buffsettings {self.CalculateValue()}" + + def Serialize(self): + return { 'value' : self.CalculateValue() } + + def Deserialize(self, init): + value = init.get('value', 0) + + value = value or 0 # in case we had for some reason 'None' stashed in the init values + + for group, controls in self.buffDisplayMap.items(): + groupid = self.Groups[group].GetStaticBox().GetId() + for cb in controls: + checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] + checkbox.SetValue( checkbox.Data & value ) + +####### Chat Command +class ChatCmd(PowerBindCmd): + def __init__(self, dialog, init = {}): + self.chatChannelMap = { # before __init__ + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } + PowerBindCmd.__init__(self, dialog, init) + + def BuildUI(self, dialog): + chatCommandSizer = wx.GridBagSizer(5, 5) + self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") + chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) + # row 1 + self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) + self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) + self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) + # row 2 + self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) + self.chatCommandDuration.SetRange(1, 20) + self.chatCommandDuration.SetValue(7) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandDuration, (2,1)) + self.chatCommandChatSize = wx.Choice(dialog, -1, + choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) + self.chatCommandChatSize.SetSelection(5) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) + self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) + self.chatCommandChannel.SetSelection(0) + chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) + chatCommandSizer.Add(self.chatCommandChannel, (2,5)) + # row 3 + self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") + chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) + self.chatCommandMessage = wx.TextCtrl(dialog, -1) + self.chatCommandMessage.SetHint('Chat Command Text') + chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) + + return chatCommandSizer + + def MakeBindString(self): + duration = self.chatCommandDuration.GetValue() + + choice = self.chatCommandChatSize + index = choice.GetSelection() + size = choice.GetString(index) + + duration = f"" if duration != 7 else "" + size = f"" if size != "1" else "" + + bdcolor = fgcolor = bgcolor = '' + if self.chatCommandUseColorsCB.IsChecked(): + bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) + + bdcolor = f"" + fgcolor = f"" + bgcolor = f"" + + beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' + text = self.chatCommandMessage.GetValue() + + choice = self.chatCommandChannel + index = choice.GetSelection() + channel = choice.GetString(index) + + return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" + + def Serialize(self): + return { + 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), + 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), + 'channel' : self.chatCommandChannel .GetSelection(), + 'size' : self.chatCommandChatSize.GetSelection(), + 'duration' : self.chatCommandDuration.GetValue(), + 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), + 'text' : self.chatCommandMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) + if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) + if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) + if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) + if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) + if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) + if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) + if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) + if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) + + +####### Chat Command Global +class ChatGlobalCmd(PowerBindCmd): + def BuildUI(self, dialog): + chatCommandGlobalSizer = wx.GridBagSizer(5,5) + + self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") + chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) + + self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalChannel.SetHint("Channel") + chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) + + self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) + self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') + chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) + + chatCommandGlobalSizer.AddGrowableCol(1) + + return chatCommandGlobalSizer + + def MakeBindString(self): + useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() + channel = self.chatCommandGlobalChannel.GetValue() + message = self.chatCommandGlobalMessage.GetValue() + + preface = "beginchat /" if useBeginchat else "" + + return f'{preface}send "{channel}" {message}' + + def Serialize(self): + return { + 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), + 'channel' : self.chatCommandGlobalChannel.GetValue(), + 'message' : self.chatCommandGlobalMessage.GetValue(), + } + + def Deserialize(self, init): + if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) + if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) + if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) + +#######Costume Change +class CostumeChangeCmd(PowerBindCmd): + def BuildUI(self, dialog): + costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeCostume = wx.Choice(dialog, -1, + choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) + self.costumeChangeCostume.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.costumeChangeEmote = wx.Choice(dialog, -1, + choices = GameData.Emotes['costumechange']) + self.costumeChangeEmote.Insert("- None -", 0) + self.costumeChangeEmote.SetSelection(0) + costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return costumeChangeSizer + + def MakeBindString(self): + costumeNumber = self.costumeChangeCostume.GetSelection() + costumeEmote = self.costumeChangeEmote.GetSelection() + + if costumeEmote: # None, or 0 == "- None -" + ccCmd = 'cce' + emoteName = self.costumeChangeEmote.GetString(costumeEmote) + emoteName = " CC" + emoteName.replace(" ","") + else: + ccCmd = 'cc' + emoteName = '' + + return f"{ccCmd} {costumeNumber}{emoteName}" + + def Serialize(self): + return{ + 'costumeNumber': self.costumeChangeCostume.GetSelection(), + 'costumeEmote' : self.costumeChangeEmote.GetSelection(), + } + + def Deserialize(self, init): + if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) + if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) + +####### Movement Command +class MovementCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + self.plusbutton.SetValue(True) + + self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.commandchoice = wx.Choice(dialog, choices = [ + "forward", "left", "right", "backward", "up", "down", + "turnleft", "turnright", "first", "autorun", "clicktomove", + ],) + sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) + self.commandchoice.SetSelection(0) + + self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) + + self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) + sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + pre = post = '' + if self.plusbutton.GetValue() : pre = "+" + elif self.plusplusbutton.GetValue() : pre = "++" + elif self.minusbutton.GetValue() : pre = "-" + elif self.zerobutton.GetValue() : post = " 0" + elif self.onebutton.GetValue() : post = " 1" + + command = self.commandchoice.GetString(self.commandchoice.GetSelection()) + + return f"{pre}{command}{post}" + + def Serialize(self): + mod = '' + if self.plusbutton.GetValue() : mod = "plus" + elif self.plusplusbutton.GetValue() : mod = "plusplus" + elif self.minusbutton.GetValue() : mod = "minus" + elif self.zerobutton.GetValue() : mod = "zero" + elif self.onebutton.GetValue() : mod = "one" + + return { + 'mod' : mod, + 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), + } + + def Deserialize(self, init): + mod = init.get('mod', 'plus') + + if mod == 'plus' : self.plusbutton.SetValue(True) + elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) + elif mod == 'minus' : self.minusbutton.SetValue(True) + elif mod == 'zero' : self.zerobutton.SetValue(True) + elif mod == 'one' : self.onebutton.SetValue(True) + + self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) + +####### Graphics Command +class GraphicsCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.FlexGridSizer(2) + + self.visscalecb = wx.CheckBox(dialog, label = "visscale") + sizer.Add(self.visscalecb) + self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) + sizer.Add(self.visscalesc) + + self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") + sizer.Add(self.dofweightcb) + self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) + sizer.Add(self.dofweightsc) + + self.fsaacb = wx.CheckBox(dialog, label = "fsaa") + sizer.Add(self.fsaacb) + self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) + self.fsaach.SetSelection(0) + sizer.Add(self.fsaach) + + self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") + sizer.Add(self.bloomscalecb) + self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) + self.bloomscalech.SetSelection(0) + sizer.Add(self.bloomscalech) + + self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") + sizer.Add(self.bloomweightcb) + self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) + sizer.Add(self.bloomweightsc) + + self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") + sizer.Add(self.lodbiascb) + self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) + sizer.Add(self.lodbiassc) + + self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") + sizer.Add(self.renderscalecb) + self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) + sizer.Add(self.renderscalesc) + + return sizer + + def MakeBindString(self): + # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. + bindstrings = [] + if self.visscalecb.IsChecked(): + bindstrings.append("visscale " + str(self.visscalesc.GetValue())) + if self.dofweightcb.IsChecked(): + bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) + if self.fsaacb.IsChecked(): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bindstrings.append("fsaa " + fsaavalue) + if self.bloomscalecb.IsChecked(): + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + bindstrings.append("bloomscale " + bloomscalevalue) + if self.bloomweightcb.IsChecked(): + bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) + if self.lodbiascb.IsChecked(): + bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) + if self.renderscalecb.IsChecked(): + bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) + + return '$$'.join(bindstrings) + + def Serialize(self): + fsaavalue = "" + fsaaselection = self.fsaach.GetSelection() + if fsaaselection != wx.NOT_FOUND: + fsaavalue = self.fsaach.GetString(fsaaselection) + bloomscalevalue = "" + bloomscaleselection = self.bloomscalech.GetSelection() + if bloomscaleselection != wx.NOT_FOUND: + bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) + return { + 'visscalecb' : self.visscalecb.IsChecked(), + 'visscalesc' : self.visscalesc.GetValue(), + 'dofweightcb' : self.dofweightcb.IsChecked(), + 'dofweightsc' : self.dofweightsc.GetValue(), + 'fsaacb' : self.fsaacb.IsChecked(), + 'fsaach' : fsaavalue, + 'bloomscalecb' : self.bloomscalecb.IsChecked(), + 'bloomscalech' : bloomscalevalue, + 'bloomweightcb' : self.bloomweightcb.IsChecked(), + 'bloomweightsc' : self.bloomweightsc.GetValue(), + 'lodbiascb' : self.lodbiascb.IsChecked(), + 'lodbiassc' : self.lodbiassc.GetValue(), + 'renderscalecb' : self.renderscalecb.IsChecked(), + 'renderscalesc' : self.renderscalesc.GetValue(), + } + + def Deserialize(self, init): + self.visscalecb.SetValue(init.get('visscalecb', False)) + self.visscalesc.SetValue(init.get('visscalesc', 1.0)) + self.dofweightcb.SetValue(init.get('dofweightcb', False)) + self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) + self.fsaacb.SetValue(init.get('fsaacb', False)) + self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) + self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) + self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) + self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) + self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) + self.lodbiascb.SetValue(init.get('lodbiascb', False)) + self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) + self.renderscalecb.SetValue(init.get('renderscalecb', False)) + self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) + +####### Custom Bind +class CustomBindCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + self.customBindName = wx.TextCtrl(dialog, -1) + self.customBindName.SetHint('Custom Bind Text') + sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) + + return sizer + + def MakeBindString(self): + return self.customBindName.GetValue() + + def Serialize(self): + return { 'customBindName': self.customBindName.GetValue() } + + def Deserialize(self,init): + if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) + +####### Emote +class EmoteCmd(PowerBindCmd): + def BuildUI(self, dialog): + emoteSizer = wx.BoxSizer(wx.HORIZONTAL) + self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") + emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + self.emoteName = wx.Button(dialog, -1, "...") + self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) + emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) + + return emoteSizer + + def MakeBindString(self): + displayedEmoteName = self.emoteName.GetLabel() + actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] + + return actualEmotePayload + + def Serialize(self): + return {'emoteName': self.emoteName.GetLabel()} + + def Deserialize(self, init): + if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) + +####### Load Binds Directory +class LoadBindsDir(PowerBindCmd): + def BuildUI(self, dialog): + mainSizer = wx.BoxSizer(wx.VERTICAL) + + lbSizer = wx.BoxSizer(wx.HORIZONTAL) + lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") + lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + + profiles = Profile.GetAllProfileBindsDirs() + + self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) + lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) + + mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") + self.lbResetCB.SetValue(True) + + mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) + + return mainSizer + + def MakeBindString(self): + + # If the specified binds directory disappeared between runs, we'd crash, so handle that. + if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' + + config = wx.ConfigBase.Get() + if config.Exists('GameBindPath'): + bindpath = config.Read('GameBindPath') + else: + bindpath = config.Read('BindPath') + + reset = "" + if self.lbResetCB.GetValue(): + reset = "keybind_reset$$" + + resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' + return reset + 'bindloadfile ' + str(resetfilepath) + + def Serialize(self): + return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), + 'ResetKeybinds' : self.lbResetCB.GetValue(), + } + + def Deserialize(self, init): + if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) + self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) + +####### Power Abort +class PowerAbortCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecabort' + +####### Power Unqueue +class PowerUnqueueCmd(PowerBindCmd): + def MakeBindString(self): + return 'powexecunqueue' + +####### SG Mode +class SGModeCmd(PowerBindCmd): + def BuildUI(self, dialog): + sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) + sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") + self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") + + sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) + + return sgmodeSizer + + def MakeBindString(self): + if self.sgmodeOnRB.GetValue(): + return 'sgmodeset 1' + elif self.sgmodeOffRB.GetValue(): + return 'sgmodeset 0' + else: + return 'sgmode' + + def Serialize(self): + if self.sgmodeOnRB.GetValue(): + val = "On" + elif self.sgmodeOffRB.GetValue(): + val = "Off" + else: + val = "Toggle" + + return {"value" : val} + + def Deserialize(self, init): + val = init.get('value', '') + if val == "On": + self.sgmodeOnRB.SetValue(True) + elif val == "Off": + self.sgmodeOffRB.SetValue(True) + else: + self.sgmodeToggleRB.SetValue(True) + +####### Target Custom +class TargetCustomCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetCustomSizer = wx.GridBagSizer(5,5) + targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), + flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) + self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetCustomModeChoice.SetSelection(0) + targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) + self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) + self.targetCustomOptionalName.SetHint("Optional name to match") + targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) + self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") + targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) + self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") + targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) + self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") + targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) + self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") + targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) + self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") + targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) + self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") + targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) + self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") + targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) + self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") + targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) + + targetCustomSizer.AddGrowableCol(2) + + return targetCustomSizer + + def MakeBindString(self): + choice = self.targetCustomModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + targetCommand = "targetcustom" + mode.lower() + + enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" + friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" + defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" + alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" + mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" + notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" + base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" + notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" + + name = self.targetCustomOptionalName.GetValue() + + return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" + + def Serialize(self): + return { + 'mode' : self.targetCustomModeChoice.GetSelection(), + 'enemy' : self.targetCustomCBEnemies. IsChecked(), + 'friend' : self.targetCustomCBFriends. IsChecked(), + 'defeated' : self.targetCustomCBDefeated. IsChecked(), + 'alive' : self.targetCustomCBAlive. IsChecked(), + 'mypet' : self.targetCustomCBMyPets. IsChecked(), + 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), + 'base' : self.targetCustomCBBaseItems. IsChecked(), + 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), + 'name' : self.targetCustomOptionalName.GetValue(), + } + + def Deserialize(self, init): + if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) + if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) + if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) + if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) + if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) + if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) + if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) + if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) + if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) + if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) + + +####### Target Enemy +class TargetEnemyCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) + targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetEnemyModeChoice.SetSelection(0) + targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetEnemySizer + + def MakeBindString(self): + choice = self.targetEnemyModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetenemy" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetEnemyModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) + +####### Target Friend +class TargetFriendCmd(PowerBindCmd): + def BuildUI(self, dialog): + targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) + targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) + self.targetFriendModeChoice.SetSelection(0) + targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) + + return targetFriendSizer + + def MakeBindString(self): + choice = self.targetFriendModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "targetfriend" + mode.lower() + + def Serialize(self): + return { 'mode' : self.targetFriendModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) + +####### Team/Pet Select +class TeamPetSelectCmd(PowerBindCmd): + def BuildUI(self, dialog): + teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) + teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) + + self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], + style=wx.ALIGN_CENTER_VERTICAL) + self.teamPetSelectNumber.SetSelection(0) + teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) + + return teamPetSelectSizer + + def MakeBindString(self): + teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' + targetNumber = self.teamPetSelectNumber.GetSelection()+1 + + return f"{teamOrPet}select {targetNumber}" + + def Serialize(self): + return { + 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', + 'targetNum': self.teamPetSelectNumber.GetSelection(), + } + + def Deserialize(self, init): + ToP = init.get('teamOrPet', '') + if ToP == 'pet': + self.teamPetSelectPetRB.SetValue(True) + else: + self.teamPetSelectTeamRB.SetValue(True) + if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) + +####### Unselect +class UnselectCmd(PowerBindCmd): + def MakeBindString(self): + return 'unselect' + +####### Use Insp By Name +class UseInspByNameCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) + for _, types in GameData.Inspirations.items(): + for _, info in types.items(): + for insp in info['tiers']: + name = re.sub(' ', '', str(insp)) + icon = GetIcon(f'Inspirations/{name}') + self.useInspByNameModeChoice.Append(insp, icon) + self.useInspByNameModeChoice.SetSelection(0) + useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) + + return useInspByNameSizer + + def MakeBindString(self): + choice = self.useInspByNameModeChoice + index = choice.GetSelection() + mode = choice.GetString(index) + return "inspexecname " + mode.lower() + + def GetAllInsps(self): + Insplist = [] + for _, info in GameData.Inspirations.items(): + for insp in info['tiers']: + Insplist.append(insp) + Insplist.append("---") + Insplist.pop(-1) # snip the terminal "---" + + return Insplist + + def Serialize(self): + return { 'insp' : self.useInspByNameModeChoice.GetSelection() } + + def Deserialize(self, init): + if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) + +####### Use Insp From Row / Column +class UseInspRowColCmd(PowerBindCmd): + def BuildUI(self, dialog): + useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnRow.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) + useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, + wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) + self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) + self.useInspRowColumnCol.SetSelection(0) + useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) + + return useInspRowColumnSizer + + def MakeBindString(self): + row = self.useInspRowColumnRow.GetSelection()+1 + col = self.useInspRowColumnCol.GetSelection()+1 + + return f"inspexectray {col} {row}" + + def Serialize(self): + return { + 'col' : self.useInspRowColumnCol.GetSelection(), + 'row' : self.useInspRowColumnRow.GetSelection(), + } + + def Deserialize(self, init): + if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) + if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) + +####### Use Power +class UsePowerCmd(PowerBindCmd): + def BuildUI(self, dialog): + outerSizer = wx.BoxSizer(wx.HORIZONTAL) + + usePowerSizer = wx.GridBagSizer(5,5) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBToggle, (0,1)) + self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOn, (0,2)) + self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) + usePowerSizer.Add(self.usePowerRBOff, (0,3)) + usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) + self.usePowerName = PowerPicker(dialog) + usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) + usePowerSizer.AddGrowableCol(3) + + outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) + + return outerSizer + + def MakeBindString(self): + if self.usePowerRBToggle.GetValue(): + method = "powexecname" + elif self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') + return '' + + return f"{method} {self.usePowerName.GetLabel()}" + + def Serialize(self): + if self.usePowerRBOn.GetValue(): + method = "powexectoggleon" + elif self.usePowerRBOff.GetValue(): + method = "powexectoggleoff" + else: + method = "powexecname" + return { + 'method': method, + 'pname' : self.usePowerName.GetLabel(), + 'picon' : self.usePowerName.IconFilename + } + + def Deserialize(self, init): + method = init.get('method', '') + if method == 'powexectoggleon': + self.usePowerRBOn.SetValue(True) + elif method == 'powexectoggleoff': + self.usePowerRBOff.SetValue(True) + else: + self.usePowerRBToggle.SetValue(True) + if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) + if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) + +####### Use Power From Tray +class UsePowerFromTrayCmd(PowerBindCmd): + def BuildUI(self, dialog): + usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTrayTray = wx.Choice(dialog, -1, + choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', + 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) + self.usePowerFromTrayTray.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) + self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) + self.usePowerFromTraySlot.SetSelection(0) + usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + return usePowerFromTraySizer + + def MakeBindString(self): + choice = self.usePowerFromTrayTray + tray = choice.GetSelection() + + choice = self.usePowerFromTraySlot + slot = choice.GetSelection()+1 + + mode = "slot" + mode2 = '' + if tray > 3: + mode = "tray" + mode2 = f" {tray - 3}" + elif tray == 3: + mode = "alt2slot" + elif tray == 2: + mode = "altslot" + + return f"powexec{mode} {slot}{mode2}" + + def Serialize(self): + return { + 'tray' : self.usePowerFromTrayTray.GetSelection(), + 'slot' : self.usePowerFromTraySlot.GetSelection(), + } + + def Deserialize(self, init): + if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) + if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) + +####### Window Color +class WindowColorCmd(PowerBindCmd): + def BuildUI(self, dialog): + windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) + borderSizer = wx.BoxSizer(wx.VERTICAL) + self.ColorBorder.SetSizer(borderSizer) + self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) + borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) + + windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) + + RGBASizer = wx.FlexGridSizer(3, 4, 5) + + RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) + self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) + self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) + self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) + RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) + self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) + RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) + + windowColorSizer.Add(RGBASizer) + + self.UpdateFromSlider() + + return windowColorSizer + + def MakeBindString(self): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + return f"windowcolor {Rval} {Gval} {Bval} {Aval}" + + def Serialize(self): + return { + 'Rval' : self.RSlider.GetValue(), + 'Gval' : self.GSlider.GetValue(), + 'Bval' : self.BSlider.GetValue(), + 'Aval' : self.ASlider.GetValue(), + } + + def Deserialize(self, init): + self.RSlider.SetValue(init['Rval']) + self.GSlider.SetValue(init['Gval']) + self.BSlider.SetValue(init['Bval']) + self.ASlider.SetValue(init['Aval']) + self.UpdateFromSlider() + + def UpdateFromSlider(self, _ = None): + Rval = self.RSlider.GetValue() + Gval = self.GSlider.GetValue() + Bval = self.BSlider.GetValue() + Aval = self.ASlider.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RReadout.SetValue(Rval) + self.GReadout.SetValue(Gval) + self.BReadout.SetValue(Bval) + self.AReadout.SetValue(Aval) + self.ColorBorder.Refresh() + + def UpdateFromText(self, _ = None): + Rval = self.RReadout.GetValue() + Gval = self.GReadout.GetValue() + Bval = self.BReadout.GetValue() + Aval = self.AReadout.GetValue() + self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) + self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) + self.RSlider.SetValue(Rval) + self.GSlider.SetValue(Gval) + self.BSlider.SetValue(Bval) + self.ASlider.SetValue(Aval) + self.ColorBorder.Refresh() + +####### Window Save / Load +class WindowSaveLoadCmd(PowerBindCmd): + def BuildUI(self, dialog): + sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) + self.CommandChoice.SetSelection(0) + sizer.Add(self.CommandChoice, 0, wx.ALL, 5) + + self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), + value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) + sizer.Add(self.FilePath, 0, wx.ALL, 5) + + return sizer + + def MakeBindString(self): + command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] + return f'{command} "{self.FilePath.GetValue()}"' + + def Serialize(self): + return { + 'command' : self.CommandChoice.GetSelection(), + 'filename' : self.FilePath.GetValue(), + } + + def Deserialize(self, init): + self.CommandChoice.SetSelection(init.get('command', 0)) + self.FilePath.SetValue(init.get('filename', '')) + +####### Window Toggle +class WindowToggleCmd(PowerBindCmd): + def BuildUI(self, dialog): + self.WindowNames = { + 'Actions' : 'actions', + 'Auction House' : 'ah', + 'Badge' : 'badge', + 'Channel Search' : 'chansearch', + 'Chat' : 'chat', + 'Custom Chat 1' : 'chat1', + 'Custom Chat 2' : 'chat2', + 'Custom Chat 3' : 'chat3', + 'Custom Chat 4' : 'chat4', + 'Clues' : 'clue', + 'Combat Numbers' : 'combatnumbers', + 'Contacts' : 'contact', + 'Contact Finder' : 'contactfinder', + 'Costumes' : 'costume', + 'Email' : 'email', + 'Enhancements' : 'enhancements', + 'Friends' : 'friend', + 'Group' : 'group', + 'Help' : 'helpwindow', + 'Incarnate' : 'incarnate', + 'Inspirations' : 'insp', + 'League' : 'league', + 'LFG' : 'lfg', + 'Map' : 'map', + 'Mission' : 'mission', + 'Nav / Compass' : 'nav', + 'Options' : 'options', + 'Pets' : 'pet', + 'Petition' : 'petition', + 'Power Tray' : 'powers', + 'Power List' : 'powerlist', + 'Quit' : 'quit', + 'Recipes' : 'recipe', + 'Salvage' : 'salvage', + 'Search' : 'search', + 'Supergroup' : 'sg', + 'Target' : 'target', + 'Team' : 'team', + 'Tray' : 'tray', + 'Tray1' : 'tray1', + 'Tray2' : 'tray2', + 'Tray3' : 'tray3', + 'Tray4' : 'tray4', + 'Tray5' : 'tray5', + 'Tray6' : 'tray6', + 'Tray7' : 'tray7', + 'Tray8' : 'tray8', + 'Vault' : 'vault', + } + + self.ShortToggleCommands = { + 'Auction House' : 'ah', + 'Chat' : 'chat', + 'Help' : 'helpwindow', + 'Map' : 'map', + 'Nav / Compass' : 'nav', + 'Power Tray' : 'powers', + 'Target' : 'target', + 'Tray' : 'tray', + } + + windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) + windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) + self.windowToggleTray.SetSelection(0) + windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + + self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) + self.windowShowRB = wx.RadioButton(dialog, -1, "Show") + self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") + + windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) + windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) + + return windowToggleSizer + + def MakeBindString(self): + choice = self.windowToggleTray + index = choice.GetSelection() + windowdesc = choice.GetString(index) + windowname = self.WindowNames[windowdesc] + + if self.windowShowRB.GetValue(): + return 'show ' + windowname + elif self.windowHideRB.GetValue(): + return 'windowhide ' + windowname + else: + if shortcmd := self.ShortToggleCommands.get(windowdesc, None): + return shortcmd + else: + return 'toggle ' + windowname + + + def Serialize(self): + choice = self.windowToggleTray + if self.windowShowRB.GetValue(): + action = "Show" + elif self.windowHideRB.GetValue(): + action = "Hide" + else: + action = "Toggle" + return { + 'window': choice.GetString(choice.GetSelection()), + 'action': action, + } + + def Deserialize(self, init): + choice = self.windowToggleTray + if window := init.get('window', ''): + if isinstance(window, int): + choice.SetSelection(window) + else: + choice.SetSelection(choice.FindString(window)) + + if choice.GetSelection() == wx.NOT_FOUND: + choice.SetSelection(0) + + action = init.get('action', '') + if action == "Show": + self.windowShowRB.SetValue(True) + elif action == "Hide": + self.windowHideRB.SetValue(True) + else: + self.windowToggleRB.SetValue(True) + + +# Must always add to this list when adding a new command class above +menuStructure = { + 'Graphics / UI' : [ + 'Attribute Monitor', + 'Buff Display Settings', + 'Graphics Settings', + 'Window Color', + 'Window Save / Load', + 'Window Toggle', + ], + 'Inspirations' : [ + 'Use Inspiration By Name', + 'Use Inspiration From Row/Column', + ], + 'Powers' : [ + 'Auto Power', + 'Power Abort', + 'Power Unqueue', + 'Use Power', + 'Use Power From Tray', + ], + 'Social' : [ + 'Away From Keyboard', + 'Chat Command', + 'Chat Command (Global)', + 'Costume Change', + 'Emote', + 'Supergroup Mode', + ], + 'Targeting' : [ + 'Target Custom', + 'Target Enemy', + 'Target Frield', + 'Team/Pet Select', + 'Unselect', + ], + 'Misc' : [ + 'Load Binds Directory', + 'Movement Commands', + ], + # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, + # but I'm leaving it here to remind myself that we do that. + } + +# Must always add to this list when adding a new command class above +commandClasses = { + 'Auto Power' : AutoPowerCmd, + 'Away From Keyboard' : AFKCmd, + 'Attribute Monitor' : AttributeMonitorCmd, + 'Buff Display Settings' : BuffDisplayCmd, + 'Chat Command' : ChatCmd, + 'Chat Command (Global)' : ChatGlobalCmd, + 'Costume Change' : CostumeChangeCmd, + 'Custom Bind' : CustomBindCmd, + 'Emote' : EmoteCmd, + 'Graphics Settings' : GraphicsCmd, + 'Load Binds Directory' : LoadBindsDir, + 'Movement Commands' : MovementCmd, + 'Power Abort' : PowerAbortCmd, + 'Power Unqueue' : PowerUnqueueCmd, + 'Supergroup Mode' : SGModeCmd, + 'Target Custom' : TargetCustomCmd, + 'Target Enemy' : TargetEnemyCmd, + 'Target Friend' : TargetFriendCmd, + 'Team/Pet Select' : TeamPetSelectCmd, + 'Unselect' : UnselectCmd, + 'Use Inspiration By Name' : UseInspByNameCmd, + 'Use Inspiration From Row/Column' : UseInspRowColCmd, + 'Use Power' : UsePowerCmd, + 'Use Power From Tray' : UsePowerFromTrayCmd, + 'Window Color' : WindowColorCmd, + 'Window Save / Load' : WindowSaveLoadCmd, + 'Window Toggle' : WindowToggleCmd, +} +# use these when we rename a commandClass so that old Profiles will still load correctly. +# If we've also updated the class, we need to try to make sure the new class will still +# Deserialize the legacy data, or at least not crash. +deprecatedCommandClasses = { + 'SG Mode Toggle' : SGModeCmd, + 'Use Insp By Name' : UseInspByNameCmd, + 'Use Insp From Row/Column' : UseInspRowColCmd, +} +commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/__init__.py b/UI/PowerBinderCommand/__init__.py new file mode 100644 index 0000000..f0a7fd2 --- /dev/null +++ b/UI/PowerBinderCommand/__init__.py @@ -0,0 +1,23 @@ +import wx + +########### Power Binder Command Objects +class PowerBinderCommand(): + Menu = '' + Name = '' + def __init__(self, dialog, init = {}): + self.UI = self.BuildUI(dialog) + if init: self.Deserialize(init) + + # Methods to override + def BuildUI(self, dialog) -> wx.Sizer|None : return None + def MakeBindString(self) -> str : return '' + def Serialize(self) -> dict : return {} + def Deserialize(self, init) : return + + def MakeListEntryString(self): + bindstr = self.MakeBindString() + short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") + return f"{self.Name} - {short_bindstr}" + +commandClasses = {} +commandRevClasses = {} diff --git a/UI/PowerBinderDialog.py b/UI/PowerBinderDialog.py index 4c02ab7..ad26b7a 100644 --- a/UI/PowerBinderDialog.py +++ b/UI/PowerBinderDialog.py @@ -1,5 +1,5 @@ import wx -import re +import re, os, sys import UI import UI.EmotePicker from UI.ControlGroup import ControlGroup @@ -7,7 +7,8 @@ from Help import HelpButton import wx.adv from wx.adv import BitmapComboBox, EditableListBox -from pathlib import PureWindowsPath +from pathlib import Path, PureWindowsPath +import importlib import GameData import Profile from Icon import GetIcon @@ -17,6 +18,9 @@ def __init__(self, parent, button, init = {}): wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) self.Page = parent.Page + + self.LoadModules() + self.EditDialog = PowerBinderEditDialog(self) self.Button = button self.AddStepMenu = self.makeAddStepMenu() @@ -24,11 +28,8 @@ def __init__(self, parent, button, init = {}): sizer = wx.BoxSizer(wx.VERTICAL); self.mainSizer = sizer + choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) AddStepButton = wx.Button(self, -1, 'Add Step') AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) @@ -89,6 +90,39 @@ def __init__(self, parent, button, init = {}): # if we are loading from profile, ie, have "init", build the list from it if init: self.LoadFromData(init) + # Load plugins / modules from UI/PowerBinderCommand directory + def LoadModules(self): + base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__))) + path = Path(base_path) / 'PowerBinderCommand' + print(f"Looking for modules in {path}") + for package_file in sorted(path.glob('*.py')): + package = package_file.stem + if package == '__init__': continue # TODO - fix up glob() to dtrt instead + print(f"Importing package {package}") + + # do the actual importing + mod = importlib.import_module('UI.PowerBinderCommand.' + package) + + if modclass := getattr(mod, package, None): + + # put the class into menuStructure, commandClasses, and commandRevClasses + if modName := getattr(modclass, 'Name', ''): + commandClasses[modName] = modclass + commandRevClasses[modclass] = modName + else: + print(f"Class {modclass} didn't define 'Name' - this is a bug") + + if modMenu := getattr(modclass, 'Menu', ''): + menuStructure[modMenu].append(modName) + else: + print(f"Module {modclass} didn't define 'Menu' - this is probably a bug") + + if depName := getattr(modclass, 'DeprecatedName', ''): + deprecatedCommandClasses[depName] = modclass + + else: + print(f"Module {mod} didn't define a class of the same name - this is a bug!") + def LoadFromData(self, init): for item in init: for type, data in item.items(): @@ -1714,87 +1748,17 @@ def Deserialize(self, init): else: self.windowToggleRB.SetValue(True) - -# Must always add to this list when adding a new command class above menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], + 'Graphics / UI' : [ ], + 'Inspirations' : [ ], + 'Powers' : [ ], + 'Social' : [ ], + 'Targeting' : [ ], + 'Misc' : [ ], # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, # but I'm leaving it here to remind myself that we do that. } +commandClasses = {} +commandRevClasses = {} +deprecatedCommandClasses = {} -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} From 6f3ef0a8c116bebe98c1c75cbe78651a53298d8b Mon Sep 17 00:00:00 2001 From: Russell Pickett Date: Sat, 25 Jan 2025 14:47:13 -0500 Subject: [PATCH 2/2] Refactor all PowerBinder steps into separate modules; working --- UI/PowerBinderCommand/AttributeMonitorCmd.py | 1664 +--------------- UI/PowerBinderCommand/AutoPowerCmd.py | 1779 +---------------- UI/PowerBinderCommand/BuffDisplayCmd.py | 1723 +---------------- UI/PowerBinderCommand/ChatCmd.py | 1727 +---------------- UI/PowerBinderCommand/ChatGlobalCmd.py | 1764 +---------------- UI/PowerBinderCommand/CostumeChangeCmd.py | 1761 +---------------- UI/PowerBinderCommand/CustomBindCmd.py | 1786 +---------------- UI/PowerBinderCommand/EmoteCmd.py | 1779 +---------------- UI/PowerBinderCommand/GraphicsCmd.py | 1691 +--------------- UI/PowerBinderCommand/LoadBindsDir.py | 1753 +---------------- UI/PowerBinderCommand/MovementCmd.py | 1739 +---------------- UI/PowerBinderCommand/PowerAbortCmd.py | 1801 +----------------- UI/PowerBinderCommand/PowerUnqueueCmd.py | 1801 +----------------- UI/PowerBinderCommand/SGModeCmd.py | 1762 +---------------- UI/PowerBinderCommand/TargetCustomCmd.py | 1727 +---------------- UI/PowerBinderCommand/TargetEnemyCmd.py | 1781 +---------------- UI/PowerBinderCommand/TargetFriendCmd.py | 1781 +---------------- UI/PowerBinderCommand/TeamPetSelectCmd.py | 1767 +---------------- UI/PowerBinderCommand/UnselectCmd.py | 1801 +----------------- UI/PowerBinderCommand/UseInspByNameCmd.py | 1767 +---------------- UI/PowerBinderCommand/UseInspRowColCmd.py | 1772 +---------------- UI/PowerBinderCommand/UsePowerCmd.py | 1744 +---------------- UI/PowerBinderCommand/UsePowerFromTrayCmd.py | 1758 +---------------- UI/PowerBinderCommand/WindowColorCmd.py | 1704 +---------------- UI/PowerBinderCommand/WindowSaveLoadCmd.py | 1776 +---------------- UI/PowerBinderCommand/WindowToggleCmd.py | 1675 +--------------- UI/PowerBinderDialog.py | 1456 +------------- 27 files changed, 166 insertions(+), 46873 deletions(-) diff --git a/UI/PowerBinderCommand/AttributeMonitorCmd.py b/UI/PowerBinderCommand/AttributeMonitorCmd.py index 4c02ab7..cd07c62 100644 --- a/UI/PowerBinderCommand/AttributeMonitorCmd.py +++ b/UI/PowerBinderCommand/AttributeMonitorCmd.py @@ -1,338 +1,15 @@ import wx -import re -import UI -import UI.EmotePicker -from UI.ControlGroup import ControlGroup -from UI.PowerPicker import PowerPicker -from Help import HelpButton import wx.adv -from wx.adv import BitmapComboBox, EditableListBox -from pathlib import PureWindowsPath -import GameData -import Profile -from Icon import GetIcon - -class PowerBinderDialog(wx.Dialog): - def __init__(self, parent, button, init = {}): - wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) - - self.Page = parent.Page - self.EditDialog = PowerBinderEditDialog(self) - self.Button = button - self.AddStepMenu = self.makeAddStepMenu() - - sizer = wx.BoxSizer(wx.VERTICAL); - self.mainSizer = sizer - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) - AddStepButton = wx.Button(self, -1, 'Add Step') - AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) - AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) - choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) - choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) - sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) - - rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) - - self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) - self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) - self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) - rearrangeCtrl.Add(self.RearrangeList, 1) - - rearrangeButtons = wx.BoxSizer(wx.VERTICAL) - self.DelButton = wx.Button(self, -1, "Delete") - self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) - self.EditButton = wx.Button(self, -1, "Edit") - self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) - self.EditButton.Disable() - upButton = wx.Button(self, -1, "\u25B2") - upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) - downButton = wx.Button(self, -1, "\u25BC") - downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) - rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) - rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) - - sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.BindStringDisplay = wx.TextCtrl(self, -1) - self.BindStringDisplay.Disable() - choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, - wx.ALIGN_CENTER_VERTICAL) - choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) - - sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) - - sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) - - # need to dig around and get the OK button since we show this dialog modelessly now. - okButton = self.FindWindow(self.GetAffirmativeId()) - okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) - - # Wrap everything in a vbox to add some padding - vbox = wx.BoxSizer(wx.VERTICAL); - vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); - - self.SetSizerAndFit(vbox); - self.Layout() - self.Fit() - self.SetFocus() - - # if we are loading from profile, ie, have "init", build the list from it - if init: self.LoadFromData(init) - - def LoadFromData(self, init): - for item in init: - for type, data in item.items(): - commandClass = commandClasses.get(type, None) - if not commandClass: - commandClass = deprecatedCommandClasses.get(type, None) - if not commandClass: - wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") - continue - newCommand = commandClass(self.EditDialog, data) - index = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.SetClientData(index, newCommand) - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) - self.EditDialog.mainSizer.Hide(newCommand.UI) - self.UpdateBindStringDisplay() - - def SaveToData(self): - data = [] - index = 0 - for _ in self.RearrangeList.GetItems(): - # check whether we have an object already attached to this choice - cmdObject = self.RearrangeList.GetClientData(index) - commandClassName = commandRevClasses[type(cmdObject)] - data.append({commandClassName: cmdObject.Serialize()}) - index = index + 1 - return data - - def OnAddStepButton(self, evt): - button = evt.EventObject - if not self.AddStepMenu: - self.AddStepMenu = self.makeAddStepMenu() - button.PopupMenu(self.AddStepMenu) - - - def OnOKButton(self, _): - if self.Button.tgtTxtCtrl: - bindString = self.MakeBindString() - if bindString != self.Button.tgtTxtCtrl.GetValue(): - self.Button.tgtTxtCtrl.SetValue(bindString) - wx.App.Get().Main.Profile.SetModified() - self.Close() - - def OnRearrangeDelete(self, _): - current = self.RearrangeList.GetSelection() - if current == wx.NOT_FOUND: return - - self.RearrangeList.Delete(current) - self.UpdateBindStringDisplay() - - def OnRearrangeUp(self, _): - self.RearrangeList.MoveCurrentUp() - self.UpdateBindStringDisplay() - - def OnRearrangeDown(self, _): - self.RearrangeList.MoveCurrentDown() - self.UpdateBindStringDisplay() - - def OnRearrangeEdit(self, _): - index = self.RearrangeList.GetSelection() - - # check whether we have an object already attached to this choice - cmdObject = None - try: - cmdObject = self.RearrangeList.GetClientData(index) - except Exception: - pass - - if cmdObject: - self.ShowEditDialogFor(cmdObject) - self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) - else: - print("cmdObject was None") - self.UpdateBindStringDisplay() - - # OnAddStepMenu creates a new step and adds it to the rearrangelist - def OnAddStepMenu(self, evt): - menuitem = self.AddStepMenu.FindItemById(evt.GetId()) - chosenName = menuitem.GetItemLabel() - - # make a new command object, attached to the parent dialog - newCommandClass = commandClasses[chosenName] - newCommand = newCommandClass(self.EditDialog) - - # show the edit dialog if this command needs it - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) - if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): - self.EditDialog.mainSizer.Remove(newCommand.UI) - return - - newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.Select(newBindIndex) - self.RearrangeList.SetClientData(newBindIndex, newCommand) - - self.OnListSelect() - self.UpdateBindStringDisplay() - - def OnListSelect(self, _ = None): - selected = self.RearrangeList.GetSelection() - - if selected != wx.NOT_FOUND: - selCommand = self.RearrangeList.GetClientData(selected) - if selCommand.UI: - self.EditButton.Enable() - else: - self.EditButton.Disable() - - def UpdateBindStringDisplay(self): - self.BindStringDisplay.SetValue(self.MakeBindString()) - self.BindStringDisplay.SetToolTip(self.MakeBindString()) - - def MakeBindString(self): - cmdBindStrings = [] - for index in range(self.RearrangeList.GetCount()): - c = self.RearrangeList.GetClientData(index) - if c: cmdBindStrings.append(c.MakeBindString()) - - bindstring = ('$$'.join(cmdBindStrings)) - return bindstring - - def ShowEditDialogFor(self, command): - if not command.UI: return - - self.EditDialog.mainSizer.Show(command.UI) - - self.EditDialog.Layout() - self.EditDialog.Fit() - - self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') - returnval = self.EditDialog.ShowModal() - - self.EditDialog.mainSizer.Hide(command.UI) - - return returnval - - def makeAddStepMenu(self): - - stepMenu = wx.Menu() - - for subname in menuStructure: - submenu = wx.Menu() - stepMenu.AppendSubMenu(submenu, subname) - for classname in menuStructure[subname]: - submenu.Append(wx.ID_ANY, classname) - - stepMenu.Append(wx.ID_ANY, 'Custom Bind') - - return stepMenu - -class PowerBinderButton(wx.BitmapButton): - - def __init__(self, parent, tgtTxtCtrl, init = {}): - wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) - self.Init = init - self.Dialog = None - self.DialogParent = parent - - self.tgtTxtCtrl = tgtTxtCtrl - self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) - self.SetToolTip("Launch PowerBinder") - - def PowerBinderEventHandler(self, _): - self.PowerBinderDialog().Show() - - def LoadFromData(self, data): - self.PowerBinderDialog().LoadFromData(data) - - def SaveToData(self): - return self.PowerBinderDialog().SaveToData() - - def PowerBinderDialog(self): - if not self.Dialog: - self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) - return self.Dialog - - -class PowerBinderEditDialog(wx.Dialog): - def __init__(self, parent): - wx.Dialog.__init__(self, parent, -1, "Edit Step", - style = wx.DEFAULT_DIALOG_STYLE) - - outerSizer = wx.BoxSizer(wx.VERTICAL) - - self.mainSizer = wx.BoxSizer(wx.VERTICAL) - self.mainSizer.SetMinSize([500, 150]) - - self.Page = parent.Page - - self.mainSizer.Add( - self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), - 0, wx.EXPAND|wx.ALL, 10) - - outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) - - self.SetSizerAndFit(outerSizer) - self.Layout() - self.Fit() - -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" +from wx.adv import EditableListBox +from UI.PowerBinderCommand import PowerBinderCommand +####### Attribute Monitor +class AttributeMonitorCmd(PowerBinderCommand): + Name = "Attribute Monitor" + Menu = "Graphics / UI" -####### Away From Keyboard -class AFKCmd(PowerBindCmd): def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): self.Page = dialog.Page - self.Groups = {} self.AttributeTable = { 'Base' : { 'Current Hit Points' : 'NT H', @@ -421,9 +98,6 @@ def __init__(self, dialog, init = {}): 'Level Shift' : 'L S', }, } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): groupSizer = wx.BoxSizer(wx.HORIZONTAL) self.AttributeMenu = wx.Menu() @@ -472,1329 +146,3 @@ def OnMenuItem(self, evt): existingstrings = self.editbox.GetStrings() existingstrings.append(menuitem.GetItemLabel()) self.editbox.SetStrings(existingstrings) - -####### Auto Power -class AutoPowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) - autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.autoPowerName = PowerPicker(dialog) - autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) - - return autoPowerSizer - - def MakeBindString(self): - return f"powexecauto {self.autoPowerName.GetLabel()}" - - def Serialize(self): - return { - 'pname' : self.autoPowerName.GetLabel(), - 'picon' : self.autoPowerName.IconFilename - } - - def Deserialize(self, init): - if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.buffDisplayMap = { - 'Status Window' : { - 'Hide Auto' : 1, - 'Hide Toggles' : 2, - 'No Blinking' : 4, - 'No Stacking' : 8, - 'Numeric Stacking' : 16, - 'Hide Buff Numbers' : 32, - 'Stop Sending Buffs' : 64, - }, - 'Group Window' : { - 'Hide Auto' : 256, - 'Hide Toggles' : 512, - 'No Blinking' : 1024, - 'No Stacking' : 2048, - 'Numeric Stacking' : 4096, - 'Hide Buff Numbers' : 8192, - 'Stop Sending Buffs' : 16384, - }, - 'Pet Window' : { - 'Hide Auto' : 65536, - 'Hide Toggles' : 131072, - 'No Blinking' : 262144, - 'No Stacking' : 524288, - 'Numeric Stacking' : 1048576, - 'Hide Buff Numbers' : 2097152, - 'Stop Sending Buffs' : 4194304, - }, - } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - for group, controls in self.buffDisplayMap.items(): - self.Groups[group] = ControlGroup(dialog, self.Page, label = group) - groupid = self.Groups[group].GetStaticBox().GetId() - for cb, data in controls.items(): - self.Groups[group].AddControl( - ctlType = 'checkbox', - ctlName = f"{groupid}_{group}_{cb}", - label = cb, - data = data, - ) - - groupSizer.Add(self.Groups[group]) - - return groupSizer - - def CalculateValue(self): - page = wx.App.Get().Main.Profile.CustomBinds - - total = 0 - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] - if checkbox.IsChecked(): - total = total + checkbox.Data - return total - - def MakeBindString(self): - return f"optionset buffsettings {self.CalculateValue()}" - - def Serialize(self): - return { 'value' : self.CalculateValue() } - - def Deserialize(self, init): - value = init.get('value', 0) - - value = value or 0 # in case we had for some reason 'None' stashed in the init values - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] - checkbox.SetValue( checkbox.Data & value ) - -####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - chatCommandSizer = wx.GridBagSizer(5, 5) - self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") - chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) - # row 1 - self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) - self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) - self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) - # row 2 - self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) - self.chatCommandDuration.SetRange(1, 20) - self.chatCommandDuration.SetValue(7) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandDuration, (2,1)) - self.chatCommandChatSize = wx.Choice(dialog, -1, - choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) - self.chatCommandChatSize.SetSelection(5) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) - self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) - self.chatCommandChannel.SetSelection(0) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChannel, (2,5)) - # row 3 - self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") - chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) - self.chatCommandMessage = wx.TextCtrl(dialog, -1) - self.chatCommandMessage.SetHint('Chat Command Text') - chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) - - return chatCommandSizer - - def MakeBindString(self): - duration = self.chatCommandDuration.GetValue() - - choice = self.chatCommandChatSize - index = choice.GetSelection() - size = choice.GetString(index) - - duration = f"" if duration != 7 else "" - size = f"" if size != "1" else "" - - bdcolor = fgcolor = bgcolor = '' - if self.chatCommandUseColorsCB.IsChecked(): - bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - - bdcolor = f"" - fgcolor = f"" - bgcolor = f"" - - beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' - text = self.chatCommandMessage.GetValue() - - choice = self.chatCommandChannel - index = choice.GetSelection() - channel = choice.GetString(index) - - return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" - - def Serialize(self): - return { - 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), - 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), - 'channel' : self.chatCommandChannel .GetSelection(), - 'size' : self.chatCommandChatSize.GetSelection(), - 'duration' : self.chatCommandDuration.GetValue(), - 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'text' : self.chatCommandMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) - if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) - if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) - if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) - if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) - if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) - if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) - if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) - if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - - -####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): - def BuildUI(self, dialog): - chatCommandGlobalSizer = wx.GridBagSizer(5,5) - - self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") - chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) - - self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalChannel.SetHint("Channel") - chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) - - self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') - chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) - - chatCommandGlobalSizer.AddGrowableCol(1) - - return chatCommandGlobalSizer - - def MakeBindString(self): - useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() - channel = self.chatCommandGlobalChannel.GetValue() - message = self.chatCommandGlobalMessage.GetValue() - - preface = "beginchat /" if useBeginchat else "" - - return f'{preface}send "{channel}" {message}' - - def Serialize(self): - return { - 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), - 'channel' : self.chatCommandGlobalChannel.GetValue(), - 'message' : self.chatCommandGlobalMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) - if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) - if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) - -#######Costume Change -class CostumeChangeCmd(PowerBindCmd): - def BuildUI(self, dialog): - costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeCostume = wx.Choice(dialog, -1, - choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) - self.costumeChangeCostume.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeEmote = wx.Choice(dialog, -1, - choices = GameData.Emotes['costumechange']) - self.costumeChangeEmote.Insert("- None -", 0) - self.costumeChangeEmote.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return costumeChangeSizer - - def MakeBindString(self): - costumeNumber = self.costumeChangeCostume.GetSelection() - costumeEmote = self.costumeChangeEmote.GetSelection() - - if costumeEmote: # None, or 0 == "- None -" - ccCmd = 'cce' - emoteName = self.costumeChangeEmote.GetString(costumeEmote) - emoteName = " CC" + emoteName.replace(" ","") - else: - ccCmd = 'cc' - emoteName = '' - - return f"{ccCmd} {costumeNumber}{emoteName}" - - def Serialize(self): - return{ - 'costumeNumber': self.costumeChangeCostume.GetSelection(), - 'costumeEmote' : self.costumeChangeEmote.GetSelection(), - } - - def Deserialize(self, init): - if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) - if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) - -####### Movement Command -class MovementCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - self.plusbutton.SetValue(True) - - self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.commandchoice = wx.Choice(dialog, choices = [ - "forward", "left", "right", "backward", "up", "down", - "turnleft", "turnright", "first", "autorun", "clicktomove", - ],) - sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) - self.commandchoice.SetSelection(0) - - self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - pre = post = '' - if self.plusbutton.GetValue() : pre = "+" - elif self.plusplusbutton.GetValue() : pre = "++" - elif self.minusbutton.GetValue() : pre = "-" - elif self.zerobutton.GetValue() : post = " 0" - elif self.onebutton.GetValue() : post = " 1" - - command = self.commandchoice.GetString(self.commandchoice.GetSelection()) - - return f"{pre}{command}{post}" - - def Serialize(self): - mod = '' - if self.plusbutton.GetValue() : mod = "plus" - elif self.plusplusbutton.GetValue() : mod = "plusplus" - elif self.minusbutton.GetValue() : mod = "minus" - elif self.zerobutton.GetValue() : mod = "zero" - elif self.onebutton.GetValue() : mod = "one" - - return { - 'mod' : mod, - 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), - } - - def Deserialize(self, init): - mod = init.get('mod', 'plus') - - if mod == 'plus' : self.plusbutton.SetValue(True) - elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) - elif mod == 'minus' : self.minusbutton.SetValue(True) - elif mod == 'zero' : self.zerobutton.SetValue(True) - elif mod == 'one' : self.onebutton.SetValue(True) - - self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) - -####### Graphics Command -class GraphicsCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.FlexGridSizer(2) - - self.visscalecb = wx.CheckBox(dialog, label = "visscale") - sizer.Add(self.visscalecb) - self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) - sizer.Add(self.visscalesc) - - self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") - sizer.Add(self.dofweightcb) - self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) - sizer.Add(self.dofweightsc) - - self.fsaacb = wx.CheckBox(dialog, label = "fsaa") - sizer.Add(self.fsaacb) - self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) - self.fsaach.SetSelection(0) - sizer.Add(self.fsaach) - - self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") - sizer.Add(self.bloomscalecb) - self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) - self.bloomscalech.SetSelection(0) - sizer.Add(self.bloomscalech) - - self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") - sizer.Add(self.bloomweightcb) - self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) - sizer.Add(self.bloomweightsc) - - self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") - sizer.Add(self.lodbiascb) - self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) - sizer.Add(self.lodbiassc) - - self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") - sizer.Add(self.renderscalecb) - self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) - sizer.Add(self.renderscalesc) - - return sizer - - def MakeBindString(self): - # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. - bindstrings = [] - if self.visscalecb.IsChecked(): - bindstrings.append("visscale " + str(self.visscalesc.GetValue())) - if self.dofweightcb.IsChecked(): - bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) - if self.fsaacb.IsChecked(): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bindstrings.append("fsaa " + fsaavalue) - if self.bloomscalecb.IsChecked(): - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - bindstrings.append("bloomscale " + bloomscalevalue) - if self.bloomweightcb.IsChecked(): - bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) - if self.lodbiascb.IsChecked(): - bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) - if self.renderscalecb.IsChecked(): - bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) - - return '$$'.join(bindstrings) - - def Serialize(self): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - return { - 'visscalecb' : self.visscalecb.IsChecked(), - 'visscalesc' : self.visscalesc.GetValue(), - 'dofweightcb' : self.dofweightcb.IsChecked(), - 'dofweightsc' : self.dofweightsc.GetValue(), - 'fsaacb' : self.fsaacb.IsChecked(), - 'fsaach' : fsaavalue, - 'bloomscalecb' : self.bloomscalecb.IsChecked(), - 'bloomscalech' : bloomscalevalue, - 'bloomweightcb' : self.bloomweightcb.IsChecked(), - 'bloomweightsc' : self.bloomweightsc.GetValue(), - 'lodbiascb' : self.lodbiascb.IsChecked(), - 'lodbiassc' : self.lodbiassc.GetValue(), - 'renderscalecb' : self.renderscalecb.IsChecked(), - 'renderscalesc' : self.renderscalesc.GetValue(), - } - - def Deserialize(self, init): - self.visscalecb.SetValue(init.get('visscalecb', False)) - self.visscalesc.SetValue(init.get('visscalesc', 1.0)) - self.dofweightcb.SetValue(init.get('dofweightcb', False)) - self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) - self.fsaacb.SetValue(init.get('fsaacb', False)) - self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) - self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) - self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) - self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) - self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) - self.lodbiascb.SetValue(init.get('lodbiascb', False)) - self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) - self.renderscalecb.SetValue(init.get('renderscalecb', False)) - self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) - -####### Custom Bind -class CustomBindCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.customBindName = wx.TextCtrl(dialog, -1) - self.customBindName.SetHint('Custom Bind Text') - sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - return self.customBindName.GetValue() - - def Serialize(self): - return { 'customBindName': self.customBindName.GetValue() } - - def Deserialize(self,init): - if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) - -####### Emote -class EmoteCmd(PowerBindCmd): - def BuildUI(self, dialog): - emoteSizer = wx.BoxSizer(wx.HORIZONTAL) - self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") - emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - self.emoteName = wx.Button(dialog, -1, "...") - self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) - emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) - - return emoteSizer - - def MakeBindString(self): - displayedEmoteName = self.emoteName.GetLabel() - actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] - - return actualEmotePayload - - def Serialize(self): - return {'emoteName': self.emoteName.GetLabel()} - - def Deserialize(self, init): - if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) - -####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): - def BuildUI(self, dialog): - mainSizer = wx.BoxSizer(wx.VERTICAL) - - lbSizer = wx.BoxSizer(wx.HORIZONTAL) - lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") - lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - profiles = Profile.GetAllProfileBindsDirs() - - self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) - lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) - - mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") - self.lbResetCB.SetValue(True) - - mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - return mainSizer - - def MakeBindString(self): - - # If the specified binds directory disappeared between runs, we'd crash, so handle that. - if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' - - config = wx.ConfigBase.Get() - if config.Exists('GameBindPath'): - bindpath = config.Read('GameBindPath') - else: - bindpath = config.Read('BindPath') - - reset = "" - if self.lbResetCB.GetValue(): - reset = "keybind_reset$$" - - resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' - return reset + 'bindloadfile ' + str(resetfilepath) - - def Serialize(self): - return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), - 'ResetKeybinds' : self.lbResetCB.GetValue(), - } - - def Deserialize(self, init): - if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) - self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) - -####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' - -####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' - -####### SG Mode -class SGModeCmd(PowerBindCmd): - def BuildUI(self, dialog): - sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) - sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") - self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") - - sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) - - return sgmodeSizer - - def MakeBindString(self): - if self.sgmodeOnRB.GetValue(): - return 'sgmodeset 1' - elif self.sgmodeOffRB.GetValue(): - return 'sgmodeset 0' - else: - return 'sgmode' - - def Serialize(self): - if self.sgmodeOnRB.GetValue(): - val = "On" - elif self.sgmodeOffRB.GetValue(): - val = "Off" - else: - val = "Toggle" - - return {"value" : val} - - def Deserialize(self, init): - val = init.get('value', '') - if val == "On": - self.sgmodeOnRB.SetValue(True) - elif val == "Off": - self.sgmodeOffRB.SetValue(True) - else: - self.sgmodeToggleRB.SetValue(True) - -####### Target Custom -class TargetCustomCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetCustomSizer = wx.GridBagSizer(5,5) - targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), - flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) - self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetCustomModeChoice.SetSelection(0) - targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) - self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) - self.targetCustomOptionalName.SetHint("Optional name to match") - targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) - self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") - targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) - self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") - targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) - self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") - targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) - self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") - targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) - self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") - targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) - self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") - targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) - self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") - targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) - self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") - targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) - - targetCustomSizer.AddGrowableCol(2) - - return targetCustomSizer - - def MakeBindString(self): - choice = self.targetCustomModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - targetCommand = "targetcustom" + mode.lower() - - enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" - friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" - defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" - alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" - mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" - notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" - base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" - notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" - - name = self.targetCustomOptionalName.GetValue() - - return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" - - def Serialize(self): - return { - 'mode' : self.targetCustomModeChoice.GetSelection(), - 'enemy' : self.targetCustomCBEnemies. IsChecked(), - 'friend' : self.targetCustomCBFriends. IsChecked(), - 'defeated' : self.targetCustomCBDefeated. IsChecked(), - 'alive' : self.targetCustomCBAlive. IsChecked(), - 'mypet' : self.targetCustomCBMyPets. IsChecked(), - 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), - 'base' : self.targetCustomCBBaseItems. IsChecked(), - 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), - 'name' : self.targetCustomOptionalName.GetValue(), - } - - def Deserialize(self, init): - if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) - if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) - if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) - if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) - if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) - if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) - if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) - if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) - if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) - if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - - -####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) - targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetEnemyModeChoice.SetSelection(0) - targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetEnemySizer - - def MakeBindString(self): - choice = self.targetEnemyModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetenemy" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetEnemyModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) - -####### Target Friend -class TargetFriendCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) - targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetFriendModeChoice.SetSelection(0) - targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetFriendSizer - - def MakeBindString(self): - choice = self.targetFriendModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetfriend" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetFriendModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) - -####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): - def BuildUI(self, dialog): - teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], - style=wx.ALIGN_CENTER_VERTICAL) - self.teamPetSelectNumber.SetSelection(0) - teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) - - return teamPetSelectSizer - - def MakeBindString(self): - teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' - targetNumber = self.teamPetSelectNumber.GetSelection()+1 - - return f"{teamOrPet}select {targetNumber}" - - def Serialize(self): - return { - 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', - 'targetNum': self.teamPetSelectNumber.GetSelection(), - } - - def Deserialize(self, init): - ToP = init.get('teamOrPet', '') - if ToP == 'pet': - self.teamPetSelectPetRB.SetValue(True) - else: - self.teamPetSelectTeamRB.SetValue(True) - if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) - -####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' - -####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) - for _, types in GameData.Inspirations.items(): - for _, info in types.items(): - for insp in info['tiers']: - name = re.sub(' ', '', str(insp)) - icon = GetIcon(f'Inspirations/{name}') - self.useInspByNameModeChoice.Append(insp, icon) - self.useInspByNameModeChoice.SetSelection(0) - useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) - - return useInspByNameSizer - - def MakeBindString(self): - choice = self.useInspByNameModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "inspexecname " + mode.lower() - - def GetAllInsps(self): - Insplist = [] - for _, info in GameData.Inspirations.items(): - for insp in info['tiers']: - Insplist.append(insp) - Insplist.append("---") - Insplist.pop(-1) # snip the terminal "---" - - return Insplist - - def Serialize(self): - return { 'insp' : self.useInspByNameModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) - -####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnRow.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) - self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnCol.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) - - return useInspRowColumnSizer - - def MakeBindString(self): - row = self.useInspRowColumnRow.GetSelection()+1 - col = self.useInspRowColumnCol.GetSelection()+1 - - return f"inspexectray {col} {row}" - - def Serialize(self): - return { - 'col' : self.useInspRowColumnCol.GetSelection(), - 'row' : self.useInspRowColumnRow.GetSelection(), - } - - def Deserialize(self, init): - if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) - if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) - -####### Use Power -class UsePowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - outerSizer = wx.BoxSizer(wx.HORIZONTAL) - - usePowerSizer = wx.GridBagSizer(5,5) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBToggle, (0,1)) - self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOn, (0,2)) - self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOff, (0,3)) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerName = PowerPicker(dialog) - usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) - usePowerSizer.AddGrowableCol(3) - - outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) - - return outerSizer - - def MakeBindString(self): - if self.usePowerRBToggle.GetValue(): - method = "powexecname" - elif self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') - return '' - - return f"{method} {self.usePowerName.GetLabel()}" - - def Serialize(self): - if self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - method = "powexecname" - return { - 'method': method, - 'pname' : self.usePowerName.GetLabel(), - 'picon' : self.usePowerName.IconFilename - } - - def Deserialize(self, init): - method = init.get('method', '') - if method == 'powexectoggleon': - self.usePowerRBOn.SetValue(True) - elif method == 'powexectoggleoff': - self.usePowerRBOff.SetValue(True) - else: - self.usePowerRBToggle.SetValue(True) - if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) - -####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): - def BuildUI(self, dialog): - usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTrayTray = wx.Choice(dialog, -1, - choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', - 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) - self.usePowerFromTrayTray.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) - self.usePowerFromTraySlot.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return usePowerFromTraySizer - - def MakeBindString(self): - choice = self.usePowerFromTrayTray - tray = choice.GetSelection() - - choice = self.usePowerFromTraySlot - slot = choice.GetSelection()+1 - - mode = "slot" - mode2 = '' - if tray > 3: - mode = "tray" - mode2 = f" {tray - 3}" - elif tray == 3: - mode = "alt2slot" - elif tray == 2: - mode = "altslot" - - return f"powexec{mode} {slot}{mode2}" - - def Serialize(self): - return { - 'tray' : self.usePowerFromTrayTray.GetSelection(), - 'slot' : self.usePowerFromTraySlot.GetSelection(), - } - - def Deserialize(self, init): - if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) - if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) - -####### Window Color -class WindowColorCmd(PowerBindCmd): - def BuildUI(self, dialog): - windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) - borderSizer = wx.BoxSizer(wx.VERTICAL) - self.ColorBorder.SetSizer(borderSizer) - self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) - borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) - - windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) - - RGBASizer = wx.FlexGridSizer(3, 4, 5) - - RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) - self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) - self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - windowColorSizer.Add(RGBASizer) - - self.UpdateFromSlider() - - return windowColorSizer - - def MakeBindString(self): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - return f"windowcolor {Rval} {Gval} {Bval} {Aval}" - - def Serialize(self): - return { - 'Rval' : self.RSlider.GetValue(), - 'Gval' : self.GSlider.GetValue(), - 'Bval' : self.BSlider.GetValue(), - 'Aval' : self.ASlider.GetValue(), - } - - def Deserialize(self, init): - self.RSlider.SetValue(init['Rval']) - self.GSlider.SetValue(init['Gval']) - self.BSlider.SetValue(init['Bval']) - self.ASlider.SetValue(init['Aval']) - self.UpdateFromSlider() - - def UpdateFromSlider(self, _ = None): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RReadout.SetValue(Rval) - self.GReadout.SetValue(Gval) - self.BReadout.SetValue(Bval) - self.AReadout.SetValue(Aval) - self.ColorBorder.Refresh() - - def UpdateFromText(self, _ = None): - Rval = self.RReadout.GetValue() - Gval = self.GReadout.GetValue() - Bval = self.BReadout.GetValue() - Aval = self.AReadout.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RSlider.SetValue(Rval) - self.GSlider.SetValue(Gval) - self.BSlider.SetValue(Bval) - self.ASlider.SetValue(Aval) - self.ColorBorder.Refresh() - -####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) - self.CommandChoice.SetSelection(0) - sizer.Add(self.CommandChoice, 0, wx.ALL, 5) - - self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), - value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) - sizer.Add(self.FilePath, 0, wx.ALL, 5) - - return sizer - - def MakeBindString(self): - command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] - return f'{command} "{self.FilePath.GetValue()}"' - - def Serialize(self): - return { - 'command' : self.CommandChoice.GetSelection(), - 'filename' : self.FilePath.GetValue(), - } - - def Deserialize(self, init): - self.CommandChoice.SetSelection(init.get('command', 0)) - self.FilePath.SetValue(init.get('filename', '')) - -####### Window Toggle -class WindowToggleCmd(PowerBindCmd): - def BuildUI(self, dialog): - self.WindowNames = { - 'Actions' : 'actions', - 'Auction House' : 'ah', - 'Badge' : 'badge', - 'Channel Search' : 'chansearch', - 'Chat' : 'chat', - 'Custom Chat 1' : 'chat1', - 'Custom Chat 2' : 'chat2', - 'Custom Chat 3' : 'chat3', - 'Custom Chat 4' : 'chat4', - 'Clues' : 'clue', - 'Combat Numbers' : 'combatnumbers', - 'Contacts' : 'contact', - 'Contact Finder' : 'contactfinder', - 'Costumes' : 'costume', - 'Email' : 'email', - 'Enhancements' : 'enhancements', - 'Friends' : 'friend', - 'Group' : 'group', - 'Help' : 'helpwindow', - 'Incarnate' : 'incarnate', - 'Inspirations' : 'insp', - 'League' : 'league', - 'LFG' : 'lfg', - 'Map' : 'map', - 'Mission' : 'mission', - 'Nav / Compass' : 'nav', - 'Options' : 'options', - 'Pets' : 'pet', - 'Petition' : 'petition', - 'Power Tray' : 'powers', - 'Power List' : 'powerlist', - 'Quit' : 'quit', - 'Recipes' : 'recipe', - 'Salvage' : 'salvage', - 'Search' : 'search', - 'Supergroup' : 'sg', - 'Target' : 'target', - 'Team' : 'team', - 'Tray' : 'tray', - 'Tray1' : 'tray1', - 'Tray2' : 'tray2', - 'Tray3' : 'tray3', - 'Tray4' : 'tray4', - 'Tray5' : 'tray5', - 'Tray6' : 'tray6', - 'Tray7' : 'tray7', - 'Tray8' : 'tray8', - 'Vault' : 'vault', - } - - self.ShortToggleCommands = { - 'Auction House' : 'ah', - 'Chat' : 'chat', - 'Help' : 'helpwindow', - 'Map' : 'map', - 'Nav / Compass' : 'nav', - 'Power Tray' : 'powers', - 'Target' : 'target', - 'Tray' : 'tray', - } - - windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) - windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) - self.windowToggleTray.SetSelection(0) - windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.windowShowRB = wx.RadioButton(dialog, -1, "Show") - self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") - - windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) - - return windowToggleSizer - - def MakeBindString(self): - choice = self.windowToggleTray - index = choice.GetSelection() - windowdesc = choice.GetString(index) - windowname = self.WindowNames[windowdesc] - - if self.windowShowRB.GetValue(): - return 'show ' + windowname - elif self.windowHideRB.GetValue(): - return 'windowhide ' + windowname - else: - if shortcmd := self.ShortToggleCommands.get(windowdesc, None): - return shortcmd - else: - return 'toggle ' + windowname - - - def Serialize(self): - choice = self.windowToggleTray - if self.windowShowRB.GetValue(): - action = "Show" - elif self.windowHideRB.GetValue(): - action = "Hide" - else: - action = "Toggle" - return { - 'window': choice.GetString(choice.GetSelection()), - 'action': action, - } - - def Deserialize(self, init): - choice = self.windowToggleTray - if window := init.get('window', ''): - if isinstance(window, int): - choice.SetSelection(window) - else: - choice.SetSelection(choice.FindString(window)) - - if choice.GetSelection() == wx.NOT_FOUND: - choice.SetSelection(0) - - action = init.get('action', '') - if action == "Show": - self.windowShowRB.SetValue(True) - elif action == "Hide": - self.windowHideRB.SetValue(True) - else: - self.windowToggleRB.SetValue(True) - - -# Must always add to this list when adding a new command class above -menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], - # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, - # but I'm leaving it here to remind myself that we do that. - } - -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/AutoPowerCmd.py b/UI/PowerBinderCommand/AutoPowerCmd.py index 4c02ab7..1bb3fd6 100644 --- a/UI/PowerBinderCommand/AutoPowerCmd.py +++ b/UI/PowerBinderCommand/AutoPowerCmd.py @@ -1,480 +1,12 @@ import wx -import re -import UI -import UI.EmotePicker -from UI.ControlGroup import ControlGroup from UI.PowerPicker import PowerPicker -from Help import HelpButton -import wx.adv -from wx.adv import BitmapComboBox, EditableListBox -from pathlib import PureWindowsPath -import GameData -import Profile from Icon import GetIcon - -class PowerBinderDialog(wx.Dialog): - def __init__(self, parent, button, init = {}): - wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) - - self.Page = parent.Page - self.EditDialog = PowerBinderEditDialog(self) - self.Button = button - self.AddStepMenu = self.makeAddStepMenu() - - sizer = wx.BoxSizer(wx.VERTICAL); - self.mainSizer = sizer - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) - AddStepButton = wx.Button(self, -1, 'Add Step') - AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) - AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) - choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) - choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) - sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) - - rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) - - self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) - self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) - self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) - rearrangeCtrl.Add(self.RearrangeList, 1) - - rearrangeButtons = wx.BoxSizer(wx.VERTICAL) - self.DelButton = wx.Button(self, -1, "Delete") - self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) - self.EditButton = wx.Button(self, -1, "Edit") - self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) - self.EditButton.Disable() - upButton = wx.Button(self, -1, "\u25B2") - upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) - downButton = wx.Button(self, -1, "\u25BC") - downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) - rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) - rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) - - sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.BindStringDisplay = wx.TextCtrl(self, -1) - self.BindStringDisplay.Disable() - choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, - wx.ALIGN_CENTER_VERTICAL) - choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) - - sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) - - sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) - - # need to dig around and get the OK button since we show this dialog modelessly now. - okButton = self.FindWindow(self.GetAffirmativeId()) - okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) - - # Wrap everything in a vbox to add some padding - vbox = wx.BoxSizer(wx.VERTICAL); - vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); - - self.SetSizerAndFit(vbox); - self.Layout() - self.Fit() - self.SetFocus() - - # if we are loading from profile, ie, have "init", build the list from it - if init: self.LoadFromData(init) - - def LoadFromData(self, init): - for item in init: - for type, data in item.items(): - commandClass = commandClasses.get(type, None) - if not commandClass: - commandClass = deprecatedCommandClasses.get(type, None) - if not commandClass: - wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") - continue - newCommand = commandClass(self.EditDialog, data) - index = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.SetClientData(index, newCommand) - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) - self.EditDialog.mainSizer.Hide(newCommand.UI) - self.UpdateBindStringDisplay() - - def SaveToData(self): - data = [] - index = 0 - for _ in self.RearrangeList.GetItems(): - # check whether we have an object already attached to this choice - cmdObject = self.RearrangeList.GetClientData(index) - commandClassName = commandRevClasses[type(cmdObject)] - data.append({commandClassName: cmdObject.Serialize()}) - index = index + 1 - return data - - def OnAddStepButton(self, evt): - button = evt.EventObject - if not self.AddStepMenu: - self.AddStepMenu = self.makeAddStepMenu() - button.PopupMenu(self.AddStepMenu) - - - def OnOKButton(self, _): - if self.Button.tgtTxtCtrl: - bindString = self.MakeBindString() - if bindString != self.Button.tgtTxtCtrl.GetValue(): - self.Button.tgtTxtCtrl.SetValue(bindString) - wx.App.Get().Main.Profile.SetModified() - self.Close() - - def OnRearrangeDelete(self, _): - current = self.RearrangeList.GetSelection() - if current == wx.NOT_FOUND: return - - self.RearrangeList.Delete(current) - self.UpdateBindStringDisplay() - - def OnRearrangeUp(self, _): - self.RearrangeList.MoveCurrentUp() - self.UpdateBindStringDisplay() - - def OnRearrangeDown(self, _): - self.RearrangeList.MoveCurrentDown() - self.UpdateBindStringDisplay() - - def OnRearrangeEdit(self, _): - index = self.RearrangeList.GetSelection() - - # check whether we have an object already attached to this choice - cmdObject = None - try: - cmdObject = self.RearrangeList.GetClientData(index) - except Exception: - pass - - if cmdObject: - self.ShowEditDialogFor(cmdObject) - self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) - else: - print("cmdObject was None") - self.UpdateBindStringDisplay() - - # OnAddStepMenu creates a new step and adds it to the rearrangelist - def OnAddStepMenu(self, evt): - menuitem = self.AddStepMenu.FindItemById(evt.GetId()) - chosenName = menuitem.GetItemLabel() - - # make a new command object, attached to the parent dialog - newCommandClass = commandClasses[chosenName] - newCommand = newCommandClass(self.EditDialog) - - # show the edit dialog if this command needs it - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) - if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): - self.EditDialog.mainSizer.Remove(newCommand.UI) - return - - newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.Select(newBindIndex) - self.RearrangeList.SetClientData(newBindIndex, newCommand) - - self.OnListSelect() - self.UpdateBindStringDisplay() - - def OnListSelect(self, _ = None): - selected = self.RearrangeList.GetSelection() - - if selected != wx.NOT_FOUND: - selCommand = self.RearrangeList.GetClientData(selected) - if selCommand.UI: - self.EditButton.Enable() - else: - self.EditButton.Disable() - - def UpdateBindStringDisplay(self): - self.BindStringDisplay.SetValue(self.MakeBindString()) - self.BindStringDisplay.SetToolTip(self.MakeBindString()) - - def MakeBindString(self): - cmdBindStrings = [] - for index in range(self.RearrangeList.GetCount()): - c = self.RearrangeList.GetClientData(index) - if c: cmdBindStrings.append(c.MakeBindString()) - - bindstring = ('$$'.join(cmdBindStrings)) - return bindstring - - def ShowEditDialogFor(self, command): - if not command.UI: return - - self.EditDialog.mainSizer.Show(command.UI) - - self.EditDialog.Layout() - self.EditDialog.Fit() - - self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') - returnval = self.EditDialog.ShowModal() - - self.EditDialog.mainSizer.Hide(command.UI) - - return returnval - - def makeAddStepMenu(self): - - stepMenu = wx.Menu() - - for subname in menuStructure: - submenu = wx.Menu() - stepMenu.AppendSubMenu(submenu, subname) - for classname in menuStructure[subname]: - submenu.Append(wx.ID_ANY, classname) - - stepMenu.Append(wx.ID_ANY, 'Custom Bind') - - return stepMenu - -class PowerBinderButton(wx.BitmapButton): - - def __init__(self, parent, tgtTxtCtrl, init = {}): - wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) - self.Init = init - self.Dialog = None - self.DialogParent = parent - - self.tgtTxtCtrl = tgtTxtCtrl - self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) - self.SetToolTip("Launch PowerBinder") - - def PowerBinderEventHandler(self, _): - self.PowerBinderDialog().Show() - - def LoadFromData(self, data): - self.PowerBinderDialog().LoadFromData(data) - - def SaveToData(self): - return self.PowerBinderDialog().SaveToData() - - def PowerBinderDialog(self): - if not self.Dialog: - self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) - return self.Dialog - - -class PowerBinderEditDialog(wx.Dialog): - def __init__(self, parent): - wx.Dialog.__init__(self, parent, -1, "Edit Step", - style = wx.DEFAULT_DIALOG_STYLE) - - outerSizer = wx.BoxSizer(wx.VERTICAL) - - self.mainSizer = wx.BoxSizer(wx.VERTICAL) - self.mainSizer.SetMinSize([500, 150]) - - self.Page = parent.Page - - self.mainSizer.Add( - self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), - 0, wx.EXPAND|wx.ALL, 10) - - outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) - - self.SetSizerAndFit(outerSizer) - self.Layout() - self.Fit() - -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" - - -####### Away From Keyboard -class AFKCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.Groups = {} - self.AttributeTable = { - 'Base' : { - 'Current Hit Points' : 'NT H', - 'Max Hit Points' : 'X H', - 'Current Endurance' : 'T E', - 'Max Endurance' : 'X EN', - 'Regeneration Rate' : 'N RAT', - 'Recovery Rate' : 'Y RA', - 'Endurance Consumption' : 'SU', - 'ToHit Bonus' : 'T B', - 'Accuracy Bonus' : 'CC', - 'Last Hit Chance' : 'T C', - 'Damage Bonus' : 'DA', - 'Healing Bonus' : 'NG B', - 'Recharge Time Bonus' : 'ME B', - 'Endurance Discount' : 'CE DIS', - 'Stealth Radius (PvP)' : 'PVP', - 'Stealth Radius (PvE)' : 'PVE', - 'Perception Radius' : 'RC', - 'Range Bonus' : 'GE B', - 'Threat Level' : 'AT L', - 'Experience to Next Level' : 'XT', - 'Experience Debt' : 'XP', - 'Influence / Infamy' : 'INF', - 'Inherent' : 'NH', - }, - 'Movement Speed' : { - 'Flying Speed' : 'FL', - 'Jumping Speed' : 'PI', - 'Max Jump Height' : 'X J', - 'Run Speed' : 'RU', - }, - 'Damage Resistance' : { - 'Smashing Resistance' : 'G R', - 'Lethal Resistance' : 'L R', - 'Fire Resistance' : 'RE R', - 'Cold Resistance' : 'COLD R', - 'Energy Resistance' : 'DamageType[4]', - 'Negative Energy Resistance' : 'GY R', - 'Psyonic Resistance' : 'NIC R', - 'Toxic Resistance' : 'XIC R', - }, - 'Defense' : { - 'Base Defense' : 'BAS', - 'Ranged Defense' : 'ED', - 'Melee Defense' : 'MEL', - 'AoE Defense' : '2', - 'Smashing Defense' : '3', - 'Lethal Defense' : '4', - 'Fire Defense' : '5', - 'Cold Defense' : '6', - 'Energy Defense' : '7', - 'Negative Energy Defense' : '8', - 'Psionic Defense' : '9', - 'Toxic Defense' : '1', - }, - 'Debuff Resistance' : { - 'Regeneration Resistance' : 'ON R', - 'Recovery Resistance' : 'RY R', - 'To Hit Resistance' : 'IT R', - 'Defense Resistance' : 'NSE RES', - }, - 'Status Effect Protection' : { - 'Hold Protection' : 'D P', - 'Immobilize Protection' : 'LIZE P', - 'Stun Protection' : 'N P', - 'Sleep Protection' : 'P P', - 'Knockback Protection' : 'K P', - 'Confuse Protection' : 'SE P', - 'Terrorize Protection' : 'ZE P', - 'Repel Protection' : 'EL P', - 'Teleport Protection' : 'T P', - }, - 'Status Effect Resistance' : { - 'Hold Resistance' : 'D R', - 'Immobilize Resistance' : 'LIZE R', - 'Stun Resistance' : 'N R', - 'Sleep Resistance' : 'P R', - 'Knockback Resistance' : 'K R', - 'Confuse Resistance' : 'SE R', - 'Terrorize Resistance' : 'ZE R', - 'Placate Resistance' : 'TE R', - 'Taunt Resistance' : 'NT R', - }, - 'Miscellaneous' : { - 'Level Shift' : 'L S', - }, - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.AttributeMenu = wx.Menu() - for group, controls in self.AttributeTable.items(): - submenu = wx.Menu() - self.AttributeMenu.AppendSubMenu(submenu, group) - for cb in controls: - submenu.Append(wx.ID_ANY, cb) - - self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) - - self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) - groupSizer.Add(self.editbox) - - newButton = self.editbox.GetNewButton() - newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) - - return groupSizer - - def MakeBindString(self): - map = {} - bindstrings = [] - for _, controls in self.AttributeTable.items(): - for cb, data in controls.items(): - map[cb] = data - - for string in self.editbox.GetStrings(): - if string: - bindstrings.append(f'monitorattribute {map[string]}') - - return '$$'.join(bindstrings) - - def Serialize(self): - return { - 'attributes' : self.editbox.GetStrings() - } - - def Deserialize(self, init): - self.editbox.SetStrings(init.get('attributes', [])) - - def OnNewButton(self, evt): - evt.GetEventObject().PopupMenu(self.AttributeMenu) - - def OnMenuItem(self, evt): - menuitem = evt.EventObject.FindItemById(evt.GetId()) - existingstrings = self.editbox.GetStrings() - existingstrings.append(menuitem.GetItemLabel()) - self.editbox.SetStrings(existingstrings) +from UI.PowerBinderCommand import PowerBinderCommand ####### Auto Power -class AutoPowerCmd(PowerBindCmd): +class AutoPowerCmd(PowerBinderCommand): + Name = "Auto Power" + Menu = "Powers" def BuildUI(self, dialog): autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) @@ -495,1306 +27,3 @@ def Serialize(self): def Deserialize(self, init): if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.buffDisplayMap = { - 'Status Window' : { - 'Hide Auto' : 1, - 'Hide Toggles' : 2, - 'No Blinking' : 4, - 'No Stacking' : 8, - 'Numeric Stacking' : 16, - 'Hide Buff Numbers' : 32, - 'Stop Sending Buffs' : 64, - }, - 'Group Window' : { - 'Hide Auto' : 256, - 'Hide Toggles' : 512, - 'No Blinking' : 1024, - 'No Stacking' : 2048, - 'Numeric Stacking' : 4096, - 'Hide Buff Numbers' : 8192, - 'Stop Sending Buffs' : 16384, - }, - 'Pet Window' : { - 'Hide Auto' : 65536, - 'Hide Toggles' : 131072, - 'No Blinking' : 262144, - 'No Stacking' : 524288, - 'Numeric Stacking' : 1048576, - 'Hide Buff Numbers' : 2097152, - 'Stop Sending Buffs' : 4194304, - }, - } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - for group, controls in self.buffDisplayMap.items(): - self.Groups[group] = ControlGroup(dialog, self.Page, label = group) - groupid = self.Groups[group].GetStaticBox().GetId() - for cb, data in controls.items(): - self.Groups[group].AddControl( - ctlType = 'checkbox', - ctlName = f"{groupid}_{group}_{cb}", - label = cb, - data = data, - ) - - groupSizer.Add(self.Groups[group]) - - return groupSizer - - def CalculateValue(self): - page = wx.App.Get().Main.Profile.CustomBinds - - total = 0 - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] - if checkbox.IsChecked(): - total = total + checkbox.Data - return total - - def MakeBindString(self): - return f"optionset buffsettings {self.CalculateValue()}" - - def Serialize(self): - return { 'value' : self.CalculateValue() } - - def Deserialize(self, init): - value = init.get('value', 0) - - value = value or 0 # in case we had for some reason 'None' stashed in the init values - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] - checkbox.SetValue( checkbox.Data & value ) - -####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - chatCommandSizer = wx.GridBagSizer(5, 5) - self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") - chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) - # row 1 - self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) - self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) - self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) - # row 2 - self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) - self.chatCommandDuration.SetRange(1, 20) - self.chatCommandDuration.SetValue(7) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandDuration, (2,1)) - self.chatCommandChatSize = wx.Choice(dialog, -1, - choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) - self.chatCommandChatSize.SetSelection(5) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) - self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) - self.chatCommandChannel.SetSelection(0) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChannel, (2,5)) - # row 3 - self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") - chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) - self.chatCommandMessage = wx.TextCtrl(dialog, -1) - self.chatCommandMessage.SetHint('Chat Command Text') - chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) - - return chatCommandSizer - - def MakeBindString(self): - duration = self.chatCommandDuration.GetValue() - - choice = self.chatCommandChatSize - index = choice.GetSelection() - size = choice.GetString(index) - - duration = f"" if duration != 7 else "" - size = f"" if size != "1" else "" - - bdcolor = fgcolor = bgcolor = '' - if self.chatCommandUseColorsCB.IsChecked(): - bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - - bdcolor = f"" - fgcolor = f"" - bgcolor = f"" - - beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' - text = self.chatCommandMessage.GetValue() - - choice = self.chatCommandChannel - index = choice.GetSelection() - channel = choice.GetString(index) - - return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" - - def Serialize(self): - return { - 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), - 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), - 'channel' : self.chatCommandChannel .GetSelection(), - 'size' : self.chatCommandChatSize.GetSelection(), - 'duration' : self.chatCommandDuration.GetValue(), - 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'text' : self.chatCommandMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) - if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) - if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) - if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) - if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) - if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) - if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) - if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) - if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - - -####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): - def BuildUI(self, dialog): - chatCommandGlobalSizer = wx.GridBagSizer(5,5) - - self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") - chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) - - self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalChannel.SetHint("Channel") - chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) - - self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') - chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) - - chatCommandGlobalSizer.AddGrowableCol(1) - - return chatCommandGlobalSizer - - def MakeBindString(self): - useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() - channel = self.chatCommandGlobalChannel.GetValue() - message = self.chatCommandGlobalMessage.GetValue() - - preface = "beginchat /" if useBeginchat else "" - - return f'{preface}send "{channel}" {message}' - - def Serialize(self): - return { - 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), - 'channel' : self.chatCommandGlobalChannel.GetValue(), - 'message' : self.chatCommandGlobalMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) - if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) - if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) - -#######Costume Change -class CostumeChangeCmd(PowerBindCmd): - def BuildUI(self, dialog): - costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeCostume = wx.Choice(dialog, -1, - choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) - self.costumeChangeCostume.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeEmote = wx.Choice(dialog, -1, - choices = GameData.Emotes['costumechange']) - self.costumeChangeEmote.Insert("- None -", 0) - self.costumeChangeEmote.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return costumeChangeSizer - - def MakeBindString(self): - costumeNumber = self.costumeChangeCostume.GetSelection() - costumeEmote = self.costumeChangeEmote.GetSelection() - - if costumeEmote: # None, or 0 == "- None -" - ccCmd = 'cce' - emoteName = self.costumeChangeEmote.GetString(costumeEmote) - emoteName = " CC" + emoteName.replace(" ","") - else: - ccCmd = 'cc' - emoteName = '' - - return f"{ccCmd} {costumeNumber}{emoteName}" - - def Serialize(self): - return{ - 'costumeNumber': self.costumeChangeCostume.GetSelection(), - 'costumeEmote' : self.costumeChangeEmote.GetSelection(), - } - - def Deserialize(self, init): - if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) - if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) - -####### Movement Command -class MovementCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - self.plusbutton.SetValue(True) - - self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.commandchoice = wx.Choice(dialog, choices = [ - "forward", "left", "right", "backward", "up", "down", - "turnleft", "turnright", "first", "autorun", "clicktomove", - ],) - sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) - self.commandchoice.SetSelection(0) - - self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - pre = post = '' - if self.plusbutton.GetValue() : pre = "+" - elif self.plusplusbutton.GetValue() : pre = "++" - elif self.minusbutton.GetValue() : pre = "-" - elif self.zerobutton.GetValue() : post = " 0" - elif self.onebutton.GetValue() : post = " 1" - - command = self.commandchoice.GetString(self.commandchoice.GetSelection()) - - return f"{pre}{command}{post}" - - def Serialize(self): - mod = '' - if self.plusbutton.GetValue() : mod = "plus" - elif self.plusplusbutton.GetValue() : mod = "plusplus" - elif self.minusbutton.GetValue() : mod = "minus" - elif self.zerobutton.GetValue() : mod = "zero" - elif self.onebutton.GetValue() : mod = "one" - - return { - 'mod' : mod, - 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), - } - - def Deserialize(self, init): - mod = init.get('mod', 'plus') - - if mod == 'plus' : self.plusbutton.SetValue(True) - elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) - elif mod == 'minus' : self.minusbutton.SetValue(True) - elif mod == 'zero' : self.zerobutton.SetValue(True) - elif mod == 'one' : self.onebutton.SetValue(True) - - self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) - -####### Graphics Command -class GraphicsCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.FlexGridSizer(2) - - self.visscalecb = wx.CheckBox(dialog, label = "visscale") - sizer.Add(self.visscalecb) - self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) - sizer.Add(self.visscalesc) - - self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") - sizer.Add(self.dofweightcb) - self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) - sizer.Add(self.dofweightsc) - - self.fsaacb = wx.CheckBox(dialog, label = "fsaa") - sizer.Add(self.fsaacb) - self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) - self.fsaach.SetSelection(0) - sizer.Add(self.fsaach) - - self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") - sizer.Add(self.bloomscalecb) - self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) - self.bloomscalech.SetSelection(0) - sizer.Add(self.bloomscalech) - - self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") - sizer.Add(self.bloomweightcb) - self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) - sizer.Add(self.bloomweightsc) - - self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") - sizer.Add(self.lodbiascb) - self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) - sizer.Add(self.lodbiassc) - - self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") - sizer.Add(self.renderscalecb) - self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) - sizer.Add(self.renderscalesc) - - return sizer - - def MakeBindString(self): - # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. - bindstrings = [] - if self.visscalecb.IsChecked(): - bindstrings.append("visscale " + str(self.visscalesc.GetValue())) - if self.dofweightcb.IsChecked(): - bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) - if self.fsaacb.IsChecked(): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bindstrings.append("fsaa " + fsaavalue) - if self.bloomscalecb.IsChecked(): - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - bindstrings.append("bloomscale " + bloomscalevalue) - if self.bloomweightcb.IsChecked(): - bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) - if self.lodbiascb.IsChecked(): - bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) - if self.renderscalecb.IsChecked(): - bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) - - return '$$'.join(bindstrings) - - def Serialize(self): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - return { - 'visscalecb' : self.visscalecb.IsChecked(), - 'visscalesc' : self.visscalesc.GetValue(), - 'dofweightcb' : self.dofweightcb.IsChecked(), - 'dofweightsc' : self.dofweightsc.GetValue(), - 'fsaacb' : self.fsaacb.IsChecked(), - 'fsaach' : fsaavalue, - 'bloomscalecb' : self.bloomscalecb.IsChecked(), - 'bloomscalech' : bloomscalevalue, - 'bloomweightcb' : self.bloomweightcb.IsChecked(), - 'bloomweightsc' : self.bloomweightsc.GetValue(), - 'lodbiascb' : self.lodbiascb.IsChecked(), - 'lodbiassc' : self.lodbiassc.GetValue(), - 'renderscalecb' : self.renderscalecb.IsChecked(), - 'renderscalesc' : self.renderscalesc.GetValue(), - } - - def Deserialize(self, init): - self.visscalecb.SetValue(init.get('visscalecb', False)) - self.visscalesc.SetValue(init.get('visscalesc', 1.0)) - self.dofweightcb.SetValue(init.get('dofweightcb', False)) - self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) - self.fsaacb.SetValue(init.get('fsaacb', False)) - self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) - self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) - self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) - self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) - self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) - self.lodbiascb.SetValue(init.get('lodbiascb', False)) - self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) - self.renderscalecb.SetValue(init.get('renderscalecb', False)) - self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) - -####### Custom Bind -class CustomBindCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.customBindName = wx.TextCtrl(dialog, -1) - self.customBindName.SetHint('Custom Bind Text') - sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - return self.customBindName.GetValue() - - def Serialize(self): - return { 'customBindName': self.customBindName.GetValue() } - - def Deserialize(self,init): - if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) - -####### Emote -class EmoteCmd(PowerBindCmd): - def BuildUI(self, dialog): - emoteSizer = wx.BoxSizer(wx.HORIZONTAL) - self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") - emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - self.emoteName = wx.Button(dialog, -1, "...") - self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) - emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) - - return emoteSizer - - def MakeBindString(self): - displayedEmoteName = self.emoteName.GetLabel() - actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] - - return actualEmotePayload - - def Serialize(self): - return {'emoteName': self.emoteName.GetLabel()} - - def Deserialize(self, init): - if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) - -####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): - def BuildUI(self, dialog): - mainSizer = wx.BoxSizer(wx.VERTICAL) - - lbSizer = wx.BoxSizer(wx.HORIZONTAL) - lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") - lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - profiles = Profile.GetAllProfileBindsDirs() - - self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) - lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) - - mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") - self.lbResetCB.SetValue(True) - - mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - return mainSizer - - def MakeBindString(self): - - # If the specified binds directory disappeared between runs, we'd crash, so handle that. - if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' - - config = wx.ConfigBase.Get() - if config.Exists('GameBindPath'): - bindpath = config.Read('GameBindPath') - else: - bindpath = config.Read('BindPath') - - reset = "" - if self.lbResetCB.GetValue(): - reset = "keybind_reset$$" - - resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' - return reset + 'bindloadfile ' + str(resetfilepath) - - def Serialize(self): - return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), - 'ResetKeybinds' : self.lbResetCB.GetValue(), - } - - def Deserialize(self, init): - if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) - self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) - -####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' - -####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' - -####### SG Mode -class SGModeCmd(PowerBindCmd): - def BuildUI(self, dialog): - sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) - sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") - self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") - - sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) - - return sgmodeSizer - - def MakeBindString(self): - if self.sgmodeOnRB.GetValue(): - return 'sgmodeset 1' - elif self.sgmodeOffRB.GetValue(): - return 'sgmodeset 0' - else: - return 'sgmode' - - def Serialize(self): - if self.sgmodeOnRB.GetValue(): - val = "On" - elif self.sgmodeOffRB.GetValue(): - val = "Off" - else: - val = "Toggle" - - return {"value" : val} - - def Deserialize(self, init): - val = init.get('value', '') - if val == "On": - self.sgmodeOnRB.SetValue(True) - elif val == "Off": - self.sgmodeOffRB.SetValue(True) - else: - self.sgmodeToggleRB.SetValue(True) - -####### Target Custom -class TargetCustomCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetCustomSizer = wx.GridBagSizer(5,5) - targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), - flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) - self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetCustomModeChoice.SetSelection(0) - targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) - self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) - self.targetCustomOptionalName.SetHint("Optional name to match") - targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) - self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") - targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) - self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") - targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) - self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") - targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) - self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") - targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) - self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") - targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) - self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") - targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) - self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") - targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) - self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") - targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) - - targetCustomSizer.AddGrowableCol(2) - - return targetCustomSizer - - def MakeBindString(self): - choice = self.targetCustomModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - targetCommand = "targetcustom" + mode.lower() - - enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" - friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" - defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" - alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" - mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" - notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" - base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" - notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" - - name = self.targetCustomOptionalName.GetValue() - - return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" - - def Serialize(self): - return { - 'mode' : self.targetCustomModeChoice.GetSelection(), - 'enemy' : self.targetCustomCBEnemies. IsChecked(), - 'friend' : self.targetCustomCBFriends. IsChecked(), - 'defeated' : self.targetCustomCBDefeated. IsChecked(), - 'alive' : self.targetCustomCBAlive. IsChecked(), - 'mypet' : self.targetCustomCBMyPets. IsChecked(), - 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), - 'base' : self.targetCustomCBBaseItems. IsChecked(), - 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), - 'name' : self.targetCustomOptionalName.GetValue(), - } - - def Deserialize(self, init): - if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) - if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) - if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) - if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) - if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) - if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) - if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) - if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) - if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) - if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - - -####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) - targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetEnemyModeChoice.SetSelection(0) - targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetEnemySizer - - def MakeBindString(self): - choice = self.targetEnemyModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetenemy" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetEnemyModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) - -####### Target Friend -class TargetFriendCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) - targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetFriendModeChoice.SetSelection(0) - targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetFriendSizer - - def MakeBindString(self): - choice = self.targetFriendModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetfriend" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetFriendModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) - -####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): - def BuildUI(self, dialog): - teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], - style=wx.ALIGN_CENTER_VERTICAL) - self.teamPetSelectNumber.SetSelection(0) - teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) - - return teamPetSelectSizer - - def MakeBindString(self): - teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' - targetNumber = self.teamPetSelectNumber.GetSelection()+1 - - return f"{teamOrPet}select {targetNumber}" - - def Serialize(self): - return { - 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', - 'targetNum': self.teamPetSelectNumber.GetSelection(), - } - - def Deserialize(self, init): - ToP = init.get('teamOrPet', '') - if ToP == 'pet': - self.teamPetSelectPetRB.SetValue(True) - else: - self.teamPetSelectTeamRB.SetValue(True) - if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) - -####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' - -####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) - for _, types in GameData.Inspirations.items(): - for _, info in types.items(): - for insp in info['tiers']: - name = re.sub(' ', '', str(insp)) - icon = GetIcon(f'Inspirations/{name}') - self.useInspByNameModeChoice.Append(insp, icon) - self.useInspByNameModeChoice.SetSelection(0) - useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) - - return useInspByNameSizer - - def MakeBindString(self): - choice = self.useInspByNameModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "inspexecname " + mode.lower() - - def GetAllInsps(self): - Insplist = [] - for _, info in GameData.Inspirations.items(): - for insp in info['tiers']: - Insplist.append(insp) - Insplist.append("---") - Insplist.pop(-1) # snip the terminal "---" - - return Insplist - - def Serialize(self): - return { 'insp' : self.useInspByNameModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) - -####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnRow.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) - self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnCol.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) - - return useInspRowColumnSizer - - def MakeBindString(self): - row = self.useInspRowColumnRow.GetSelection()+1 - col = self.useInspRowColumnCol.GetSelection()+1 - - return f"inspexectray {col} {row}" - - def Serialize(self): - return { - 'col' : self.useInspRowColumnCol.GetSelection(), - 'row' : self.useInspRowColumnRow.GetSelection(), - } - - def Deserialize(self, init): - if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) - if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) - -####### Use Power -class UsePowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - outerSizer = wx.BoxSizer(wx.HORIZONTAL) - - usePowerSizer = wx.GridBagSizer(5,5) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBToggle, (0,1)) - self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOn, (0,2)) - self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOff, (0,3)) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerName = PowerPicker(dialog) - usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) - usePowerSizer.AddGrowableCol(3) - - outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) - - return outerSizer - - def MakeBindString(self): - if self.usePowerRBToggle.GetValue(): - method = "powexecname" - elif self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') - return '' - - return f"{method} {self.usePowerName.GetLabel()}" - - def Serialize(self): - if self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - method = "powexecname" - return { - 'method': method, - 'pname' : self.usePowerName.GetLabel(), - 'picon' : self.usePowerName.IconFilename - } - - def Deserialize(self, init): - method = init.get('method', '') - if method == 'powexectoggleon': - self.usePowerRBOn.SetValue(True) - elif method == 'powexectoggleoff': - self.usePowerRBOff.SetValue(True) - else: - self.usePowerRBToggle.SetValue(True) - if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) - -####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): - def BuildUI(self, dialog): - usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTrayTray = wx.Choice(dialog, -1, - choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', - 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) - self.usePowerFromTrayTray.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) - self.usePowerFromTraySlot.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return usePowerFromTraySizer - - def MakeBindString(self): - choice = self.usePowerFromTrayTray - tray = choice.GetSelection() - - choice = self.usePowerFromTraySlot - slot = choice.GetSelection()+1 - - mode = "slot" - mode2 = '' - if tray > 3: - mode = "tray" - mode2 = f" {tray - 3}" - elif tray == 3: - mode = "alt2slot" - elif tray == 2: - mode = "altslot" - - return f"powexec{mode} {slot}{mode2}" - - def Serialize(self): - return { - 'tray' : self.usePowerFromTrayTray.GetSelection(), - 'slot' : self.usePowerFromTraySlot.GetSelection(), - } - - def Deserialize(self, init): - if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) - if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) - -####### Window Color -class WindowColorCmd(PowerBindCmd): - def BuildUI(self, dialog): - windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) - borderSizer = wx.BoxSizer(wx.VERTICAL) - self.ColorBorder.SetSizer(borderSizer) - self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) - borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) - - windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) - - RGBASizer = wx.FlexGridSizer(3, 4, 5) - - RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) - self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) - self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - windowColorSizer.Add(RGBASizer) - - self.UpdateFromSlider() - - return windowColorSizer - - def MakeBindString(self): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - return f"windowcolor {Rval} {Gval} {Bval} {Aval}" - - def Serialize(self): - return { - 'Rval' : self.RSlider.GetValue(), - 'Gval' : self.GSlider.GetValue(), - 'Bval' : self.BSlider.GetValue(), - 'Aval' : self.ASlider.GetValue(), - } - - def Deserialize(self, init): - self.RSlider.SetValue(init['Rval']) - self.GSlider.SetValue(init['Gval']) - self.BSlider.SetValue(init['Bval']) - self.ASlider.SetValue(init['Aval']) - self.UpdateFromSlider() - - def UpdateFromSlider(self, _ = None): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RReadout.SetValue(Rval) - self.GReadout.SetValue(Gval) - self.BReadout.SetValue(Bval) - self.AReadout.SetValue(Aval) - self.ColorBorder.Refresh() - - def UpdateFromText(self, _ = None): - Rval = self.RReadout.GetValue() - Gval = self.GReadout.GetValue() - Bval = self.BReadout.GetValue() - Aval = self.AReadout.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RSlider.SetValue(Rval) - self.GSlider.SetValue(Gval) - self.BSlider.SetValue(Bval) - self.ASlider.SetValue(Aval) - self.ColorBorder.Refresh() - -####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) - self.CommandChoice.SetSelection(0) - sizer.Add(self.CommandChoice, 0, wx.ALL, 5) - - self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), - value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) - sizer.Add(self.FilePath, 0, wx.ALL, 5) - - return sizer - - def MakeBindString(self): - command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] - return f'{command} "{self.FilePath.GetValue()}"' - - def Serialize(self): - return { - 'command' : self.CommandChoice.GetSelection(), - 'filename' : self.FilePath.GetValue(), - } - - def Deserialize(self, init): - self.CommandChoice.SetSelection(init.get('command', 0)) - self.FilePath.SetValue(init.get('filename', '')) - -####### Window Toggle -class WindowToggleCmd(PowerBindCmd): - def BuildUI(self, dialog): - self.WindowNames = { - 'Actions' : 'actions', - 'Auction House' : 'ah', - 'Badge' : 'badge', - 'Channel Search' : 'chansearch', - 'Chat' : 'chat', - 'Custom Chat 1' : 'chat1', - 'Custom Chat 2' : 'chat2', - 'Custom Chat 3' : 'chat3', - 'Custom Chat 4' : 'chat4', - 'Clues' : 'clue', - 'Combat Numbers' : 'combatnumbers', - 'Contacts' : 'contact', - 'Contact Finder' : 'contactfinder', - 'Costumes' : 'costume', - 'Email' : 'email', - 'Enhancements' : 'enhancements', - 'Friends' : 'friend', - 'Group' : 'group', - 'Help' : 'helpwindow', - 'Incarnate' : 'incarnate', - 'Inspirations' : 'insp', - 'League' : 'league', - 'LFG' : 'lfg', - 'Map' : 'map', - 'Mission' : 'mission', - 'Nav / Compass' : 'nav', - 'Options' : 'options', - 'Pets' : 'pet', - 'Petition' : 'petition', - 'Power Tray' : 'powers', - 'Power List' : 'powerlist', - 'Quit' : 'quit', - 'Recipes' : 'recipe', - 'Salvage' : 'salvage', - 'Search' : 'search', - 'Supergroup' : 'sg', - 'Target' : 'target', - 'Team' : 'team', - 'Tray' : 'tray', - 'Tray1' : 'tray1', - 'Tray2' : 'tray2', - 'Tray3' : 'tray3', - 'Tray4' : 'tray4', - 'Tray5' : 'tray5', - 'Tray6' : 'tray6', - 'Tray7' : 'tray7', - 'Tray8' : 'tray8', - 'Vault' : 'vault', - } - - self.ShortToggleCommands = { - 'Auction House' : 'ah', - 'Chat' : 'chat', - 'Help' : 'helpwindow', - 'Map' : 'map', - 'Nav / Compass' : 'nav', - 'Power Tray' : 'powers', - 'Target' : 'target', - 'Tray' : 'tray', - } - - windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) - windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) - self.windowToggleTray.SetSelection(0) - windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.windowShowRB = wx.RadioButton(dialog, -1, "Show") - self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") - - windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) - - return windowToggleSizer - - def MakeBindString(self): - choice = self.windowToggleTray - index = choice.GetSelection() - windowdesc = choice.GetString(index) - windowname = self.WindowNames[windowdesc] - - if self.windowShowRB.GetValue(): - return 'show ' + windowname - elif self.windowHideRB.GetValue(): - return 'windowhide ' + windowname - else: - if shortcmd := self.ShortToggleCommands.get(windowdesc, None): - return shortcmd - else: - return 'toggle ' + windowname - - - def Serialize(self): - choice = self.windowToggleTray - if self.windowShowRB.GetValue(): - action = "Show" - elif self.windowHideRB.GetValue(): - action = "Hide" - else: - action = "Toggle" - return { - 'window': choice.GetString(choice.GetSelection()), - 'action': action, - } - - def Deserialize(self, init): - choice = self.windowToggleTray - if window := init.get('window', ''): - if isinstance(window, int): - choice.SetSelection(window) - else: - choice.SetSelection(choice.FindString(window)) - - if choice.GetSelection() == wx.NOT_FOUND: - choice.SetSelection(0) - - action = init.get('action', '') - if action == "Show": - self.windowShowRB.SetValue(True) - elif action == "Hide": - self.windowHideRB.SetValue(True) - else: - self.windowToggleRB.SetValue(True) - - -# Must always add to this list when adding a new command class above -menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], - # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, - # but I'm leaving it here to remind myself that we do that. - } - -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/BuffDisplayCmd.py b/UI/PowerBinderCommand/BuffDisplayCmd.py index 4c02ab7..8e89b52 100644 --- a/UI/PowerBinderCommand/BuffDisplayCmd.py +++ b/UI/PowerBinderCommand/BuffDisplayCmd.py @@ -1,504 +1,16 @@ import wx -import re -import UI -import UI.EmotePicker from UI.ControlGroup import ControlGroup -from UI.PowerPicker import PowerPicker -from Help import HelpButton import wx.adv -from wx.adv import BitmapComboBox, EditableListBox -from pathlib import PureWindowsPath -import GameData -import Profile -from Icon import GetIcon - -class PowerBinderDialog(wx.Dialog): - def __init__(self, parent, button, init = {}): - wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) - - self.Page = parent.Page - self.EditDialog = PowerBinderEditDialog(self) - self.Button = button - self.AddStepMenu = self.makeAddStepMenu() - - sizer = wx.BoxSizer(wx.VERTICAL); - self.mainSizer = sizer - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) - AddStepButton = wx.Button(self, -1, 'Add Step') - AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) - AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) - choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) - choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) - sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) - - rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) - - self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) - self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) - self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) - rearrangeCtrl.Add(self.RearrangeList, 1) - - rearrangeButtons = wx.BoxSizer(wx.VERTICAL) - self.DelButton = wx.Button(self, -1, "Delete") - self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) - self.EditButton = wx.Button(self, -1, "Edit") - self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) - self.EditButton.Disable() - upButton = wx.Button(self, -1, "\u25B2") - upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) - downButton = wx.Button(self, -1, "\u25BC") - downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) - rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) - rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) - - sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.BindStringDisplay = wx.TextCtrl(self, -1) - self.BindStringDisplay.Disable() - choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, - wx.ALIGN_CENTER_VERTICAL) - choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) - - sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) - - sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) - - # need to dig around and get the OK button since we show this dialog modelessly now. - okButton = self.FindWindow(self.GetAffirmativeId()) - okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) - - # Wrap everything in a vbox to add some padding - vbox = wx.BoxSizer(wx.VERTICAL); - vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); - - self.SetSizerAndFit(vbox); - self.Layout() - self.Fit() - self.SetFocus() - - # if we are loading from profile, ie, have "init", build the list from it - if init: self.LoadFromData(init) - - def LoadFromData(self, init): - for item in init: - for type, data in item.items(): - commandClass = commandClasses.get(type, None) - if not commandClass: - commandClass = deprecatedCommandClasses.get(type, None) - if not commandClass: - wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") - continue - newCommand = commandClass(self.EditDialog, data) - index = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.SetClientData(index, newCommand) - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) - self.EditDialog.mainSizer.Hide(newCommand.UI) - self.UpdateBindStringDisplay() - - def SaveToData(self): - data = [] - index = 0 - for _ in self.RearrangeList.GetItems(): - # check whether we have an object already attached to this choice - cmdObject = self.RearrangeList.GetClientData(index) - commandClassName = commandRevClasses[type(cmdObject)] - data.append({commandClassName: cmdObject.Serialize()}) - index = index + 1 - return data - - def OnAddStepButton(self, evt): - button = evt.EventObject - if not self.AddStepMenu: - self.AddStepMenu = self.makeAddStepMenu() - button.PopupMenu(self.AddStepMenu) - - - def OnOKButton(self, _): - if self.Button.tgtTxtCtrl: - bindString = self.MakeBindString() - if bindString != self.Button.tgtTxtCtrl.GetValue(): - self.Button.tgtTxtCtrl.SetValue(bindString) - wx.App.Get().Main.Profile.SetModified() - self.Close() - - def OnRearrangeDelete(self, _): - current = self.RearrangeList.GetSelection() - if current == wx.NOT_FOUND: return - - self.RearrangeList.Delete(current) - self.UpdateBindStringDisplay() - - def OnRearrangeUp(self, _): - self.RearrangeList.MoveCurrentUp() - self.UpdateBindStringDisplay() - - def OnRearrangeDown(self, _): - self.RearrangeList.MoveCurrentDown() - self.UpdateBindStringDisplay() - - def OnRearrangeEdit(self, _): - index = self.RearrangeList.GetSelection() - - # check whether we have an object already attached to this choice - cmdObject = None - try: - cmdObject = self.RearrangeList.GetClientData(index) - except Exception: - pass - - if cmdObject: - self.ShowEditDialogFor(cmdObject) - self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) - else: - print("cmdObject was None") - self.UpdateBindStringDisplay() - - # OnAddStepMenu creates a new step and adds it to the rearrangelist - def OnAddStepMenu(self, evt): - menuitem = self.AddStepMenu.FindItemById(evt.GetId()) - chosenName = menuitem.GetItemLabel() - - # make a new command object, attached to the parent dialog - newCommandClass = commandClasses[chosenName] - newCommand = newCommandClass(self.EditDialog) - - # show the edit dialog if this command needs it - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) - if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): - self.EditDialog.mainSizer.Remove(newCommand.UI) - return - - newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.Select(newBindIndex) - self.RearrangeList.SetClientData(newBindIndex, newCommand) - - self.OnListSelect() - self.UpdateBindStringDisplay() - - def OnListSelect(self, _ = None): - selected = self.RearrangeList.GetSelection() - - if selected != wx.NOT_FOUND: - selCommand = self.RearrangeList.GetClientData(selected) - if selCommand.UI: - self.EditButton.Enable() - else: - self.EditButton.Disable() - - def UpdateBindStringDisplay(self): - self.BindStringDisplay.SetValue(self.MakeBindString()) - self.BindStringDisplay.SetToolTip(self.MakeBindString()) - - def MakeBindString(self): - cmdBindStrings = [] - for index in range(self.RearrangeList.GetCount()): - c = self.RearrangeList.GetClientData(index) - if c: cmdBindStrings.append(c.MakeBindString()) - - bindstring = ('$$'.join(cmdBindStrings)) - return bindstring - - def ShowEditDialogFor(self, command): - if not command.UI: return - - self.EditDialog.mainSizer.Show(command.UI) - - self.EditDialog.Layout() - self.EditDialog.Fit() - - self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') - returnval = self.EditDialog.ShowModal() - - self.EditDialog.mainSizer.Hide(command.UI) - - return returnval - - def makeAddStepMenu(self): - - stepMenu = wx.Menu() - - for subname in menuStructure: - submenu = wx.Menu() - stepMenu.AppendSubMenu(submenu, subname) - for classname in menuStructure[subname]: - submenu.Append(wx.ID_ANY, classname) - - stepMenu.Append(wx.ID_ANY, 'Custom Bind') - - return stepMenu - -class PowerBinderButton(wx.BitmapButton): - - def __init__(self, parent, tgtTxtCtrl, init = {}): - wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) - self.Init = init - self.Dialog = None - self.DialogParent = parent - - self.tgtTxtCtrl = tgtTxtCtrl - self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) - self.SetToolTip("Launch PowerBinder") - - def PowerBinderEventHandler(self, _): - self.PowerBinderDialog().Show() - - def LoadFromData(self, data): - self.PowerBinderDialog().LoadFromData(data) - - def SaveToData(self): - return self.PowerBinderDialog().SaveToData() - - def PowerBinderDialog(self): - if not self.Dialog: - self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) - return self.Dialog - - -class PowerBinderEditDialog(wx.Dialog): - def __init__(self, parent): - wx.Dialog.__init__(self, parent, -1, "Edit Step", - style = wx.DEFAULT_DIALOG_STYLE) - - outerSizer = wx.BoxSizer(wx.VERTICAL) - - self.mainSizer = wx.BoxSizer(wx.VERTICAL) - self.mainSizer.SetMinSize([500, 150]) - - self.Page = parent.Page - - self.mainSizer.Add( - self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), - 0, wx.EXPAND|wx.ALL, 10) - - outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) - - self.SetSizerAndFit(outerSizer) - self.Layout() - self.Fit() - -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" +from UI.PowerBinderCommand import PowerBinderCommand +####### Buff Display Command +class BuffDisplayCmd(PowerBinderCommand): + Name = "Buff Display Settings" + Menu = "Graphics / UI" + Groups = {} -####### Away From Keyboard -class AFKCmd(PowerBindCmd): def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page self.Groups = {} - self.AttributeTable = { - 'Base' : { - 'Current Hit Points' : 'NT H', - 'Max Hit Points' : 'X H', - 'Current Endurance' : 'T E', - 'Max Endurance' : 'X EN', - 'Regeneration Rate' : 'N RAT', - 'Recovery Rate' : 'Y RA', - 'Endurance Consumption' : 'SU', - 'ToHit Bonus' : 'T B', - 'Accuracy Bonus' : 'CC', - 'Last Hit Chance' : 'T C', - 'Damage Bonus' : 'DA', - 'Healing Bonus' : 'NG B', - 'Recharge Time Bonus' : 'ME B', - 'Endurance Discount' : 'CE DIS', - 'Stealth Radius (PvP)' : 'PVP', - 'Stealth Radius (PvE)' : 'PVE', - 'Perception Radius' : 'RC', - 'Range Bonus' : 'GE B', - 'Threat Level' : 'AT L', - 'Experience to Next Level' : 'XT', - 'Experience Debt' : 'XP', - 'Influence / Infamy' : 'INF', - 'Inherent' : 'NH', - }, - 'Movement Speed' : { - 'Flying Speed' : 'FL', - 'Jumping Speed' : 'PI', - 'Max Jump Height' : 'X J', - 'Run Speed' : 'RU', - }, - 'Damage Resistance' : { - 'Smashing Resistance' : 'G R', - 'Lethal Resistance' : 'L R', - 'Fire Resistance' : 'RE R', - 'Cold Resistance' : 'COLD R', - 'Energy Resistance' : 'DamageType[4]', - 'Negative Energy Resistance' : 'GY R', - 'Psyonic Resistance' : 'NIC R', - 'Toxic Resistance' : 'XIC R', - }, - 'Defense' : { - 'Base Defense' : 'BAS', - 'Ranged Defense' : 'ED', - 'Melee Defense' : 'MEL', - 'AoE Defense' : '2', - 'Smashing Defense' : '3', - 'Lethal Defense' : '4', - 'Fire Defense' : '5', - 'Cold Defense' : '6', - 'Energy Defense' : '7', - 'Negative Energy Defense' : '8', - 'Psionic Defense' : '9', - 'Toxic Defense' : '1', - }, - 'Debuff Resistance' : { - 'Regeneration Resistance' : 'ON R', - 'Recovery Resistance' : 'RY R', - 'To Hit Resistance' : 'IT R', - 'Defense Resistance' : 'NSE RES', - }, - 'Status Effect Protection' : { - 'Hold Protection' : 'D P', - 'Immobilize Protection' : 'LIZE P', - 'Stun Protection' : 'N P', - 'Sleep Protection' : 'P P', - 'Knockback Protection' : 'K P', - 'Confuse Protection' : 'SE P', - 'Terrorize Protection' : 'ZE P', - 'Repel Protection' : 'EL P', - 'Teleport Protection' : 'T P', - }, - 'Status Effect Resistance' : { - 'Hold Resistance' : 'D R', - 'Immobilize Resistance' : 'LIZE R', - 'Stun Resistance' : 'N R', - 'Sleep Resistance' : 'P R', - 'Knockback Resistance' : 'K R', - 'Confuse Resistance' : 'SE R', - 'Terrorize Resistance' : 'ZE R', - 'Placate Resistance' : 'TE R', - 'Taunt Resistance' : 'NT R', - }, - 'Miscellaneous' : { - 'Level Shift' : 'L S', - }, - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.AttributeMenu = wx.Menu() - for group, controls in self.AttributeTable.items(): - submenu = wx.Menu() - self.AttributeMenu.AppendSubMenu(submenu, group) - for cb in controls: - submenu.Append(wx.ID_ANY, cb) - - self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) - - self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) - groupSizer.Add(self.editbox) - - newButton = self.editbox.GetNewButton() - newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) - - return groupSizer - - def MakeBindString(self): - map = {} - bindstrings = [] - for _, controls in self.AttributeTable.items(): - for cb, data in controls.items(): - map[cb] = data - - for string in self.editbox.GetStrings(): - if string: - bindstrings.append(f'monitorattribute {map[string]}') - - return '$$'.join(bindstrings) - - def Serialize(self): - return { - 'attributes' : self.editbox.GetStrings() - } - - def Deserialize(self, init): - self.editbox.SetStrings(init.get('attributes', [])) - - def OnNewButton(self, evt): - evt.GetEventObject().PopupMenu(self.AttributeMenu) - - def OnMenuItem(self, evt): - menuitem = evt.EventObject.FindItemById(evt.GetId()) - existingstrings = self.editbox.GetStrings() - existingstrings.append(menuitem.GetItemLabel()) - self.editbox.SetStrings(existingstrings) - -####### Auto Power -class AutoPowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) - autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.autoPowerName = PowerPicker(dialog) - autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) - - return autoPowerSizer - - def MakeBindString(self): - return f"powexecauto {self.autoPowerName.GetLabel()}" - - def Serialize(self): - return { - 'pname' : self.autoPowerName.GetLabel(), - 'picon' : self.autoPowerName.IconFilename - } - - def Deserialize(self, init): - if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): self.Page = dialog.Page self.buffDisplayMap = { 'Status Window' : { @@ -529,10 +41,6 @@ def __init__(self, dialog, init = {}): 'Stop Sending Buffs' : 4194304, }, } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): groupSizer = wx.BoxSizer(wx.HORIZONTAL) for group, controls in self.buffDisplayMap.items(): @@ -579,1222 +87,3 @@ def Deserialize(self, init): for cb in controls: checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] checkbox.SetValue( checkbox.Data & value ) - -####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - chatCommandSizer = wx.GridBagSizer(5, 5) - self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") - chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) - # row 1 - self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) - self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) - self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) - # row 2 - self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) - self.chatCommandDuration.SetRange(1, 20) - self.chatCommandDuration.SetValue(7) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandDuration, (2,1)) - self.chatCommandChatSize = wx.Choice(dialog, -1, - choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) - self.chatCommandChatSize.SetSelection(5) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) - self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) - self.chatCommandChannel.SetSelection(0) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChannel, (2,5)) - # row 3 - self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") - chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) - self.chatCommandMessage = wx.TextCtrl(dialog, -1) - self.chatCommandMessage.SetHint('Chat Command Text') - chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) - - return chatCommandSizer - - def MakeBindString(self): - duration = self.chatCommandDuration.GetValue() - - choice = self.chatCommandChatSize - index = choice.GetSelection() - size = choice.GetString(index) - - duration = f"" if duration != 7 else "" - size = f"" if size != "1" else "" - - bdcolor = fgcolor = bgcolor = '' - if self.chatCommandUseColorsCB.IsChecked(): - bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - - bdcolor = f"" - fgcolor = f"" - bgcolor = f"" - - beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' - text = self.chatCommandMessage.GetValue() - - choice = self.chatCommandChannel - index = choice.GetSelection() - channel = choice.GetString(index) - - return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" - - def Serialize(self): - return { - 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), - 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), - 'channel' : self.chatCommandChannel .GetSelection(), - 'size' : self.chatCommandChatSize.GetSelection(), - 'duration' : self.chatCommandDuration.GetValue(), - 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'text' : self.chatCommandMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) - if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) - if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) - if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) - if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) - if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) - if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) - if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) - if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - - -####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): - def BuildUI(self, dialog): - chatCommandGlobalSizer = wx.GridBagSizer(5,5) - - self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") - chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) - - self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalChannel.SetHint("Channel") - chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) - - self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') - chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) - - chatCommandGlobalSizer.AddGrowableCol(1) - - return chatCommandGlobalSizer - - def MakeBindString(self): - useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() - channel = self.chatCommandGlobalChannel.GetValue() - message = self.chatCommandGlobalMessage.GetValue() - - preface = "beginchat /" if useBeginchat else "" - - return f'{preface}send "{channel}" {message}' - - def Serialize(self): - return { - 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), - 'channel' : self.chatCommandGlobalChannel.GetValue(), - 'message' : self.chatCommandGlobalMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) - if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) - if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) - -#######Costume Change -class CostumeChangeCmd(PowerBindCmd): - def BuildUI(self, dialog): - costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeCostume = wx.Choice(dialog, -1, - choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) - self.costumeChangeCostume.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeEmote = wx.Choice(dialog, -1, - choices = GameData.Emotes['costumechange']) - self.costumeChangeEmote.Insert("- None -", 0) - self.costumeChangeEmote.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return costumeChangeSizer - - def MakeBindString(self): - costumeNumber = self.costumeChangeCostume.GetSelection() - costumeEmote = self.costumeChangeEmote.GetSelection() - - if costumeEmote: # None, or 0 == "- None -" - ccCmd = 'cce' - emoteName = self.costumeChangeEmote.GetString(costumeEmote) - emoteName = " CC" + emoteName.replace(" ","") - else: - ccCmd = 'cc' - emoteName = '' - - return f"{ccCmd} {costumeNumber}{emoteName}" - - def Serialize(self): - return{ - 'costumeNumber': self.costumeChangeCostume.GetSelection(), - 'costumeEmote' : self.costumeChangeEmote.GetSelection(), - } - - def Deserialize(self, init): - if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) - if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) - -####### Movement Command -class MovementCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - self.plusbutton.SetValue(True) - - self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.commandchoice = wx.Choice(dialog, choices = [ - "forward", "left", "right", "backward", "up", "down", - "turnleft", "turnright", "first", "autorun", "clicktomove", - ],) - sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) - self.commandchoice.SetSelection(0) - - self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - pre = post = '' - if self.plusbutton.GetValue() : pre = "+" - elif self.plusplusbutton.GetValue() : pre = "++" - elif self.minusbutton.GetValue() : pre = "-" - elif self.zerobutton.GetValue() : post = " 0" - elif self.onebutton.GetValue() : post = " 1" - - command = self.commandchoice.GetString(self.commandchoice.GetSelection()) - - return f"{pre}{command}{post}" - - def Serialize(self): - mod = '' - if self.plusbutton.GetValue() : mod = "plus" - elif self.plusplusbutton.GetValue() : mod = "plusplus" - elif self.minusbutton.GetValue() : mod = "minus" - elif self.zerobutton.GetValue() : mod = "zero" - elif self.onebutton.GetValue() : mod = "one" - - return { - 'mod' : mod, - 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), - } - - def Deserialize(self, init): - mod = init.get('mod', 'plus') - - if mod == 'plus' : self.plusbutton.SetValue(True) - elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) - elif mod == 'minus' : self.minusbutton.SetValue(True) - elif mod == 'zero' : self.zerobutton.SetValue(True) - elif mod == 'one' : self.onebutton.SetValue(True) - - self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) - -####### Graphics Command -class GraphicsCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.FlexGridSizer(2) - - self.visscalecb = wx.CheckBox(dialog, label = "visscale") - sizer.Add(self.visscalecb) - self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) - sizer.Add(self.visscalesc) - - self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") - sizer.Add(self.dofweightcb) - self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) - sizer.Add(self.dofweightsc) - - self.fsaacb = wx.CheckBox(dialog, label = "fsaa") - sizer.Add(self.fsaacb) - self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) - self.fsaach.SetSelection(0) - sizer.Add(self.fsaach) - - self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") - sizer.Add(self.bloomscalecb) - self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) - self.bloomscalech.SetSelection(0) - sizer.Add(self.bloomscalech) - - self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") - sizer.Add(self.bloomweightcb) - self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) - sizer.Add(self.bloomweightsc) - - self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") - sizer.Add(self.lodbiascb) - self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) - sizer.Add(self.lodbiassc) - - self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") - sizer.Add(self.renderscalecb) - self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) - sizer.Add(self.renderscalesc) - - return sizer - - def MakeBindString(self): - # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. - bindstrings = [] - if self.visscalecb.IsChecked(): - bindstrings.append("visscale " + str(self.visscalesc.GetValue())) - if self.dofweightcb.IsChecked(): - bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) - if self.fsaacb.IsChecked(): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bindstrings.append("fsaa " + fsaavalue) - if self.bloomscalecb.IsChecked(): - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - bindstrings.append("bloomscale " + bloomscalevalue) - if self.bloomweightcb.IsChecked(): - bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) - if self.lodbiascb.IsChecked(): - bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) - if self.renderscalecb.IsChecked(): - bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) - - return '$$'.join(bindstrings) - - def Serialize(self): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - return { - 'visscalecb' : self.visscalecb.IsChecked(), - 'visscalesc' : self.visscalesc.GetValue(), - 'dofweightcb' : self.dofweightcb.IsChecked(), - 'dofweightsc' : self.dofweightsc.GetValue(), - 'fsaacb' : self.fsaacb.IsChecked(), - 'fsaach' : fsaavalue, - 'bloomscalecb' : self.bloomscalecb.IsChecked(), - 'bloomscalech' : bloomscalevalue, - 'bloomweightcb' : self.bloomweightcb.IsChecked(), - 'bloomweightsc' : self.bloomweightsc.GetValue(), - 'lodbiascb' : self.lodbiascb.IsChecked(), - 'lodbiassc' : self.lodbiassc.GetValue(), - 'renderscalecb' : self.renderscalecb.IsChecked(), - 'renderscalesc' : self.renderscalesc.GetValue(), - } - - def Deserialize(self, init): - self.visscalecb.SetValue(init.get('visscalecb', False)) - self.visscalesc.SetValue(init.get('visscalesc', 1.0)) - self.dofweightcb.SetValue(init.get('dofweightcb', False)) - self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) - self.fsaacb.SetValue(init.get('fsaacb', False)) - self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) - self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) - self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) - self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) - self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) - self.lodbiascb.SetValue(init.get('lodbiascb', False)) - self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) - self.renderscalecb.SetValue(init.get('renderscalecb', False)) - self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) - -####### Custom Bind -class CustomBindCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.customBindName = wx.TextCtrl(dialog, -1) - self.customBindName.SetHint('Custom Bind Text') - sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - return self.customBindName.GetValue() - - def Serialize(self): - return { 'customBindName': self.customBindName.GetValue() } - - def Deserialize(self,init): - if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) - -####### Emote -class EmoteCmd(PowerBindCmd): - def BuildUI(self, dialog): - emoteSizer = wx.BoxSizer(wx.HORIZONTAL) - self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") - emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - self.emoteName = wx.Button(dialog, -1, "...") - self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) - emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) - - return emoteSizer - - def MakeBindString(self): - displayedEmoteName = self.emoteName.GetLabel() - actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] - - return actualEmotePayload - - def Serialize(self): - return {'emoteName': self.emoteName.GetLabel()} - - def Deserialize(self, init): - if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) - -####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): - def BuildUI(self, dialog): - mainSizer = wx.BoxSizer(wx.VERTICAL) - - lbSizer = wx.BoxSizer(wx.HORIZONTAL) - lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") - lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - profiles = Profile.GetAllProfileBindsDirs() - - self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) - lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) - - mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") - self.lbResetCB.SetValue(True) - - mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - return mainSizer - - def MakeBindString(self): - - # If the specified binds directory disappeared between runs, we'd crash, so handle that. - if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' - - config = wx.ConfigBase.Get() - if config.Exists('GameBindPath'): - bindpath = config.Read('GameBindPath') - else: - bindpath = config.Read('BindPath') - - reset = "" - if self.lbResetCB.GetValue(): - reset = "keybind_reset$$" - - resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' - return reset + 'bindloadfile ' + str(resetfilepath) - - def Serialize(self): - return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), - 'ResetKeybinds' : self.lbResetCB.GetValue(), - } - - def Deserialize(self, init): - if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) - self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) - -####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' - -####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' - -####### SG Mode -class SGModeCmd(PowerBindCmd): - def BuildUI(self, dialog): - sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) - sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") - self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") - - sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) - - return sgmodeSizer - - def MakeBindString(self): - if self.sgmodeOnRB.GetValue(): - return 'sgmodeset 1' - elif self.sgmodeOffRB.GetValue(): - return 'sgmodeset 0' - else: - return 'sgmode' - - def Serialize(self): - if self.sgmodeOnRB.GetValue(): - val = "On" - elif self.sgmodeOffRB.GetValue(): - val = "Off" - else: - val = "Toggle" - - return {"value" : val} - - def Deserialize(self, init): - val = init.get('value', '') - if val == "On": - self.sgmodeOnRB.SetValue(True) - elif val == "Off": - self.sgmodeOffRB.SetValue(True) - else: - self.sgmodeToggleRB.SetValue(True) - -####### Target Custom -class TargetCustomCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetCustomSizer = wx.GridBagSizer(5,5) - targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), - flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) - self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetCustomModeChoice.SetSelection(0) - targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) - self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) - self.targetCustomOptionalName.SetHint("Optional name to match") - targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) - self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") - targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) - self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") - targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) - self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") - targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) - self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") - targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) - self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") - targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) - self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") - targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) - self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") - targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) - self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") - targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) - - targetCustomSizer.AddGrowableCol(2) - - return targetCustomSizer - - def MakeBindString(self): - choice = self.targetCustomModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - targetCommand = "targetcustom" + mode.lower() - - enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" - friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" - defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" - alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" - mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" - notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" - base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" - notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" - - name = self.targetCustomOptionalName.GetValue() - - return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" - - def Serialize(self): - return { - 'mode' : self.targetCustomModeChoice.GetSelection(), - 'enemy' : self.targetCustomCBEnemies. IsChecked(), - 'friend' : self.targetCustomCBFriends. IsChecked(), - 'defeated' : self.targetCustomCBDefeated. IsChecked(), - 'alive' : self.targetCustomCBAlive. IsChecked(), - 'mypet' : self.targetCustomCBMyPets. IsChecked(), - 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), - 'base' : self.targetCustomCBBaseItems. IsChecked(), - 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), - 'name' : self.targetCustomOptionalName.GetValue(), - } - - def Deserialize(self, init): - if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) - if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) - if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) - if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) - if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) - if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) - if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) - if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) - if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) - if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - - -####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) - targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetEnemyModeChoice.SetSelection(0) - targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetEnemySizer - - def MakeBindString(self): - choice = self.targetEnemyModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetenemy" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetEnemyModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) - -####### Target Friend -class TargetFriendCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) - targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetFriendModeChoice.SetSelection(0) - targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetFriendSizer - - def MakeBindString(self): - choice = self.targetFriendModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetfriend" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetFriendModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) - -####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): - def BuildUI(self, dialog): - teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], - style=wx.ALIGN_CENTER_VERTICAL) - self.teamPetSelectNumber.SetSelection(0) - teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) - - return teamPetSelectSizer - - def MakeBindString(self): - teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' - targetNumber = self.teamPetSelectNumber.GetSelection()+1 - - return f"{teamOrPet}select {targetNumber}" - - def Serialize(self): - return { - 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', - 'targetNum': self.teamPetSelectNumber.GetSelection(), - } - - def Deserialize(self, init): - ToP = init.get('teamOrPet', '') - if ToP == 'pet': - self.teamPetSelectPetRB.SetValue(True) - else: - self.teamPetSelectTeamRB.SetValue(True) - if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) - -####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' - -####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) - for _, types in GameData.Inspirations.items(): - for _, info in types.items(): - for insp in info['tiers']: - name = re.sub(' ', '', str(insp)) - icon = GetIcon(f'Inspirations/{name}') - self.useInspByNameModeChoice.Append(insp, icon) - self.useInspByNameModeChoice.SetSelection(0) - useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) - - return useInspByNameSizer - - def MakeBindString(self): - choice = self.useInspByNameModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "inspexecname " + mode.lower() - - def GetAllInsps(self): - Insplist = [] - for _, info in GameData.Inspirations.items(): - for insp in info['tiers']: - Insplist.append(insp) - Insplist.append("---") - Insplist.pop(-1) # snip the terminal "---" - - return Insplist - - def Serialize(self): - return { 'insp' : self.useInspByNameModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) - -####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnRow.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) - self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnCol.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) - - return useInspRowColumnSizer - - def MakeBindString(self): - row = self.useInspRowColumnRow.GetSelection()+1 - col = self.useInspRowColumnCol.GetSelection()+1 - - return f"inspexectray {col} {row}" - - def Serialize(self): - return { - 'col' : self.useInspRowColumnCol.GetSelection(), - 'row' : self.useInspRowColumnRow.GetSelection(), - } - - def Deserialize(self, init): - if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) - if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) - -####### Use Power -class UsePowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - outerSizer = wx.BoxSizer(wx.HORIZONTAL) - - usePowerSizer = wx.GridBagSizer(5,5) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBToggle, (0,1)) - self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOn, (0,2)) - self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOff, (0,3)) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerName = PowerPicker(dialog) - usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) - usePowerSizer.AddGrowableCol(3) - - outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) - - return outerSizer - - def MakeBindString(self): - if self.usePowerRBToggle.GetValue(): - method = "powexecname" - elif self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') - return '' - - return f"{method} {self.usePowerName.GetLabel()}" - - def Serialize(self): - if self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - method = "powexecname" - return { - 'method': method, - 'pname' : self.usePowerName.GetLabel(), - 'picon' : self.usePowerName.IconFilename - } - - def Deserialize(self, init): - method = init.get('method', '') - if method == 'powexectoggleon': - self.usePowerRBOn.SetValue(True) - elif method == 'powexectoggleoff': - self.usePowerRBOff.SetValue(True) - else: - self.usePowerRBToggle.SetValue(True) - if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) - -####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): - def BuildUI(self, dialog): - usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTrayTray = wx.Choice(dialog, -1, - choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', - 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) - self.usePowerFromTrayTray.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) - self.usePowerFromTraySlot.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return usePowerFromTraySizer - - def MakeBindString(self): - choice = self.usePowerFromTrayTray - tray = choice.GetSelection() - - choice = self.usePowerFromTraySlot - slot = choice.GetSelection()+1 - - mode = "slot" - mode2 = '' - if tray > 3: - mode = "tray" - mode2 = f" {tray - 3}" - elif tray == 3: - mode = "alt2slot" - elif tray == 2: - mode = "altslot" - - return f"powexec{mode} {slot}{mode2}" - - def Serialize(self): - return { - 'tray' : self.usePowerFromTrayTray.GetSelection(), - 'slot' : self.usePowerFromTraySlot.GetSelection(), - } - - def Deserialize(self, init): - if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) - if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) - -####### Window Color -class WindowColorCmd(PowerBindCmd): - def BuildUI(self, dialog): - windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) - borderSizer = wx.BoxSizer(wx.VERTICAL) - self.ColorBorder.SetSizer(borderSizer) - self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) - borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) - - windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) - - RGBASizer = wx.FlexGridSizer(3, 4, 5) - - RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) - self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) - self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - windowColorSizer.Add(RGBASizer) - - self.UpdateFromSlider() - - return windowColorSizer - - def MakeBindString(self): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - return f"windowcolor {Rval} {Gval} {Bval} {Aval}" - - def Serialize(self): - return { - 'Rval' : self.RSlider.GetValue(), - 'Gval' : self.GSlider.GetValue(), - 'Bval' : self.BSlider.GetValue(), - 'Aval' : self.ASlider.GetValue(), - } - - def Deserialize(self, init): - self.RSlider.SetValue(init['Rval']) - self.GSlider.SetValue(init['Gval']) - self.BSlider.SetValue(init['Bval']) - self.ASlider.SetValue(init['Aval']) - self.UpdateFromSlider() - - def UpdateFromSlider(self, _ = None): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RReadout.SetValue(Rval) - self.GReadout.SetValue(Gval) - self.BReadout.SetValue(Bval) - self.AReadout.SetValue(Aval) - self.ColorBorder.Refresh() - - def UpdateFromText(self, _ = None): - Rval = self.RReadout.GetValue() - Gval = self.GReadout.GetValue() - Bval = self.BReadout.GetValue() - Aval = self.AReadout.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RSlider.SetValue(Rval) - self.GSlider.SetValue(Gval) - self.BSlider.SetValue(Bval) - self.ASlider.SetValue(Aval) - self.ColorBorder.Refresh() - -####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) - self.CommandChoice.SetSelection(0) - sizer.Add(self.CommandChoice, 0, wx.ALL, 5) - - self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), - value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) - sizer.Add(self.FilePath, 0, wx.ALL, 5) - - return sizer - - def MakeBindString(self): - command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] - return f'{command} "{self.FilePath.GetValue()}"' - - def Serialize(self): - return { - 'command' : self.CommandChoice.GetSelection(), - 'filename' : self.FilePath.GetValue(), - } - - def Deserialize(self, init): - self.CommandChoice.SetSelection(init.get('command', 0)) - self.FilePath.SetValue(init.get('filename', '')) - -####### Window Toggle -class WindowToggleCmd(PowerBindCmd): - def BuildUI(self, dialog): - self.WindowNames = { - 'Actions' : 'actions', - 'Auction House' : 'ah', - 'Badge' : 'badge', - 'Channel Search' : 'chansearch', - 'Chat' : 'chat', - 'Custom Chat 1' : 'chat1', - 'Custom Chat 2' : 'chat2', - 'Custom Chat 3' : 'chat3', - 'Custom Chat 4' : 'chat4', - 'Clues' : 'clue', - 'Combat Numbers' : 'combatnumbers', - 'Contacts' : 'contact', - 'Contact Finder' : 'contactfinder', - 'Costumes' : 'costume', - 'Email' : 'email', - 'Enhancements' : 'enhancements', - 'Friends' : 'friend', - 'Group' : 'group', - 'Help' : 'helpwindow', - 'Incarnate' : 'incarnate', - 'Inspirations' : 'insp', - 'League' : 'league', - 'LFG' : 'lfg', - 'Map' : 'map', - 'Mission' : 'mission', - 'Nav / Compass' : 'nav', - 'Options' : 'options', - 'Pets' : 'pet', - 'Petition' : 'petition', - 'Power Tray' : 'powers', - 'Power List' : 'powerlist', - 'Quit' : 'quit', - 'Recipes' : 'recipe', - 'Salvage' : 'salvage', - 'Search' : 'search', - 'Supergroup' : 'sg', - 'Target' : 'target', - 'Team' : 'team', - 'Tray' : 'tray', - 'Tray1' : 'tray1', - 'Tray2' : 'tray2', - 'Tray3' : 'tray3', - 'Tray4' : 'tray4', - 'Tray5' : 'tray5', - 'Tray6' : 'tray6', - 'Tray7' : 'tray7', - 'Tray8' : 'tray8', - 'Vault' : 'vault', - } - - self.ShortToggleCommands = { - 'Auction House' : 'ah', - 'Chat' : 'chat', - 'Help' : 'helpwindow', - 'Map' : 'map', - 'Nav / Compass' : 'nav', - 'Power Tray' : 'powers', - 'Target' : 'target', - 'Tray' : 'tray', - } - - windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) - windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) - self.windowToggleTray.SetSelection(0) - windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.windowShowRB = wx.RadioButton(dialog, -1, "Show") - self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") - - windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) - - return windowToggleSizer - - def MakeBindString(self): - choice = self.windowToggleTray - index = choice.GetSelection() - windowdesc = choice.GetString(index) - windowname = self.WindowNames[windowdesc] - - if self.windowShowRB.GetValue(): - return 'show ' + windowname - elif self.windowHideRB.GetValue(): - return 'windowhide ' + windowname - else: - if shortcmd := self.ShortToggleCommands.get(windowdesc, None): - return shortcmd - else: - return 'toggle ' + windowname - - - def Serialize(self): - choice = self.windowToggleTray - if self.windowShowRB.GetValue(): - action = "Show" - elif self.windowHideRB.GetValue(): - action = "Hide" - else: - action = "Toggle" - return { - 'window': choice.GetString(choice.GetSelection()), - 'action': action, - } - - def Deserialize(self, init): - choice = self.windowToggleTray - if window := init.get('window', ''): - if isinstance(window, int): - choice.SetSelection(window) - else: - choice.SetSelection(choice.FindString(window)) - - if choice.GetSelection() == wx.NOT_FOUND: - choice.SetSelection(0) - - action = init.get('action', '') - if action == "Show": - self.windowShowRB.SetValue(True) - elif action == "Hide": - self.windowHideRB.SetValue(True) - else: - self.windowToggleRB.SetValue(True) - - -# Must always add to this list when adding a new command class above -menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], - # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, - # but I'm leaving it here to remind myself that we do that. - } - -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/ChatCmd.py b/UI/PowerBinderCommand/ChatCmd.py index 4c02ab7..d11f55f 100644 --- a/UI/PowerBinderCommand/ChatCmd.py +++ b/UI/PowerBinderCommand/ChatCmd.py @@ -1,606 +1,28 @@ import wx -import re -import UI -import UI.EmotePicker -from UI.ControlGroup import ControlGroup -from UI.PowerPicker import PowerPicker -from Help import HelpButton -import wx.adv -from wx.adv import BitmapComboBox, EditableListBox -from pathlib import PureWindowsPath -import GameData -import Profile -from Icon import GetIcon - -class PowerBinderDialog(wx.Dialog): - def __init__(self, parent, button, init = {}): - wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) - - self.Page = parent.Page - self.EditDialog = PowerBinderEditDialog(self) - self.Button = button - self.AddStepMenu = self.makeAddStepMenu() - - sizer = wx.BoxSizer(wx.VERTICAL); - self.mainSizer = sizer - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) - AddStepButton = wx.Button(self, -1, 'Add Step') - AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) - AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) - choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) - choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) - sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) - - rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) - - self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) - self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) - self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) - rearrangeCtrl.Add(self.RearrangeList, 1) - - rearrangeButtons = wx.BoxSizer(wx.VERTICAL) - self.DelButton = wx.Button(self, -1, "Delete") - self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) - self.EditButton = wx.Button(self, -1, "Edit") - self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) - self.EditButton.Disable() - upButton = wx.Button(self, -1, "\u25B2") - upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) - downButton = wx.Button(self, -1, "\u25BC") - downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) - rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) - rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) - - sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.BindStringDisplay = wx.TextCtrl(self, -1) - self.BindStringDisplay.Disable() - choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, - wx.ALIGN_CENTER_VERTICAL) - choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) - - sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) - - sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) - - # need to dig around and get the OK button since we show this dialog modelessly now. - okButton = self.FindWindow(self.GetAffirmativeId()) - okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) - - # Wrap everything in a vbox to add some padding - vbox = wx.BoxSizer(wx.VERTICAL); - vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); - - self.SetSizerAndFit(vbox); - self.Layout() - self.Fit() - self.SetFocus() - - # if we are loading from profile, ie, have "init", build the list from it - if init: self.LoadFromData(init) - - def LoadFromData(self, init): - for item in init: - for type, data in item.items(): - commandClass = commandClasses.get(type, None) - if not commandClass: - commandClass = deprecatedCommandClasses.get(type, None) - if not commandClass: - wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") - continue - newCommand = commandClass(self.EditDialog, data) - index = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.SetClientData(index, newCommand) - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) - self.EditDialog.mainSizer.Hide(newCommand.UI) - self.UpdateBindStringDisplay() - - def SaveToData(self): - data = [] - index = 0 - for _ in self.RearrangeList.GetItems(): - # check whether we have an object already attached to this choice - cmdObject = self.RearrangeList.GetClientData(index) - commandClassName = commandRevClasses[type(cmdObject)] - data.append({commandClassName: cmdObject.Serialize()}) - index = index + 1 - return data - - def OnAddStepButton(self, evt): - button = evt.EventObject - if not self.AddStepMenu: - self.AddStepMenu = self.makeAddStepMenu() - button.PopupMenu(self.AddStepMenu) - - - def OnOKButton(self, _): - if self.Button.tgtTxtCtrl: - bindString = self.MakeBindString() - if bindString != self.Button.tgtTxtCtrl.GetValue(): - self.Button.tgtTxtCtrl.SetValue(bindString) - wx.App.Get().Main.Profile.SetModified() - self.Close() - - def OnRearrangeDelete(self, _): - current = self.RearrangeList.GetSelection() - if current == wx.NOT_FOUND: return - - self.RearrangeList.Delete(current) - self.UpdateBindStringDisplay() - - def OnRearrangeUp(self, _): - self.RearrangeList.MoveCurrentUp() - self.UpdateBindStringDisplay() - - def OnRearrangeDown(self, _): - self.RearrangeList.MoveCurrentDown() - self.UpdateBindStringDisplay() - - def OnRearrangeEdit(self, _): - index = self.RearrangeList.GetSelection() - - # check whether we have an object already attached to this choice - cmdObject = None - try: - cmdObject = self.RearrangeList.GetClientData(index) - except Exception: - pass - - if cmdObject: - self.ShowEditDialogFor(cmdObject) - self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) - else: - print("cmdObject was None") - self.UpdateBindStringDisplay() - - # OnAddStepMenu creates a new step and adds it to the rearrangelist - def OnAddStepMenu(self, evt): - menuitem = self.AddStepMenu.FindItemById(evt.GetId()) - chosenName = menuitem.GetItemLabel() - - # make a new command object, attached to the parent dialog - newCommandClass = commandClasses[chosenName] - newCommand = newCommandClass(self.EditDialog) - - # show the edit dialog if this command needs it - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) - if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): - self.EditDialog.mainSizer.Remove(newCommand.UI) - return - - newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.Select(newBindIndex) - self.RearrangeList.SetClientData(newBindIndex, newCommand) - - self.OnListSelect() - self.UpdateBindStringDisplay() - - def OnListSelect(self, _ = None): - selected = self.RearrangeList.GetSelection() - - if selected != wx.NOT_FOUND: - selCommand = self.RearrangeList.GetClientData(selected) - if selCommand.UI: - self.EditButton.Enable() - else: - self.EditButton.Disable() - - def UpdateBindStringDisplay(self): - self.BindStringDisplay.SetValue(self.MakeBindString()) - self.BindStringDisplay.SetToolTip(self.MakeBindString()) - - def MakeBindString(self): - cmdBindStrings = [] - for index in range(self.RearrangeList.GetCount()): - c = self.RearrangeList.GetClientData(index) - if c: cmdBindStrings.append(c.MakeBindString()) - - bindstring = ('$$'.join(cmdBindStrings)) - return bindstring - - def ShowEditDialogFor(self, command): - if not command.UI: return - - self.EditDialog.mainSizer.Show(command.UI) - - self.EditDialog.Layout() - self.EditDialog.Fit() - - self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') - returnval = self.EditDialog.ShowModal() - - self.EditDialog.mainSizer.Hide(command.UI) - - return returnval - - def makeAddStepMenu(self): - - stepMenu = wx.Menu() - - for subname in menuStructure: - submenu = wx.Menu() - stepMenu.AppendSubMenu(submenu, subname) - for classname in menuStructure[subname]: - submenu.Append(wx.ID_ANY, classname) - - stepMenu.Append(wx.ID_ANY, 'Custom Bind') - - return stepMenu - -class PowerBinderButton(wx.BitmapButton): - - def __init__(self, parent, tgtTxtCtrl, init = {}): - wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) - self.Init = init - self.Dialog = None - self.DialogParent = parent - - self.tgtTxtCtrl = tgtTxtCtrl - self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) - self.SetToolTip("Launch PowerBinder") - - def PowerBinderEventHandler(self, _): - self.PowerBinderDialog().Show() - - def LoadFromData(self, data): - self.PowerBinderDialog().LoadFromData(data) - - def SaveToData(self): - return self.PowerBinderDialog().SaveToData() - - def PowerBinderDialog(self): - if not self.Dialog: - self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) - return self.Dialog - - -class PowerBinderEditDialog(wx.Dialog): - def __init__(self, parent): - wx.Dialog.__init__(self, parent, -1, "Edit Step", - style = wx.DEFAULT_DIALOG_STYLE) - - outerSizer = wx.BoxSizer(wx.VERTICAL) - - self.mainSizer = wx.BoxSizer(wx.VERTICAL) - self.mainSizer.SetMinSize([500, 150]) - - self.Page = parent.Page - - self.mainSizer.Add( - self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), - 0, wx.EXPAND|wx.ALL, 10) - - outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) - - self.SetSizerAndFit(outerSizer) - self.Layout() - self.Fit() - -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" - - -####### Away From Keyboard -class AFKCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.Groups = {} - self.AttributeTable = { - 'Base' : { - 'Current Hit Points' : 'NT H', - 'Max Hit Points' : 'X H', - 'Current Endurance' : 'T E', - 'Max Endurance' : 'X EN', - 'Regeneration Rate' : 'N RAT', - 'Recovery Rate' : 'Y RA', - 'Endurance Consumption' : 'SU', - 'ToHit Bonus' : 'T B', - 'Accuracy Bonus' : 'CC', - 'Last Hit Chance' : 'T C', - 'Damage Bonus' : 'DA', - 'Healing Bonus' : 'NG B', - 'Recharge Time Bonus' : 'ME B', - 'Endurance Discount' : 'CE DIS', - 'Stealth Radius (PvP)' : 'PVP', - 'Stealth Radius (PvE)' : 'PVE', - 'Perception Radius' : 'RC', - 'Range Bonus' : 'GE B', - 'Threat Level' : 'AT L', - 'Experience to Next Level' : 'XT', - 'Experience Debt' : 'XP', - 'Influence / Infamy' : 'INF', - 'Inherent' : 'NH', - }, - 'Movement Speed' : { - 'Flying Speed' : 'FL', - 'Jumping Speed' : 'PI', - 'Max Jump Height' : 'X J', - 'Run Speed' : 'RU', - }, - 'Damage Resistance' : { - 'Smashing Resistance' : 'G R', - 'Lethal Resistance' : 'L R', - 'Fire Resistance' : 'RE R', - 'Cold Resistance' : 'COLD R', - 'Energy Resistance' : 'DamageType[4]', - 'Negative Energy Resistance' : 'GY R', - 'Psyonic Resistance' : 'NIC R', - 'Toxic Resistance' : 'XIC R', - }, - 'Defense' : { - 'Base Defense' : 'BAS', - 'Ranged Defense' : 'ED', - 'Melee Defense' : 'MEL', - 'AoE Defense' : '2', - 'Smashing Defense' : '3', - 'Lethal Defense' : '4', - 'Fire Defense' : '5', - 'Cold Defense' : '6', - 'Energy Defense' : '7', - 'Negative Energy Defense' : '8', - 'Psionic Defense' : '9', - 'Toxic Defense' : '1', - }, - 'Debuff Resistance' : { - 'Regeneration Resistance' : 'ON R', - 'Recovery Resistance' : 'RY R', - 'To Hit Resistance' : 'IT R', - 'Defense Resistance' : 'NSE RES', - }, - 'Status Effect Protection' : { - 'Hold Protection' : 'D P', - 'Immobilize Protection' : 'LIZE P', - 'Stun Protection' : 'N P', - 'Sleep Protection' : 'P P', - 'Knockback Protection' : 'K P', - 'Confuse Protection' : 'SE P', - 'Terrorize Protection' : 'ZE P', - 'Repel Protection' : 'EL P', - 'Teleport Protection' : 'T P', - }, - 'Status Effect Resistance' : { - 'Hold Resistance' : 'D R', - 'Immobilize Resistance' : 'LIZE R', - 'Stun Resistance' : 'N R', - 'Sleep Resistance' : 'P R', - 'Knockback Resistance' : 'K R', - 'Confuse Resistance' : 'SE R', - 'Terrorize Resistance' : 'ZE R', - 'Placate Resistance' : 'TE R', - 'Taunt Resistance' : 'NT R', - }, - 'Miscellaneous' : { - 'Level Shift' : 'L S', - }, - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.AttributeMenu = wx.Menu() - for group, controls in self.AttributeTable.items(): - submenu = wx.Menu() - self.AttributeMenu.AppendSubMenu(submenu, group) - for cb in controls: - submenu.Append(wx.ID_ANY, cb) - - self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) - - self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) - groupSizer.Add(self.editbox) - - newButton = self.editbox.GetNewButton() - newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) - - return groupSizer - - def MakeBindString(self): - map = {} - bindstrings = [] - for _, controls in self.AttributeTable.items(): - for cb, data in controls.items(): - map[cb] = data - - for string in self.editbox.GetStrings(): - if string: - bindstrings.append(f'monitorattribute {map[string]}') - - return '$$'.join(bindstrings) - - def Serialize(self): - return { - 'attributes' : self.editbox.GetStrings() - } - - def Deserialize(self, init): - self.editbox.SetStrings(init.get('attributes', [])) - - def OnNewButton(self, evt): - evt.GetEventObject().PopupMenu(self.AttributeMenu) - - def OnMenuItem(self, evt): - menuitem = evt.EventObject.FindItemById(evt.GetId()) - existingstrings = self.editbox.GetStrings() - existingstrings.append(menuitem.GetItemLabel()) - self.editbox.SetStrings(existingstrings) - -####### Auto Power -class AutoPowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) - autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.autoPowerName = PowerPicker(dialog) - autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) - - return autoPowerSizer - - def MakeBindString(self): - return f"powexecauto {self.autoPowerName.GetLabel()}" - - def Serialize(self): - return { - 'pname' : self.autoPowerName.GetLabel(), - 'picon' : self.autoPowerName.IconFilename - } - - def Deserialize(self, init): - if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.buffDisplayMap = { - 'Status Window' : { - 'Hide Auto' : 1, - 'Hide Toggles' : 2, - 'No Blinking' : 4, - 'No Stacking' : 8, - 'Numeric Stacking' : 16, - 'Hide Buff Numbers' : 32, - 'Stop Sending Buffs' : 64, - }, - 'Group Window' : { - 'Hide Auto' : 256, - 'Hide Toggles' : 512, - 'No Blinking' : 1024, - 'No Stacking' : 2048, - 'Numeric Stacking' : 4096, - 'Hide Buff Numbers' : 8192, - 'Stop Sending Buffs' : 16384, - }, - 'Pet Window' : { - 'Hide Auto' : 65536, - 'Hide Toggles' : 131072, - 'No Blinking' : 262144, - 'No Stacking' : 524288, - 'Numeric Stacking' : 1048576, - 'Hide Buff Numbers' : 2097152, - 'Stop Sending Buffs' : 4194304, - }, - } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - for group, controls in self.buffDisplayMap.items(): - self.Groups[group] = ControlGroup(dialog, self.Page, label = group) - groupid = self.Groups[group].GetStaticBox().GetId() - for cb, data in controls.items(): - self.Groups[group].AddControl( - ctlType = 'checkbox', - ctlName = f"{groupid}_{group}_{cb}", - label = cb, - data = data, - ) - - groupSizer.Add(self.Groups[group]) - - return groupSizer - - def CalculateValue(self): - page = wx.App.Get().Main.Profile.CustomBinds - - total = 0 - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] - if checkbox.IsChecked(): - total = total + checkbox.Data - return total - - def MakeBindString(self): - return f"optionset buffsettings {self.CalculateValue()}" - - def Serialize(self): - return { 'value' : self.CalculateValue() } - - def Deserialize(self, init): - value = init.get('value', 0) - - value = value or 0 # in case we had for some reason 'None' stashed in the init values - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] - checkbox.SetValue( checkbox.Data & value ) +from UI.PowerBinderCommand import PowerBinderCommand ####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) +class ChatCmd(PowerBinderCommand): + Name = "Chat Command" + Menu = "Social" + + chatChannelMap = { + 'say' : 's', + 'group' : 'g', + 'broadcast': 'b', + 'local': 'l', + 'yell': 'y', + 'friends': 'f', + 'general': 'gen', + 'help': 'h', + 'looking for group': 'lfg', + 'request': 'req', + 'arena': 'ac', + 'supergroup': 'sg', + 'coalition': 'c', + 'tell $target,': 't $target,', + 'tell $name': 't $name', + } def BuildUI(self, dialog): chatCommandSizer = wx.GridBagSizer(5, 5) @@ -693,1108 +115,3 @@ def Deserialize(self, init): if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - -####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): - def BuildUI(self, dialog): - chatCommandGlobalSizer = wx.GridBagSizer(5,5) - - self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") - chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) - - self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalChannel.SetHint("Channel") - chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) - - self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') - chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) - - chatCommandGlobalSizer.AddGrowableCol(1) - - return chatCommandGlobalSizer - - def MakeBindString(self): - useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() - channel = self.chatCommandGlobalChannel.GetValue() - message = self.chatCommandGlobalMessage.GetValue() - - preface = "beginchat /" if useBeginchat else "" - - return f'{preface}send "{channel}" {message}' - - def Serialize(self): - return { - 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), - 'channel' : self.chatCommandGlobalChannel.GetValue(), - 'message' : self.chatCommandGlobalMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) - if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) - if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) - -#######Costume Change -class CostumeChangeCmd(PowerBindCmd): - def BuildUI(self, dialog): - costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeCostume = wx.Choice(dialog, -1, - choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) - self.costumeChangeCostume.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeEmote = wx.Choice(dialog, -1, - choices = GameData.Emotes['costumechange']) - self.costumeChangeEmote.Insert("- None -", 0) - self.costumeChangeEmote.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return costumeChangeSizer - - def MakeBindString(self): - costumeNumber = self.costumeChangeCostume.GetSelection() - costumeEmote = self.costumeChangeEmote.GetSelection() - - if costumeEmote: # None, or 0 == "- None -" - ccCmd = 'cce' - emoteName = self.costumeChangeEmote.GetString(costumeEmote) - emoteName = " CC" + emoteName.replace(" ","") - else: - ccCmd = 'cc' - emoteName = '' - - return f"{ccCmd} {costumeNumber}{emoteName}" - - def Serialize(self): - return{ - 'costumeNumber': self.costumeChangeCostume.GetSelection(), - 'costumeEmote' : self.costumeChangeEmote.GetSelection(), - } - - def Deserialize(self, init): - if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) - if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) - -####### Movement Command -class MovementCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - self.plusbutton.SetValue(True) - - self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.commandchoice = wx.Choice(dialog, choices = [ - "forward", "left", "right", "backward", "up", "down", - "turnleft", "turnright", "first", "autorun", "clicktomove", - ],) - sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) - self.commandchoice.SetSelection(0) - - self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - pre = post = '' - if self.plusbutton.GetValue() : pre = "+" - elif self.plusplusbutton.GetValue() : pre = "++" - elif self.minusbutton.GetValue() : pre = "-" - elif self.zerobutton.GetValue() : post = " 0" - elif self.onebutton.GetValue() : post = " 1" - - command = self.commandchoice.GetString(self.commandchoice.GetSelection()) - - return f"{pre}{command}{post}" - - def Serialize(self): - mod = '' - if self.plusbutton.GetValue() : mod = "plus" - elif self.plusplusbutton.GetValue() : mod = "plusplus" - elif self.minusbutton.GetValue() : mod = "minus" - elif self.zerobutton.GetValue() : mod = "zero" - elif self.onebutton.GetValue() : mod = "one" - - return { - 'mod' : mod, - 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), - } - - def Deserialize(self, init): - mod = init.get('mod', 'plus') - - if mod == 'plus' : self.plusbutton.SetValue(True) - elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) - elif mod == 'minus' : self.minusbutton.SetValue(True) - elif mod == 'zero' : self.zerobutton.SetValue(True) - elif mod == 'one' : self.onebutton.SetValue(True) - - self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) - -####### Graphics Command -class GraphicsCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.FlexGridSizer(2) - - self.visscalecb = wx.CheckBox(dialog, label = "visscale") - sizer.Add(self.visscalecb) - self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) - sizer.Add(self.visscalesc) - - self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") - sizer.Add(self.dofweightcb) - self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) - sizer.Add(self.dofweightsc) - - self.fsaacb = wx.CheckBox(dialog, label = "fsaa") - sizer.Add(self.fsaacb) - self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) - self.fsaach.SetSelection(0) - sizer.Add(self.fsaach) - - self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") - sizer.Add(self.bloomscalecb) - self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) - self.bloomscalech.SetSelection(0) - sizer.Add(self.bloomscalech) - - self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") - sizer.Add(self.bloomweightcb) - self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) - sizer.Add(self.bloomweightsc) - - self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") - sizer.Add(self.lodbiascb) - self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) - sizer.Add(self.lodbiassc) - - self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") - sizer.Add(self.renderscalecb) - self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) - sizer.Add(self.renderscalesc) - - return sizer - - def MakeBindString(self): - # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. - bindstrings = [] - if self.visscalecb.IsChecked(): - bindstrings.append("visscale " + str(self.visscalesc.GetValue())) - if self.dofweightcb.IsChecked(): - bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) - if self.fsaacb.IsChecked(): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bindstrings.append("fsaa " + fsaavalue) - if self.bloomscalecb.IsChecked(): - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - bindstrings.append("bloomscale " + bloomscalevalue) - if self.bloomweightcb.IsChecked(): - bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) - if self.lodbiascb.IsChecked(): - bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) - if self.renderscalecb.IsChecked(): - bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) - - return '$$'.join(bindstrings) - - def Serialize(self): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - return { - 'visscalecb' : self.visscalecb.IsChecked(), - 'visscalesc' : self.visscalesc.GetValue(), - 'dofweightcb' : self.dofweightcb.IsChecked(), - 'dofweightsc' : self.dofweightsc.GetValue(), - 'fsaacb' : self.fsaacb.IsChecked(), - 'fsaach' : fsaavalue, - 'bloomscalecb' : self.bloomscalecb.IsChecked(), - 'bloomscalech' : bloomscalevalue, - 'bloomweightcb' : self.bloomweightcb.IsChecked(), - 'bloomweightsc' : self.bloomweightsc.GetValue(), - 'lodbiascb' : self.lodbiascb.IsChecked(), - 'lodbiassc' : self.lodbiassc.GetValue(), - 'renderscalecb' : self.renderscalecb.IsChecked(), - 'renderscalesc' : self.renderscalesc.GetValue(), - } - - def Deserialize(self, init): - self.visscalecb.SetValue(init.get('visscalecb', False)) - self.visscalesc.SetValue(init.get('visscalesc', 1.0)) - self.dofweightcb.SetValue(init.get('dofweightcb', False)) - self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) - self.fsaacb.SetValue(init.get('fsaacb', False)) - self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) - self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) - self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) - self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) - self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) - self.lodbiascb.SetValue(init.get('lodbiascb', False)) - self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) - self.renderscalecb.SetValue(init.get('renderscalecb', False)) - self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) - -####### Custom Bind -class CustomBindCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.customBindName = wx.TextCtrl(dialog, -1) - self.customBindName.SetHint('Custom Bind Text') - sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - return self.customBindName.GetValue() - - def Serialize(self): - return { 'customBindName': self.customBindName.GetValue() } - - def Deserialize(self,init): - if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) - -####### Emote -class EmoteCmd(PowerBindCmd): - def BuildUI(self, dialog): - emoteSizer = wx.BoxSizer(wx.HORIZONTAL) - self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") - emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - self.emoteName = wx.Button(dialog, -1, "...") - self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) - emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) - - return emoteSizer - - def MakeBindString(self): - displayedEmoteName = self.emoteName.GetLabel() - actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] - - return actualEmotePayload - - def Serialize(self): - return {'emoteName': self.emoteName.GetLabel()} - - def Deserialize(self, init): - if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) - -####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): - def BuildUI(self, dialog): - mainSizer = wx.BoxSizer(wx.VERTICAL) - - lbSizer = wx.BoxSizer(wx.HORIZONTAL) - lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") - lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - profiles = Profile.GetAllProfileBindsDirs() - - self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) - lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) - - mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") - self.lbResetCB.SetValue(True) - - mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - return mainSizer - - def MakeBindString(self): - - # If the specified binds directory disappeared between runs, we'd crash, so handle that. - if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' - - config = wx.ConfigBase.Get() - if config.Exists('GameBindPath'): - bindpath = config.Read('GameBindPath') - else: - bindpath = config.Read('BindPath') - - reset = "" - if self.lbResetCB.GetValue(): - reset = "keybind_reset$$" - - resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' - return reset + 'bindloadfile ' + str(resetfilepath) - - def Serialize(self): - return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), - 'ResetKeybinds' : self.lbResetCB.GetValue(), - } - - def Deserialize(self, init): - if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) - self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) - -####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' - -####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' - -####### SG Mode -class SGModeCmd(PowerBindCmd): - def BuildUI(self, dialog): - sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) - sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") - self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") - - sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) - - return sgmodeSizer - - def MakeBindString(self): - if self.sgmodeOnRB.GetValue(): - return 'sgmodeset 1' - elif self.sgmodeOffRB.GetValue(): - return 'sgmodeset 0' - else: - return 'sgmode' - - def Serialize(self): - if self.sgmodeOnRB.GetValue(): - val = "On" - elif self.sgmodeOffRB.GetValue(): - val = "Off" - else: - val = "Toggle" - - return {"value" : val} - - def Deserialize(self, init): - val = init.get('value', '') - if val == "On": - self.sgmodeOnRB.SetValue(True) - elif val == "Off": - self.sgmodeOffRB.SetValue(True) - else: - self.sgmodeToggleRB.SetValue(True) - -####### Target Custom -class TargetCustomCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetCustomSizer = wx.GridBagSizer(5,5) - targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), - flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) - self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetCustomModeChoice.SetSelection(0) - targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) - self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) - self.targetCustomOptionalName.SetHint("Optional name to match") - targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) - self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") - targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) - self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") - targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) - self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") - targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) - self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") - targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) - self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") - targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) - self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") - targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) - self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") - targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) - self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") - targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) - - targetCustomSizer.AddGrowableCol(2) - - return targetCustomSizer - - def MakeBindString(self): - choice = self.targetCustomModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - targetCommand = "targetcustom" + mode.lower() - - enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" - friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" - defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" - alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" - mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" - notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" - base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" - notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" - - name = self.targetCustomOptionalName.GetValue() - - return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" - - def Serialize(self): - return { - 'mode' : self.targetCustomModeChoice.GetSelection(), - 'enemy' : self.targetCustomCBEnemies. IsChecked(), - 'friend' : self.targetCustomCBFriends. IsChecked(), - 'defeated' : self.targetCustomCBDefeated. IsChecked(), - 'alive' : self.targetCustomCBAlive. IsChecked(), - 'mypet' : self.targetCustomCBMyPets. IsChecked(), - 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), - 'base' : self.targetCustomCBBaseItems. IsChecked(), - 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), - 'name' : self.targetCustomOptionalName.GetValue(), - } - - def Deserialize(self, init): - if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) - if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) - if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) - if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) - if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) - if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) - if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) - if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) - if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) - if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - - -####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) - targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetEnemyModeChoice.SetSelection(0) - targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetEnemySizer - - def MakeBindString(self): - choice = self.targetEnemyModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetenemy" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetEnemyModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) - -####### Target Friend -class TargetFriendCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) - targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetFriendModeChoice.SetSelection(0) - targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetFriendSizer - - def MakeBindString(self): - choice = self.targetFriendModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetfriend" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetFriendModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) - -####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): - def BuildUI(self, dialog): - teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], - style=wx.ALIGN_CENTER_VERTICAL) - self.teamPetSelectNumber.SetSelection(0) - teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) - - return teamPetSelectSizer - - def MakeBindString(self): - teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' - targetNumber = self.teamPetSelectNumber.GetSelection()+1 - - return f"{teamOrPet}select {targetNumber}" - - def Serialize(self): - return { - 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', - 'targetNum': self.teamPetSelectNumber.GetSelection(), - } - - def Deserialize(self, init): - ToP = init.get('teamOrPet', '') - if ToP == 'pet': - self.teamPetSelectPetRB.SetValue(True) - else: - self.teamPetSelectTeamRB.SetValue(True) - if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) - -####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' - -####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) - for _, types in GameData.Inspirations.items(): - for _, info in types.items(): - for insp in info['tiers']: - name = re.sub(' ', '', str(insp)) - icon = GetIcon(f'Inspirations/{name}') - self.useInspByNameModeChoice.Append(insp, icon) - self.useInspByNameModeChoice.SetSelection(0) - useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) - - return useInspByNameSizer - - def MakeBindString(self): - choice = self.useInspByNameModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "inspexecname " + mode.lower() - - def GetAllInsps(self): - Insplist = [] - for _, info in GameData.Inspirations.items(): - for insp in info['tiers']: - Insplist.append(insp) - Insplist.append("---") - Insplist.pop(-1) # snip the terminal "---" - - return Insplist - - def Serialize(self): - return { 'insp' : self.useInspByNameModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) - -####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnRow.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) - self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnCol.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) - - return useInspRowColumnSizer - - def MakeBindString(self): - row = self.useInspRowColumnRow.GetSelection()+1 - col = self.useInspRowColumnCol.GetSelection()+1 - - return f"inspexectray {col} {row}" - - def Serialize(self): - return { - 'col' : self.useInspRowColumnCol.GetSelection(), - 'row' : self.useInspRowColumnRow.GetSelection(), - } - - def Deserialize(self, init): - if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) - if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) - -####### Use Power -class UsePowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - outerSizer = wx.BoxSizer(wx.HORIZONTAL) - - usePowerSizer = wx.GridBagSizer(5,5) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBToggle, (0,1)) - self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOn, (0,2)) - self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOff, (0,3)) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerName = PowerPicker(dialog) - usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) - usePowerSizer.AddGrowableCol(3) - - outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) - - return outerSizer - - def MakeBindString(self): - if self.usePowerRBToggle.GetValue(): - method = "powexecname" - elif self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') - return '' - - return f"{method} {self.usePowerName.GetLabel()}" - - def Serialize(self): - if self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - method = "powexecname" - return { - 'method': method, - 'pname' : self.usePowerName.GetLabel(), - 'picon' : self.usePowerName.IconFilename - } - - def Deserialize(self, init): - method = init.get('method', '') - if method == 'powexectoggleon': - self.usePowerRBOn.SetValue(True) - elif method == 'powexectoggleoff': - self.usePowerRBOff.SetValue(True) - else: - self.usePowerRBToggle.SetValue(True) - if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) - -####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): - def BuildUI(self, dialog): - usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTrayTray = wx.Choice(dialog, -1, - choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', - 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) - self.usePowerFromTrayTray.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) - self.usePowerFromTraySlot.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return usePowerFromTraySizer - - def MakeBindString(self): - choice = self.usePowerFromTrayTray - tray = choice.GetSelection() - - choice = self.usePowerFromTraySlot - slot = choice.GetSelection()+1 - - mode = "slot" - mode2 = '' - if tray > 3: - mode = "tray" - mode2 = f" {tray - 3}" - elif tray == 3: - mode = "alt2slot" - elif tray == 2: - mode = "altslot" - - return f"powexec{mode} {slot}{mode2}" - - def Serialize(self): - return { - 'tray' : self.usePowerFromTrayTray.GetSelection(), - 'slot' : self.usePowerFromTraySlot.GetSelection(), - } - - def Deserialize(self, init): - if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) - if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) - -####### Window Color -class WindowColorCmd(PowerBindCmd): - def BuildUI(self, dialog): - windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) - borderSizer = wx.BoxSizer(wx.VERTICAL) - self.ColorBorder.SetSizer(borderSizer) - self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) - borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) - - windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) - - RGBASizer = wx.FlexGridSizer(3, 4, 5) - - RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) - self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) - self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - windowColorSizer.Add(RGBASizer) - - self.UpdateFromSlider() - - return windowColorSizer - - def MakeBindString(self): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - return f"windowcolor {Rval} {Gval} {Bval} {Aval}" - - def Serialize(self): - return { - 'Rval' : self.RSlider.GetValue(), - 'Gval' : self.GSlider.GetValue(), - 'Bval' : self.BSlider.GetValue(), - 'Aval' : self.ASlider.GetValue(), - } - - def Deserialize(self, init): - self.RSlider.SetValue(init['Rval']) - self.GSlider.SetValue(init['Gval']) - self.BSlider.SetValue(init['Bval']) - self.ASlider.SetValue(init['Aval']) - self.UpdateFromSlider() - - def UpdateFromSlider(self, _ = None): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RReadout.SetValue(Rval) - self.GReadout.SetValue(Gval) - self.BReadout.SetValue(Bval) - self.AReadout.SetValue(Aval) - self.ColorBorder.Refresh() - - def UpdateFromText(self, _ = None): - Rval = self.RReadout.GetValue() - Gval = self.GReadout.GetValue() - Bval = self.BReadout.GetValue() - Aval = self.AReadout.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RSlider.SetValue(Rval) - self.GSlider.SetValue(Gval) - self.BSlider.SetValue(Bval) - self.ASlider.SetValue(Aval) - self.ColorBorder.Refresh() - -####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) - self.CommandChoice.SetSelection(0) - sizer.Add(self.CommandChoice, 0, wx.ALL, 5) - - self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), - value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) - sizer.Add(self.FilePath, 0, wx.ALL, 5) - - return sizer - - def MakeBindString(self): - command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] - return f'{command} "{self.FilePath.GetValue()}"' - - def Serialize(self): - return { - 'command' : self.CommandChoice.GetSelection(), - 'filename' : self.FilePath.GetValue(), - } - - def Deserialize(self, init): - self.CommandChoice.SetSelection(init.get('command', 0)) - self.FilePath.SetValue(init.get('filename', '')) - -####### Window Toggle -class WindowToggleCmd(PowerBindCmd): - def BuildUI(self, dialog): - self.WindowNames = { - 'Actions' : 'actions', - 'Auction House' : 'ah', - 'Badge' : 'badge', - 'Channel Search' : 'chansearch', - 'Chat' : 'chat', - 'Custom Chat 1' : 'chat1', - 'Custom Chat 2' : 'chat2', - 'Custom Chat 3' : 'chat3', - 'Custom Chat 4' : 'chat4', - 'Clues' : 'clue', - 'Combat Numbers' : 'combatnumbers', - 'Contacts' : 'contact', - 'Contact Finder' : 'contactfinder', - 'Costumes' : 'costume', - 'Email' : 'email', - 'Enhancements' : 'enhancements', - 'Friends' : 'friend', - 'Group' : 'group', - 'Help' : 'helpwindow', - 'Incarnate' : 'incarnate', - 'Inspirations' : 'insp', - 'League' : 'league', - 'LFG' : 'lfg', - 'Map' : 'map', - 'Mission' : 'mission', - 'Nav / Compass' : 'nav', - 'Options' : 'options', - 'Pets' : 'pet', - 'Petition' : 'petition', - 'Power Tray' : 'powers', - 'Power List' : 'powerlist', - 'Quit' : 'quit', - 'Recipes' : 'recipe', - 'Salvage' : 'salvage', - 'Search' : 'search', - 'Supergroup' : 'sg', - 'Target' : 'target', - 'Team' : 'team', - 'Tray' : 'tray', - 'Tray1' : 'tray1', - 'Tray2' : 'tray2', - 'Tray3' : 'tray3', - 'Tray4' : 'tray4', - 'Tray5' : 'tray5', - 'Tray6' : 'tray6', - 'Tray7' : 'tray7', - 'Tray8' : 'tray8', - 'Vault' : 'vault', - } - - self.ShortToggleCommands = { - 'Auction House' : 'ah', - 'Chat' : 'chat', - 'Help' : 'helpwindow', - 'Map' : 'map', - 'Nav / Compass' : 'nav', - 'Power Tray' : 'powers', - 'Target' : 'target', - 'Tray' : 'tray', - } - - windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) - windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) - self.windowToggleTray.SetSelection(0) - windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.windowShowRB = wx.RadioButton(dialog, -1, "Show") - self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") - - windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) - - return windowToggleSizer - - def MakeBindString(self): - choice = self.windowToggleTray - index = choice.GetSelection() - windowdesc = choice.GetString(index) - windowname = self.WindowNames[windowdesc] - - if self.windowShowRB.GetValue(): - return 'show ' + windowname - elif self.windowHideRB.GetValue(): - return 'windowhide ' + windowname - else: - if shortcmd := self.ShortToggleCommands.get(windowdesc, None): - return shortcmd - else: - return 'toggle ' + windowname - - - def Serialize(self): - choice = self.windowToggleTray - if self.windowShowRB.GetValue(): - action = "Show" - elif self.windowHideRB.GetValue(): - action = "Hide" - else: - action = "Toggle" - return { - 'window': choice.GetString(choice.GetSelection()), - 'action': action, - } - - def Deserialize(self, init): - choice = self.windowToggleTray - if window := init.get('window', ''): - if isinstance(window, int): - choice.SetSelection(window) - else: - choice.SetSelection(choice.FindString(window)) - - if choice.GetSelection() == wx.NOT_FOUND: - choice.SetSelection(0) - - action = init.get('action', '') - if action == "Show": - self.windowShowRB.SetValue(True) - elif action == "Hide": - self.windowHideRB.SetValue(True) - else: - self.windowToggleRB.SetValue(True) - - -# Must always add to this list when adding a new command class above -menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], - # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, - # but I'm leaving it here to remind myself that we do that. - } - -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/ChatGlobalCmd.py b/UI/PowerBinderCommand/ChatGlobalCmd.py index 4c02ab7..0084e12 100644 --- a/UI/PowerBinderCommand/ChatGlobalCmd.py +++ b/UI/PowerBinderCommand/ChatGlobalCmd.py @@ -1,701 +1,11 @@ import wx -import re -import UI -import UI.EmotePicker -from UI.ControlGroup import ControlGroup -from UI.PowerPicker import PowerPicker -from Help import HelpButton -import wx.adv -from wx.adv import BitmapComboBox, EditableListBox -from pathlib import PureWindowsPath -import GameData -import Profile -from Icon import GetIcon - -class PowerBinderDialog(wx.Dialog): - def __init__(self, parent, button, init = {}): - wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) - - self.Page = parent.Page - self.EditDialog = PowerBinderEditDialog(self) - self.Button = button - self.AddStepMenu = self.makeAddStepMenu() - - sizer = wx.BoxSizer(wx.VERTICAL); - self.mainSizer = sizer - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) - AddStepButton = wx.Button(self, -1, 'Add Step') - AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) - AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) - choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) - choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) - sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) - - rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) - - self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) - self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) - self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) - rearrangeCtrl.Add(self.RearrangeList, 1) - - rearrangeButtons = wx.BoxSizer(wx.VERTICAL) - self.DelButton = wx.Button(self, -1, "Delete") - self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) - self.EditButton = wx.Button(self, -1, "Edit") - self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) - self.EditButton.Disable() - upButton = wx.Button(self, -1, "\u25B2") - upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) - downButton = wx.Button(self, -1, "\u25BC") - downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) - rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) - rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) - - sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.BindStringDisplay = wx.TextCtrl(self, -1) - self.BindStringDisplay.Disable() - choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, - wx.ALIGN_CENTER_VERTICAL) - choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) - - sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) - - sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) - - # need to dig around and get the OK button since we show this dialog modelessly now. - okButton = self.FindWindow(self.GetAffirmativeId()) - okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) - - # Wrap everything in a vbox to add some padding - vbox = wx.BoxSizer(wx.VERTICAL); - vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); - - self.SetSizerAndFit(vbox); - self.Layout() - self.Fit() - self.SetFocus() - - # if we are loading from profile, ie, have "init", build the list from it - if init: self.LoadFromData(init) - - def LoadFromData(self, init): - for item in init: - for type, data in item.items(): - commandClass = commandClasses.get(type, None) - if not commandClass: - commandClass = deprecatedCommandClasses.get(type, None) - if not commandClass: - wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") - continue - newCommand = commandClass(self.EditDialog, data) - index = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.SetClientData(index, newCommand) - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) - self.EditDialog.mainSizer.Hide(newCommand.UI) - self.UpdateBindStringDisplay() - - def SaveToData(self): - data = [] - index = 0 - for _ in self.RearrangeList.GetItems(): - # check whether we have an object already attached to this choice - cmdObject = self.RearrangeList.GetClientData(index) - commandClassName = commandRevClasses[type(cmdObject)] - data.append({commandClassName: cmdObject.Serialize()}) - index = index + 1 - return data - - def OnAddStepButton(self, evt): - button = evt.EventObject - if not self.AddStepMenu: - self.AddStepMenu = self.makeAddStepMenu() - button.PopupMenu(self.AddStepMenu) - - - def OnOKButton(self, _): - if self.Button.tgtTxtCtrl: - bindString = self.MakeBindString() - if bindString != self.Button.tgtTxtCtrl.GetValue(): - self.Button.tgtTxtCtrl.SetValue(bindString) - wx.App.Get().Main.Profile.SetModified() - self.Close() - - def OnRearrangeDelete(self, _): - current = self.RearrangeList.GetSelection() - if current == wx.NOT_FOUND: return - - self.RearrangeList.Delete(current) - self.UpdateBindStringDisplay() - - def OnRearrangeUp(self, _): - self.RearrangeList.MoveCurrentUp() - self.UpdateBindStringDisplay() - - def OnRearrangeDown(self, _): - self.RearrangeList.MoveCurrentDown() - self.UpdateBindStringDisplay() - - def OnRearrangeEdit(self, _): - index = self.RearrangeList.GetSelection() - - # check whether we have an object already attached to this choice - cmdObject = None - try: - cmdObject = self.RearrangeList.GetClientData(index) - except Exception: - pass - - if cmdObject: - self.ShowEditDialogFor(cmdObject) - self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) - else: - print("cmdObject was None") - self.UpdateBindStringDisplay() - - # OnAddStepMenu creates a new step and adds it to the rearrangelist - def OnAddStepMenu(self, evt): - menuitem = self.AddStepMenu.FindItemById(evt.GetId()) - chosenName = menuitem.GetItemLabel() - - # make a new command object, attached to the parent dialog - newCommandClass = commandClasses[chosenName] - newCommand = newCommandClass(self.EditDialog) - - # show the edit dialog if this command needs it - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) - if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): - self.EditDialog.mainSizer.Remove(newCommand.UI) - return - - newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.Select(newBindIndex) - self.RearrangeList.SetClientData(newBindIndex, newCommand) - - self.OnListSelect() - self.UpdateBindStringDisplay() - - def OnListSelect(self, _ = None): - selected = self.RearrangeList.GetSelection() - - if selected != wx.NOT_FOUND: - selCommand = self.RearrangeList.GetClientData(selected) - if selCommand.UI: - self.EditButton.Enable() - else: - self.EditButton.Disable() - - def UpdateBindStringDisplay(self): - self.BindStringDisplay.SetValue(self.MakeBindString()) - self.BindStringDisplay.SetToolTip(self.MakeBindString()) - - def MakeBindString(self): - cmdBindStrings = [] - for index in range(self.RearrangeList.GetCount()): - c = self.RearrangeList.GetClientData(index) - if c: cmdBindStrings.append(c.MakeBindString()) - - bindstring = ('$$'.join(cmdBindStrings)) - return bindstring - - def ShowEditDialogFor(self, command): - if not command.UI: return - - self.EditDialog.mainSizer.Show(command.UI) - - self.EditDialog.Layout() - self.EditDialog.Fit() - - self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') - returnval = self.EditDialog.ShowModal() - - self.EditDialog.mainSizer.Hide(command.UI) - - return returnval - - def makeAddStepMenu(self): - - stepMenu = wx.Menu() - - for subname in menuStructure: - submenu = wx.Menu() - stepMenu.AppendSubMenu(submenu, subname) - for classname in menuStructure[subname]: - submenu.Append(wx.ID_ANY, classname) - - stepMenu.Append(wx.ID_ANY, 'Custom Bind') - - return stepMenu - -class PowerBinderButton(wx.BitmapButton): - - def __init__(self, parent, tgtTxtCtrl, init = {}): - wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) - self.Init = init - self.Dialog = None - self.DialogParent = parent - - self.tgtTxtCtrl = tgtTxtCtrl - self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) - self.SetToolTip("Launch PowerBinder") - - def PowerBinderEventHandler(self, _): - self.PowerBinderDialog().Show() - - def LoadFromData(self, data): - self.PowerBinderDialog().LoadFromData(data) - - def SaveToData(self): - return self.PowerBinderDialog().SaveToData() - - def PowerBinderDialog(self): - if not self.Dialog: - self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) - return self.Dialog - - -class PowerBinderEditDialog(wx.Dialog): - def __init__(self, parent): - wx.Dialog.__init__(self, parent, -1, "Edit Step", - style = wx.DEFAULT_DIALOG_STYLE) - - outerSizer = wx.BoxSizer(wx.VERTICAL) - - self.mainSizer = wx.BoxSizer(wx.VERTICAL) - self.mainSizer.SetMinSize([500, 150]) - - self.Page = parent.Page - - self.mainSizer.Add( - self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), - 0, wx.EXPAND|wx.ALL, 10) - - outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) - - self.SetSizerAndFit(outerSizer) - self.Layout() - self.Fit() - -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" - - -####### Away From Keyboard -class AFKCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.Groups = {} - self.AttributeTable = { - 'Base' : { - 'Current Hit Points' : 'NT H', - 'Max Hit Points' : 'X H', - 'Current Endurance' : 'T E', - 'Max Endurance' : 'X EN', - 'Regeneration Rate' : 'N RAT', - 'Recovery Rate' : 'Y RA', - 'Endurance Consumption' : 'SU', - 'ToHit Bonus' : 'T B', - 'Accuracy Bonus' : 'CC', - 'Last Hit Chance' : 'T C', - 'Damage Bonus' : 'DA', - 'Healing Bonus' : 'NG B', - 'Recharge Time Bonus' : 'ME B', - 'Endurance Discount' : 'CE DIS', - 'Stealth Radius (PvP)' : 'PVP', - 'Stealth Radius (PvE)' : 'PVE', - 'Perception Radius' : 'RC', - 'Range Bonus' : 'GE B', - 'Threat Level' : 'AT L', - 'Experience to Next Level' : 'XT', - 'Experience Debt' : 'XP', - 'Influence / Infamy' : 'INF', - 'Inherent' : 'NH', - }, - 'Movement Speed' : { - 'Flying Speed' : 'FL', - 'Jumping Speed' : 'PI', - 'Max Jump Height' : 'X J', - 'Run Speed' : 'RU', - }, - 'Damage Resistance' : { - 'Smashing Resistance' : 'G R', - 'Lethal Resistance' : 'L R', - 'Fire Resistance' : 'RE R', - 'Cold Resistance' : 'COLD R', - 'Energy Resistance' : 'DamageType[4]', - 'Negative Energy Resistance' : 'GY R', - 'Psyonic Resistance' : 'NIC R', - 'Toxic Resistance' : 'XIC R', - }, - 'Defense' : { - 'Base Defense' : 'BAS', - 'Ranged Defense' : 'ED', - 'Melee Defense' : 'MEL', - 'AoE Defense' : '2', - 'Smashing Defense' : '3', - 'Lethal Defense' : '4', - 'Fire Defense' : '5', - 'Cold Defense' : '6', - 'Energy Defense' : '7', - 'Negative Energy Defense' : '8', - 'Psionic Defense' : '9', - 'Toxic Defense' : '1', - }, - 'Debuff Resistance' : { - 'Regeneration Resistance' : 'ON R', - 'Recovery Resistance' : 'RY R', - 'To Hit Resistance' : 'IT R', - 'Defense Resistance' : 'NSE RES', - }, - 'Status Effect Protection' : { - 'Hold Protection' : 'D P', - 'Immobilize Protection' : 'LIZE P', - 'Stun Protection' : 'N P', - 'Sleep Protection' : 'P P', - 'Knockback Protection' : 'K P', - 'Confuse Protection' : 'SE P', - 'Terrorize Protection' : 'ZE P', - 'Repel Protection' : 'EL P', - 'Teleport Protection' : 'T P', - }, - 'Status Effect Resistance' : { - 'Hold Resistance' : 'D R', - 'Immobilize Resistance' : 'LIZE R', - 'Stun Resistance' : 'N R', - 'Sleep Resistance' : 'P R', - 'Knockback Resistance' : 'K R', - 'Confuse Resistance' : 'SE R', - 'Terrorize Resistance' : 'ZE R', - 'Placate Resistance' : 'TE R', - 'Taunt Resistance' : 'NT R', - }, - 'Miscellaneous' : { - 'Level Shift' : 'L S', - }, - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.AttributeMenu = wx.Menu() - for group, controls in self.AttributeTable.items(): - submenu = wx.Menu() - self.AttributeMenu.AppendSubMenu(submenu, group) - for cb in controls: - submenu.Append(wx.ID_ANY, cb) - - self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) - - self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) - groupSizer.Add(self.editbox) - - newButton = self.editbox.GetNewButton() - newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) - - return groupSizer - - def MakeBindString(self): - map = {} - bindstrings = [] - for _, controls in self.AttributeTable.items(): - for cb, data in controls.items(): - map[cb] = data - - for string in self.editbox.GetStrings(): - if string: - bindstrings.append(f'monitorattribute {map[string]}') - - return '$$'.join(bindstrings) - - def Serialize(self): - return { - 'attributes' : self.editbox.GetStrings() - } - - def Deserialize(self, init): - self.editbox.SetStrings(init.get('attributes', [])) - - def OnNewButton(self, evt): - evt.GetEventObject().PopupMenu(self.AttributeMenu) - - def OnMenuItem(self, evt): - menuitem = evt.EventObject.FindItemById(evt.GetId()) - existingstrings = self.editbox.GetStrings() - existingstrings.append(menuitem.GetItemLabel()) - self.editbox.SetStrings(existingstrings) - -####### Auto Power -class AutoPowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) - autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.autoPowerName = PowerPicker(dialog) - autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) - - return autoPowerSizer - - def MakeBindString(self): - return f"powexecauto {self.autoPowerName.GetLabel()}" - - def Serialize(self): - return { - 'pname' : self.autoPowerName.GetLabel(), - 'picon' : self.autoPowerName.IconFilename - } - - def Deserialize(self, init): - if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.buffDisplayMap = { - 'Status Window' : { - 'Hide Auto' : 1, - 'Hide Toggles' : 2, - 'No Blinking' : 4, - 'No Stacking' : 8, - 'Numeric Stacking' : 16, - 'Hide Buff Numbers' : 32, - 'Stop Sending Buffs' : 64, - }, - 'Group Window' : { - 'Hide Auto' : 256, - 'Hide Toggles' : 512, - 'No Blinking' : 1024, - 'No Stacking' : 2048, - 'Numeric Stacking' : 4096, - 'Hide Buff Numbers' : 8192, - 'Stop Sending Buffs' : 16384, - }, - 'Pet Window' : { - 'Hide Auto' : 65536, - 'Hide Toggles' : 131072, - 'No Blinking' : 262144, - 'No Stacking' : 524288, - 'Numeric Stacking' : 1048576, - 'Hide Buff Numbers' : 2097152, - 'Stop Sending Buffs' : 4194304, - }, - } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - for group, controls in self.buffDisplayMap.items(): - self.Groups[group] = ControlGroup(dialog, self.Page, label = group) - groupid = self.Groups[group].GetStaticBox().GetId() - for cb, data in controls.items(): - self.Groups[group].AddControl( - ctlType = 'checkbox', - ctlName = f"{groupid}_{group}_{cb}", - label = cb, - data = data, - ) - - groupSizer.Add(self.Groups[group]) - - return groupSizer - - def CalculateValue(self): - page = wx.App.Get().Main.Profile.CustomBinds - - total = 0 - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] - if checkbox.IsChecked(): - total = total + checkbox.Data - return total - - def MakeBindString(self): - return f"optionset buffsettings {self.CalculateValue()}" - - def Serialize(self): - return { 'value' : self.CalculateValue() } - - def Deserialize(self, init): - value = init.get('value', 0) - - value = value or 0 # in case we had for some reason 'None' stashed in the init values - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] - checkbox.SetValue( checkbox.Data & value ) - -####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - chatCommandSizer = wx.GridBagSizer(5, 5) - self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") - chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) - # row 1 - self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) - self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) - self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) - # row 2 - self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) - self.chatCommandDuration.SetRange(1, 20) - self.chatCommandDuration.SetValue(7) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandDuration, (2,1)) - self.chatCommandChatSize = wx.Choice(dialog, -1, - choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) - self.chatCommandChatSize.SetSelection(5) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) - self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) - self.chatCommandChannel.SetSelection(0) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChannel, (2,5)) - # row 3 - self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") - chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) - self.chatCommandMessage = wx.TextCtrl(dialog, -1) - self.chatCommandMessage.SetHint('Chat Command Text') - chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) - - return chatCommandSizer - - def MakeBindString(self): - duration = self.chatCommandDuration.GetValue() - - choice = self.chatCommandChatSize - index = choice.GetSelection() - size = choice.GetString(index) - - duration = f"" if duration != 7 else "" - size = f"" if size != "1" else "" - - bdcolor = fgcolor = bgcolor = '' - if self.chatCommandUseColorsCB.IsChecked(): - bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - - bdcolor = f"" - fgcolor = f"" - bgcolor = f"" - - beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' - text = self.chatCommandMessage.GetValue() - - choice = self.chatCommandChannel - index = choice.GetSelection() - channel = choice.GetString(index) - - return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" - - def Serialize(self): - return { - 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), - 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), - 'channel' : self.chatCommandChannel .GetSelection(), - 'size' : self.chatCommandChatSize.GetSelection(), - 'duration' : self.chatCommandDuration.GetValue(), - 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'text' : self.chatCommandMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) - if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) - if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) - if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) - if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) - if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) - if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) - if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) - if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - +from UI.PowerBinderCommand import PowerBinderCommand ####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): +class ChatGlobalCmd(PowerBinderCommand): + Name = "Chat Command (Global)" + Menu = "Social" + def BuildUI(self, dialog): chatCommandGlobalSizer = wx.GridBagSizer(5,5) @@ -734,1067 +44,3 @@ def Deserialize(self, init): if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) - -#######Costume Change -class CostumeChangeCmd(PowerBindCmd): - def BuildUI(self, dialog): - costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeCostume = wx.Choice(dialog, -1, - choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) - self.costumeChangeCostume.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeEmote = wx.Choice(dialog, -1, - choices = GameData.Emotes['costumechange']) - self.costumeChangeEmote.Insert("- None -", 0) - self.costumeChangeEmote.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return costumeChangeSizer - - def MakeBindString(self): - costumeNumber = self.costumeChangeCostume.GetSelection() - costumeEmote = self.costumeChangeEmote.GetSelection() - - if costumeEmote: # None, or 0 == "- None -" - ccCmd = 'cce' - emoteName = self.costumeChangeEmote.GetString(costumeEmote) - emoteName = " CC" + emoteName.replace(" ","") - else: - ccCmd = 'cc' - emoteName = '' - - return f"{ccCmd} {costumeNumber}{emoteName}" - - def Serialize(self): - return{ - 'costumeNumber': self.costumeChangeCostume.GetSelection(), - 'costumeEmote' : self.costumeChangeEmote.GetSelection(), - } - - def Deserialize(self, init): - if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) - if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) - -####### Movement Command -class MovementCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - self.plusbutton.SetValue(True) - - self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.commandchoice = wx.Choice(dialog, choices = [ - "forward", "left", "right", "backward", "up", "down", - "turnleft", "turnright", "first", "autorun", "clicktomove", - ],) - sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) - self.commandchoice.SetSelection(0) - - self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - pre = post = '' - if self.plusbutton.GetValue() : pre = "+" - elif self.plusplusbutton.GetValue() : pre = "++" - elif self.minusbutton.GetValue() : pre = "-" - elif self.zerobutton.GetValue() : post = " 0" - elif self.onebutton.GetValue() : post = " 1" - - command = self.commandchoice.GetString(self.commandchoice.GetSelection()) - - return f"{pre}{command}{post}" - - def Serialize(self): - mod = '' - if self.plusbutton.GetValue() : mod = "plus" - elif self.plusplusbutton.GetValue() : mod = "plusplus" - elif self.minusbutton.GetValue() : mod = "minus" - elif self.zerobutton.GetValue() : mod = "zero" - elif self.onebutton.GetValue() : mod = "one" - - return { - 'mod' : mod, - 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), - } - - def Deserialize(self, init): - mod = init.get('mod', 'plus') - - if mod == 'plus' : self.plusbutton.SetValue(True) - elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) - elif mod == 'minus' : self.minusbutton.SetValue(True) - elif mod == 'zero' : self.zerobutton.SetValue(True) - elif mod == 'one' : self.onebutton.SetValue(True) - - self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) - -####### Graphics Command -class GraphicsCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.FlexGridSizer(2) - - self.visscalecb = wx.CheckBox(dialog, label = "visscale") - sizer.Add(self.visscalecb) - self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) - sizer.Add(self.visscalesc) - - self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") - sizer.Add(self.dofweightcb) - self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) - sizer.Add(self.dofweightsc) - - self.fsaacb = wx.CheckBox(dialog, label = "fsaa") - sizer.Add(self.fsaacb) - self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) - self.fsaach.SetSelection(0) - sizer.Add(self.fsaach) - - self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") - sizer.Add(self.bloomscalecb) - self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) - self.bloomscalech.SetSelection(0) - sizer.Add(self.bloomscalech) - - self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") - sizer.Add(self.bloomweightcb) - self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) - sizer.Add(self.bloomweightsc) - - self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") - sizer.Add(self.lodbiascb) - self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) - sizer.Add(self.lodbiassc) - - self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") - sizer.Add(self.renderscalecb) - self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) - sizer.Add(self.renderscalesc) - - return sizer - - def MakeBindString(self): - # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. - bindstrings = [] - if self.visscalecb.IsChecked(): - bindstrings.append("visscale " + str(self.visscalesc.GetValue())) - if self.dofweightcb.IsChecked(): - bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) - if self.fsaacb.IsChecked(): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bindstrings.append("fsaa " + fsaavalue) - if self.bloomscalecb.IsChecked(): - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - bindstrings.append("bloomscale " + bloomscalevalue) - if self.bloomweightcb.IsChecked(): - bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) - if self.lodbiascb.IsChecked(): - bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) - if self.renderscalecb.IsChecked(): - bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) - - return '$$'.join(bindstrings) - - def Serialize(self): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - return { - 'visscalecb' : self.visscalecb.IsChecked(), - 'visscalesc' : self.visscalesc.GetValue(), - 'dofweightcb' : self.dofweightcb.IsChecked(), - 'dofweightsc' : self.dofweightsc.GetValue(), - 'fsaacb' : self.fsaacb.IsChecked(), - 'fsaach' : fsaavalue, - 'bloomscalecb' : self.bloomscalecb.IsChecked(), - 'bloomscalech' : bloomscalevalue, - 'bloomweightcb' : self.bloomweightcb.IsChecked(), - 'bloomweightsc' : self.bloomweightsc.GetValue(), - 'lodbiascb' : self.lodbiascb.IsChecked(), - 'lodbiassc' : self.lodbiassc.GetValue(), - 'renderscalecb' : self.renderscalecb.IsChecked(), - 'renderscalesc' : self.renderscalesc.GetValue(), - } - - def Deserialize(self, init): - self.visscalecb.SetValue(init.get('visscalecb', False)) - self.visscalesc.SetValue(init.get('visscalesc', 1.0)) - self.dofweightcb.SetValue(init.get('dofweightcb', False)) - self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) - self.fsaacb.SetValue(init.get('fsaacb', False)) - self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) - self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) - self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) - self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) - self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) - self.lodbiascb.SetValue(init.get('lodbiascb', False)) - self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) - self.renderscalecb.SetValue(init.get('renderscalecb', False)) - self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) - -####### Custom Bind -class CustomBindCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.customBindName = wx.TextCtrl(dialog, -1) - self.customBindName.SetHint('Custom Bind Text') - sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - return self.customBindName.GetValue() - - def Serialize(self): - return { 'customBindName': self.customBindName.GetValue() } - - def Deserialize(self,init): - if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) - -####### Emote -class EmoteCmd(PowerBindCmd): - def BuildUI(self, dialog): - emoteSizer = wx.BoxSizer(wx.HORIZONTAL) - self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") - emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - self.emoteName = wx.Button(dialog, -1, "...") - self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) - emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) - - return emoteSizer - - def MakeBindString(self): - displayedEmoteName = self.emoteName.GetLabel() - actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] - - return actualEmotePayload - - def Serialize(self): - return {'emoteName': self.emoteName.GetLabel()} - - def Deserialize(self, init): - if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) - -####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): - def BuildUI(self, dialog): - mainSizer = wx.BoxSizer(wx.VERTICAL) - - lbSizer = wx.BoxSizer(wx.HORIZONTAL) - lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") - lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - profiles = Profile.GetAllProfileBindsDirs() - - self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) - lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) - - mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") - self.lbResetCB.SetValue(True) - - mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - return mainSizer - - def MakeBindString(self): - - # If the specified binds directory disappeared between runs, we'd crash, so handle that. - if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' - - config = wx.ConfigBase.Get() - if config.Exists('GameBindPath'): - bindpath = config.Read('GameBindPath') - else: - bindpath = config.Read('BindPath') - - reset = "" - if self.lbResetCB.GetValue(): - reset = "keybind_reset$$" - - resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' - return reset + 'bindloadfile ' + str(resetfilepath) - - def Serialize(self): - return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), - 'ResetKeybinds' : self.lbResetCB.GetValue(), - } - - def Deserialize(self, init): - if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) - self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) - -####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' - -####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' - -####### SG Mode -class SGModeCmd(PowerBindCmd): - def BuildUI(self, dialog): - sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) - sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") - self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") - - sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) - - return sgmodeSizer - - def MakeBindString(self): - if self.sgmodeOnRB.GetValue(): - return 'sgmodeset 1' - elif self.sgmodeOffRB.GetValue(): - return 'sgmodeset 0' - else: - return 'sgmode' - - def Serialize(self): - if self.sgmodeOnRB.GetValue(): - val = "On" - elif self.sgmodeOffRB.GetValue(): - val = "Off" - else: - val = "Toggle" - - return {"value" : val} - - def Deserialize(self, init): - val = init.get('value', '') - if val == "On": - self.sgmodeOnRB.SetValue(True) - elif val == "Off": - self.sgmodeOffRB.SetValue(True) - else: - self.sgmodeToggleRB.SetValue(True) - -####### Target Custom -class TargetCustomCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetCustomSizer = wx.GridBagSizer(5,5) - targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), - flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) - self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetCustomModeChoice.SetSelection(0) - targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) - self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) - self.targetCustomOptionalName.SetHint("Optional name to match") - targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) - self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") - targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) - self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") - targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) - self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") - targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) - self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") - targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) - self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") - targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) - self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") - targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) - self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") - targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) - self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") - targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) - - targetCustomSizer.AddGrowableCol(2) - - return targetCustomSizer - - def MakeBindString(self): - choice = self.targetCustomModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - targetCommand = "targetcustom" + mode.lower() - - enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" - friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" - defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" - alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" - mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" - notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" - base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" - notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" - - name = self.targetCustomOptionalName.GetValue() - - return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" - - def Serialize(self): - return { - 'mode' : self.targetCustomModeChoice.GetSelection(), - 'enemy' : self.targetCustomCBEnemies. IsChecked(), - 'friend' : self.targetCustomCBFriends. IsChecked(), - 'defeated' : self.targetCustomCBDefeated. IsChecked(), - 'alive' : self.targetCustomCBAlive. IsChecked(), - 'mypet' : self.targetCustomCBMyPets. IsChecked(), - 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), - 'base' : self.targetCustomCBBaseItems. IsChecked(), - 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), - 'name' : self.targetCustomOptionalName.GetValue(), - } - - def Deserialize(self, init): - if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) - if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) - if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) - if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) - if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) - if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) - if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) - if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) - if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) - if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - - -####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) - targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetEnemyModeChoice.SetSelection(0) - targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetEnemySizer - - def MakeBindString(self): - choice = self.targetEnemyModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetenemy" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetEnemyModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) - -####### Target Friend -class TargetFriendCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) - targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetFriendModeChoice.SetSelection(0) - targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetFriendSizer - - def MakeBindString(self): - choice = self.targetFriendModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetfriend" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetFriendModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) - -####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): - def BuildUI(self, dialog): - teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], - style=wx.ALIGN_CENTER_VERTICAL) - self.teamPetSelectNumber.SetSelection(0) - teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) - - return teamPetSelectSizer - - def MakeBindString(self): - teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' - targetNumber = self.teamPetSelectNumber.GetSelection()+1 - - return f"{teamOrPet}select {targetNumber}" - - def Serialize(self): - return { - 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', - 'targetNum': self.teamPetSelectNumber.GetSelection(), - } - - def Deserialize(self, init): - ToP = init.get('teamOrPet', '') - if ToP == 'pet': - self.teamPetSelectPetRB.SetValue(True) - else: - self.teamPetSelectTeamRB.SetValue(True) - if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) - -####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' - -####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) - for _, types in GameData.Inspirations.items(): - for _, info in types.items(): - for insp in info['tiers']: - name = re.sub(' ', '', str(insp)) - icon = GetIcon(f'Inspirations/{name}') - self.useInspByNameModeChoice.Append(insp, icon) - self.useInspByNameModeChoice.SetSelection(0) - useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) - - return useInspByNameSizer - - def MakeBindString(self): - choice = self.useInspByNameModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "inspexecname " + mode.lower() - - def GetAllInsps(self): - Insplist = [] - for _, info in GameData.Inspirations.items(): - for insp in info['tiers']: - Insplist.append(insp) - Insplist.append("---") - Insplist.pop(-1) # snip the terminal "---" - - return Insplist - - def Serialize(self): - return { 'insp' : self.useInspByNameModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) - -####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnRow.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) - self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnCol.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) - - return useInspRowColumnSizer - - def MakeBindString(self): - row = self.useInspRowColumnRow.GetSelection()+1 - col = self.useInspRowColumnCol.GetSelection()+1 - - return f"inspexectray {col} {row}" - - def Serialize(self): - return { - 'col' : self.useInspRowColumnCol.GetSelection(), - 'row' : self.useInspRowColumnRow.GetSelection(), - } - - def Deserialize(self, init): - if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) - if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) - -####### Use Power -class UsePowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - outerSizer = wx.BoxSizer(wx.HORIZONTAL) - - usePowerSizer = wx.GridBagSizer(5,5) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBToggle, (0,1)) - self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOn, (0,2)) - self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOff, (0,3)) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerName = PowerPicker(dialog) - usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) - usePowerSizer.AddGrowableCol(3) - - outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) - - return outerSizer - - def MakeBindString(self): - if self.usePowerRBToggle.GetValue(): - method = "powexecname" - elif self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') - return '' - - return f"{method} {self.usePowerName.GetLabel()}" - - def Serialize(self): - if self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - method = "powexecname" - return { - 'method': method, - 'pname' : self.usePowerName.GetLabel(), - 'picon' : self.usePowerName.IconFilename - } - - def Deserialize(self, init): - method = init.get('method', '') - if method == 'powexectoggleon': - self.usePowerRBOn.SetValue(True) - elif method == 'powexectoggleoff': - self.usePowerRBOff.SetValue(True) - else: - self.usePowerRBToggle.SetValue(True) - if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) - -####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): - def BuildUI(self, dialog): - usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTrayTray = wx.Choice(dialog, -1, - choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', - 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) - self.usePowerFromTrayTray.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) - self.usePowerFromTraySlot.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return usePowerFromTraySizer - - def MakeBindString(self): - choice = self.usePowerFromTrayTray - tray = choice.GetSelection() - - choice = self.usePowerFromTraySlot - slot = choice.GetSelection()+1 - - mode = "slot" - mode2 = '' - if tray > 3: - mode = "tray" - mode2 = f" {tray - 3}" - elif tray == 3: - mode = "alt2slot" - elif tray == 2: - mode = "altslot" - - return f"powexec{mode} {slot}{mode2}" - - def Serialize(self): - return { - 'tray' : self.usePowerFromTrayTray.GetSelection(), - 'slot' : self.usePowerFromTraySlot.GetSelection(), - } - - def Deserialize(self, init): - if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) - if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) - -####### Window Color -class WindowColorCmd(PowerBindCmd): - def BuildUI(self, dialog): - windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) - borderSizer = wx.BoxSizer(wx.VERTICAL) - self.ColorBorder.SetSizer(borderSizer) - self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) - borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) - - windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) - - RGBASizer = wx.FlexGridSizer(3, 4, 5) - - RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) - self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) - self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - windowColorSizer.Add(RGBASizer) - - self.UpdateFromSlider() - - return windowColorSizer - - def MakeBindString(self): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - return f"windowcolor {Rval} {Gval} {Bval} {Aval}" - - def Serialize(self): - return { - 'Rval' : self.RSlider.GetValue(), - 'Gval' : self.GSlider.GetValue(), - 'Bval' : self.BSlider.GetValue(), - 'Aval' : self.ASlider.GetValue(), - } - - def Deserialize(self, init): - self.RSlider.SetValue(init['Rval']) - self.GSlider.SetValue(init['Gval']) - self.BSlider.SetValue(init['Bval']) - self.ASlider.SetValue(init['Aval']) - self.UpdateFromSlider() - - def UpdateFromSlider(self, _ = None): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RReadout.SetValue(Rval) - self.GReadout.SetValue(Gval) - self.BReadout.SetValue(Bval) - self.AReadout.SetValue(Aval) - self.ColorBorder.Refresh() - - def UpdateFromText(self, _ = None): - Rval = self.RReadout.GetValue() - Gval = self.GReadout.GetValue() - Bval = self.BReadout.GetValue() - Aval = self.AReadout.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RSlider.SetValue(Rval) - self.GSlider.SetValue(Gval) - self.BSlider.SetValue(Bval) - self.ASlider.SetValue(Aval) - self.ColorBorder.Refresh() - -####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) - self.CommandChoice.SetSelection(0) - sizer.Add(self.CommandChoice, 0, wx.ALL, 5) - - self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), - value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) - sizer.Add(self.FilePath, 0, wx.ALL, 5) - - return sizer - - def MakeBindString(self): - command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] - return f'{command} "{self.FilePath.GetValue()}"' - - def Serialize(self): - return { - 'command' : self.CommandChoice.GetSelection(), - 'filename' : self.FilePath.GetValue(), - } - - def Deserialize(self, init): - self.CommandChoice.SetSelection(init.get('command', 0)) - self.FilePath.SetValue(init.get('filename', '')) - -####### Window Toggle -class WindowToggleCmd(PowerBindCmd): - def BuildUI(self, dialog): - self.WindowNames = { - 'Actions' : 'actions', - 'Auction House' : 'ah', - 'Badge' : 'badge', - 'Channel Search' : 'chansearch', - 'Chat' : 'chat', - 'Custom Chat 1' : 'chat1', - 'Custom Chat 2' : 'chat2', - 'Custom Chat 3' : 'chat3', - 'Custom Chat 4' : 'chat4', - 'Clues' : 'clue', - 'Combat Numbers' : 'combatnumbers', - 'Contacts' : 'contact', - 'Contact Finder' : 'contactfinder', - 'Costumes' : 'costume', - 'Email' : 'email', - 'Enhancements' : 'enhancements', - 'Friends' : 'friend', - 'Group' : 'group', - 'Help' : 'helpwindow', - 'Incarnate' : 'incarnate', - 'Inspirations' : 'insp', - 'League' : 'league', - 'LFG' : 'lfg', - 'Map' : 'map', - 'Mission' : 'mission', - 'Nav / Compass' : 'nav', - 'Options' : 'options', - 'Pets' : 'pet', - 'Petition' : 'petition', - 'Power Tray' : 'powers', - 'Power List' : 'powerlist', - 'Quit' : 'quit', - 'Recipes' : 'recipe', - 'Salvage' : 'salvage', - 'Search' : 'search', - 'Supergroup' : 'sg', - 'Target' : 'target', - 'Team' : 'team', - 'Tray' : 'tray', - 'Tray1' : 'tray1', - 'Tray2' : 'tray2', - 'Tray3' : 'tray3', - 'Tray4' : 'tray4', - 'Tray5' : 'tray5', - 'Tray6' : 'tray6', - 'Tray7' : 'tray7', - 'Tray8' : 'tray8', - 'Vault' : 'vault', - } - - self.ShortToggleCommands = { - 'Auction House' : 'ah', - 'Chat' : 'chat', - 'Help' : 'helpwindow', - 'Map' : 'map', - 'Nav / Compass' : 'nav', - 'Power Tray' : 'powers', - 'Target' : 'target', - 'Tray' : 'tray', - } - - windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) - windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) - self.windowToggleTray.SetSelection(0) - windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.windowShowRB = wx.RadioButton(dialog, -1, "Show") - self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") - - windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) - - return windowToggleSizer - - def MakeBindString(self): - choice = self.windowToggleTray - index = choice.GetSelection() - windowdesc = choice.GetString(index) - windowname = self.WindowNames[windowdesc] - - if self.windowShowRB.GetValue(): - return 'show ' + windowname - elif self.windowHideRB.GetValue(): - return 'windowhide ' + windowname - else: - if shortcmd := self.ShortToggleCommands.get(windowdesc, None): - return shortcmd - else: - return 'toggle ' + windowname - - - def Serialize(self): - choice = self.windowToggleTray - if self.windowShowRB.GetValue(): - action = "Show" - elif self.windowHideRB.GetValue(): - action = "Hide" - else: - action = "Toggle" - return { - 'window': choice.GetString(choice.GetSelection()), - 'action': action, - } - - def Deserialize(self, init): - choice = self.windowToggleTray - if window := init.get('window', ''): - if isinstance(window, int): - choice.SetSelection(window) - else: - choice.SetSelection(choice.FindString(window)) - - if choice.GetSelection() == wx.NOT_FOUND: - choice.SetSelection(0) - - action = init.get('action', '') - if action == "Show": - self.windowShowRB.SetValue(True) - elif action == "Hide": - self.windowHideRB.SetValue(True) - else: - self.windowToggleRB.SetValue(True) - - -# Must always add to this list when adding a new command class above -menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], - # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, - # but I'm leaving it here to remind myself that we do that. - } - -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/CostumeChangeCmd.py b/UI/PowerBinderCommand/CostumeChangeCmd.py index 4c02ab7..cd3889a 100644 --- a/UI/PowerBinderCommand/CostumeChangeCmd.py +++ b/UI/PowerBinderCommand/CostumeChangeCmd.py @@ -1,742 +1,12 @@ import wx -import re -import UI -import UI.EmotePicker -from UI.ControlGroup import ControlGroup -from UI.PowerPicker import PowerPicker -from Help import HelpButton -import wx.adv -from wx.adv import BitmapComboBox, EditableListBox -from pathlib import PureWindowsPath import GameData -import Profile -from Icon import GetIcon - -class PowerBinderDialog(wx.Dialog): - def __init__(self, parent, button, init = {}): - wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) - - self.Page = parent.Page - self.EditDialog = PowerBinderEditDialog(self) - self.Button = button - self.AddStepMenu = self.makeAddStepMenu() - - sizer = wx.BoxSizer(wx.VERTICAL); - self.mainSizer = sizer - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) - AddStepButton = wx.Button(self, -1, 'Add Step') - AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) - AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) - choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) - choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) - sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) - - rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) - - self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) - self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) - self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) - rearrangeCtrl.Add(self.RearrangeList, 1) - - rearrangeButtons = wx.BoxSizer(wx.VERTICAL) - self.DelButton = wx.Button(self, -1, "Delete") - self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) - self.EditButton = wx.Button(self, -1, "Edit") - self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) - self.EditButton.Disable() - upButton = wx.Button(self, -1, "\u25B2") - upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) - downButton = wx.Button(self, -1, "\u25BC") - downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) - rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) - rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) - - sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.BindStringDisplay = wx.TextCtrl(self, -1) - self.BindStringDisplay.Disable() - choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, - wx.ALIGN_CENTER_VERTICAL) - choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) - - sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) - - sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) - - # need to dig around and get the OK button since we show this dialog modelessly now. - okButton = self.FindWindow(self.GetAffirmativeId()) - okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) - - # Wrap everything in a vbox to add some padding - vbox = wx.BoxSizer(wx.VERTICAL); - vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); - - self.SetSizerAndFit(vbox); - self.Layout() - self.Fit() - self.SetFocus() - - # if we are loading from profile, ie, have "init", build the list from it - if init: self.LoadFromData(init) - - def LoadFromData(self, init): - for item in init: - for type, data in item.items(): - commandClass = commandClasses.get(type, None) - if not commandClass: - commandClass = deprecatedCommandClasses.get(type, None) - if not commandClass: - wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") - continue - newCommand = commandClass(self.EditDialog, data) - index = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.SetClientData(index, newCommand) - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) - self.EditDialog.mainSizer.Hide(newCommand.UI) - self.UpdateBindStringDisplay() - - def SaveToData(self): - data = [] - index = 0 - for _ in self.RearrangeList.GetItems(): - # check whether we have an object already attached to this choice - cmdObject = self.RearrangeList.GetClientData(index) - commandClassName = commandRevClasses[type(cmdObject)] - data.append({commandClassName: cmdObject.Serialize()}) - index = index + 1 - return data - - def OnAddStepButton(self, evt): - button = evt.EventObject - if not self.AddStepMenu: - self.AddStepMenu = self.makeAddStepMenu() - button.PopupMenu(self.AddStepMenu) - - - def OnOKButton(self, _): - if self.Button.tgtTxtCtrl: - bindString = self.MakeBindString() - if bindString != self.Button.tgtTxtCtrl.GetValue(): - self.Button.tgtTxtCtrl.SetValue(bindString) - wx.App.Get().Main.Profile.SetModified() - self.Close() - - def OnRearrangeDelete(self, _): - current = self.RearrangeList.GetSelection() - if current == wx.NOT_FOUND: return - - self.RearrangeList.Delete(current) - self.UpdateBindStringDisplay() - - def OnRearrangeUp(self, _): - self.RearrangeList.MoveCurrentUp() - self.UpdateBindStringDisplay() - - def OnRearrangeDown(self, _): - self.RearrangeList.MoveCurrentDown() - self.UpdateBindStringDisplay() - - def OnRearrangeEdit(self, _): - index = self.RearrangeList.GetSelection() - - # check whether we have an object already attached to this choice - cmdObject = None - try: - cmdObject = self.RearrangeList.GetClientData(index) - except Exception: - pass - - if cmdObject: - self.ShowEditDialogFor(cmdObject) - self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) - else: - print("cmdObject was None") - self.UpdateBindStringDisplay() - - # OnAddStepMenu creates a new step and adds it to the rearrangelist - def OnAddStepMenu(self, evt): - menuitem = self.AddStepMenu.FindItemById(evt.GetId()) - chosenName = menuitem.GetItemLabel() - - # make a new command object, attached to the parent dialog - newCommandClass = commandClasses[chosenName] - newCommand = newCommandClass(self.EditDialog) - - # show the edit dialog if this command needs it - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) - if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): - self.EditDialog.mainSizer.Remove(newCommand.UI) - return - - newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.Select(newBindIndex) - self.RearrangeList.SetClientData(newBindIndex, newCommand) - - self.OnListSelect() - self.UpdateBindStringDisplay() - - def OnListSelect(self, _ = None): - selected = self.RearrangeList.GetSelection() - - if selected != wx.NOT_FOUND: - selCommand = self.RearrangeList.GetClientData(selected) - if selCommand.UI: - self.EditButton.Enable() - else: - self.EditButton.Disable() - - def UpdateBindStringDisplay(self): - self.BindStringDisplay.SetValue(self.MakeBindString()) - self.BindStringDisplay.SetToolTip(self.MakeBindString()) - - def MakeBindString(self): - cmdBindStrings = [] - for index in range(self.RearrangeList.GetCount()): - c = self.RearrangeList.GetClientData(index) - if c: cmdBindStrings.append(c.MakeBindString()) - - bindstring = ('$$'.join(cmdBindStrings)) - return bindstring - - def ShowEditDialogFor(self, command): - if not command.UI: return - - self.EditDialog.mainSizer.Show(command.UI) - - self.EditDialog.Layout() - self.EditDialog.Fit() - - self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') - returnval = self.EditDialog.ShowModal() - - self.EditDialog.mainSizer.Hide(command.UI) - - return returnval - - def makeAddStepMenu(self): - - stepMenu = wx.Menu() - - for subname in menuStructure: - submenu = wx.Menu() - stepMenu.AppendSubMenu(submenu, subname) - for classname in menuStructure[subname]: - submenu.Append(wx.ID_ANY, classname) - - stepMenu.Append(wx.ID_ANY, 'Custom Bind') - - return stepMenu - -class PowerBinderButton(wx.BitmapButton): - - def __init__(self, parent, tgtTxtCtrl, init = {}): - wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) - self.Init = init - self.Dialog = None - self.DialogParent = parent - - self.tgtTxtCtrl = tgtTxtCtrl - self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) - self.SetToolTip("Launch PowerBinder") - - def PowerBinderEventHandler(self, _): - self.PowerBinderDialog().Show() - - def LoadFromData(self, data): - self.PowerBinderDialog().LoadFromData(data) - - def SaveToData(self): - return self.PowerBinderDialog().SaveToData() - - def PowerBinderDialog(self): - if not self.Dialog: - self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) - return self.Dialog - - -class PowerBinderEditDialog(wx.Dialog): - def __init__(self, parent): - wx.Dialog.__init__(self, parent, -1, "Edit Step", - style = wx.DEFAULT_DIALOG_STYLE) - - outerSizer = wx.BoxSizer(wx.VERTICAL) - - self.mainSizer = wx.BoxSizer(wx.VERTICAL) - self.mainSizer.SetMinSize([500, 150]) - - self.Page = parent.Page - - self.mainSizer.Add( - self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), - 0, wx.EXPAND|wx.ALL, 10) - - outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) - - self.SetSizerAndFit(outerSizer) - self.Layout() - self.Fit() - -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" - - -####### Away From Keyboard -class AFKCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.Groups = {} - self.AttributeTable = { - 'Base' : { - 'Current Hit Points' : 'NT H', - 'Max Hit Points' : 'X H', - 'Current Endurance' : 'T E', - 'Max Endurance' : 'X EN', - 'Regeneration Rate' : 'N RAT', - 'Recovery Rate' : 'Y RA', - 'Endurance Consumption' : 'SU', - 'ToHit Bonus' : 'T B', - 'Accuracy Bonus' : 'CC', - 'Last Hit Chance' : 'T C', - 'Damage Bonus' : 'DA', - 'Healing Bonus' : 'NG B', - 'Recharge Time Bonus' : 'ME B', - 'Endurance Discount' : 'CE DIS', - 'Stealth Radius (PvP)' : 'PVP', - 'Stealth Radius (PvE)' : 'PVE', - 'Perception Radius' : 'RC', - 'Range Bonus' : 'GE B', - 'Threat Level' : 'AT L', - 'Experience to Next Level' : 'XT', - 'Experience Debt' : 'XP', - 'Influence / Infamy' : 'INF', - 'Inherent' : 'NH', - }, - 'Movement Speed' : { - 'Flying Speed' : 'FL', - 'Jumping Speed' : 'PI', - 'Max Jump Height' : 'X J', - 'Run Speed' : 'RU', - }, - 'Damage Resistance' : { - 'Smashing Resistance' : 'G R', - 'Lethal Resistance' : 'L R', - 'Fire Resistance' : 'RE R', - 'Cold Resistance' : 'COLD R', - 'Energy Resistance' : 'DamageType[4]', - 'Negative Energy Resistance' : 'GY R', - 'Psyonic Resistance' : 'NIC R', - 'Toxic Resistance' : 'XIC R', - }, - 'Defense' : { - 'Base Defense' : 'BAS', - 'Ranged Defense' : 'ED', - 'Melee Defense' : 'MEL', - 'AoE Defense' : '2', - 'Smashing Defense' : '3', - 'Lethal Defense' : '4', - 'Fire Defense' : '5', - 'Cold Defense' : '6', - 'Energy Defense' : '7', - 'Negative Energy Defense' : '8', - 'Psionic Defense' : '9', - 'Toxic Defense' : '1', - }, - 'Debuff Resistance' : { - 'Regeneration Resistance' : 'ON R', - 'Recovery Resistance' : 'RY R', - 'To Hit Resistance' : 'IT R', - 'Defense Resistance' : 'NSE RES', - }, - 'Status Effect Protection' : { - 'Hold Protection' : 'D P', - 'Immobilize Protection' : 'LIZE P', - 'Stun Protection' : 'N P', - 'Sleep Protection' : 'P P', - 'Knockback Protection' : 'K P', - 'Confuse Protection' : 'SE P', - 'Terrorize Protection' : 'ZE P', - 'Repel Protection' : 'EL P', - 'Teleport Protection' : 'T P', - }, - 'Status Effect Resistance' : { - 'Hold Resistance' : 'D R', - 'Immobilize Resistance' : 'LIZE R', - 'Stun Resistance' : 'N R', - 'Sleep Resistance' : 'P R', - 'Knockback Resistance' : 'K R', - 'Confuse Resistance' : 'SE R', - 'Terrorize Resistance' : 'ZE R', - 'Placate Resistance' : 'TE R', - 'Taunt Resistance' : 'NT R', - }, - 'Miscellaneous' : { - 'Level Shift' : 'L S', - }, - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.AttributeMenu = wx.Menu() - for group, controls in self.AttributeTable.items(): - submenu = wx.Menu() - self.AttributeMenu.AppendSubMenu(submenu, group) - for cb in controls: - submenu.Append(wx.ID_ANY, cb) - - self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) - - self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) - groupSizer.Add(self.editbox) - - newButton = self.editbox.GetNewButton() - newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) - - return groupSizer - - def MakeBindString(self): - map = {} - bindstrings = [] - for _, controls in self.AttributeTable.items(): - for cb, data in controls.items(): - map[cb] = data - - for string in self.editbox.GetStrings(): - if string: - bindstrings.append(f'monitorattribute {map[string]}') - - return '$$'.join(bindstrings) - - def Serialize(self): - return { - 'attributes' : self.editbox.GetStrings() - } - - def Deserialize(self, init): - self.editbox.SetStrings(init.get('attributes', [])) - - def OnNewButton(self, evt): - evt.GetEventObject().PopupMenu(self.AttributeMenu) - - def OnMenuItem(self, evt): - menuitem = evt.EventObject.FindItemById(evt.GetId()) - existingstrings = self.editbox.GetStrings() - existingstrings.append(menuitem.GetItemLabel()) - self.editbox.SetStrings(existingstrings) - -####### Auto Power -class AutoPowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) - autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.autoPowerName = PowerPicker(dialog) - autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) - - return autoPowerSizer - - def MakeBindString(self): - return f"powexecauto {self.autoPowerName.GetLabel()}" - - def Serialize(self): - return { - 'pname' : self.autoPowerName.GetLabel(), - 'picon' : self.autoPowerName.IconFilename - } - - def Deserialize(self, init): - if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.buffDisplayMap = { - 'Status Window' : { - 'Hide Auto' : 1, - 'Hide Toggles' : 2, - 'No Blinking' : 4, - 'No Stacking' : 8, - 'Numeric Stacking' : 16, - 'Hide Buff Numbers' : 32, - 'Stop Sending Buffs' : 64, - }, - 'Group Window' : { - 'Hide Auto' : 256, - 'Hide Toggles' : 512, - 'No Blinking' : 1024, - 'No Stacking' : 2048, - 'Numeric Stacking' : 4096, - 'Hide Buff Numbers' : 8192, - 'Stop Sending Buffs' : 16384, - }, - 'Pet Window' : { - 'Hide Auto' : 65536, - 'Hide Toggles' : 131072, - 'No Blinking' : 262144, - 'No Stacking' : 524288, - 'Numeric Stacking' : 1048576, - 'Hide Buff Numbers' : 2097152, - 'Stop Sending Buffs' : 4194304, - }, - } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - for group, controls in self.buffDisplayMap.items(): - self.Groups[group] = ControlGroup(dialog, self.Page, label = group) - groupid = self.Groups[group].GetStaticBox().GetId() - for cb, data in controls.items(): - self.Groups[group].AddControl( - ctlType = 'checkbox', - ctlName = f"{groupid}_{group}_{cb}", - label = cb, - data = data, - ) - - groupSizer.Add(self.Groups[group]) - - return groupSizer - - def CalculateValue(self): - page = wx.App.Get().Main.Profile.CustomBinds - - total = 0 - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] - if checkbox.IsChecked(): - total = total + checkbox.Data - return total - - def MakeBindString(self): - return f"optionset buffsettings {self.CalculateValue()}" - - def Serialize(self): - return { 'value' : self.CalculateValue() } - - def Deserialize(self, init): - value = init.get('value', 0) - - value = value or 0 # in case we had for some reason 'None' stashed in the init values - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] - checkbox.SetValue( checkbox.Data & value ) - -####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - chatCommandSizer = wx.GridBagSizer(5, 5) - self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") - chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) - # row 1 - self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) - self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) - self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) - # row 2 - self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) - self.chatCommandDuration.SetRange(1, 20) - self.chatCommandDuration.SetValue(7) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandDuration, (2,1)) - self.chatCommandChatSize = wx.Choice(dialog, -1, - choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) - self.chatCommandChatSize.SetSelection(5) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) - self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) - self.chatCommandChannel.SetSelection(0) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChannel, (2,5)) - # row 3 - self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") - chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) - self.chatCommandMessage = wx.TextCtrl(dialog, -1) - self.chatCommandMessage.SetHint('Chat Command Text') - chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) - - return chatCommandSizer - - def MakeBindString(self): - duration = self.chatCommandDuration.GetValue() - - choice = self.chatCommandChatSize - index = choice.GetSelection() - size = choice.GetString(index) - - duration = f"" if duration != 7 else "" - size = f"" if size != "1" else "" - - bdcolor = fgcolor = bgcolor = '' - if self.chatCommandUseColorsCB.IsChecked(): - bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - - bdcolor = f"" - fgcolor = f"" - bgcolor = f"" - - beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' - text = self.chatCommandMessage.GetValue() - - choice = self.chatCommandChannel - index = choice.GetSelection() - channel = choice.GetString(index) - - return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" - - def Serialize(self): - return { - 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), - 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), - 'channel' : self.chatCommandChannel .GetSelection(), - 'size' : self.chatCommandChatSize.GetSelection(), - 'duration' : self.chatCommandDuration.GetValue(), - 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'text' : self.chatCommandMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) - if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) - if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) - if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) - if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) - if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) - if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) - if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) - if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - - -####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): - def BuildUI(self, dialog): - chatCommandGlobalSizer = wx.GridBagSizer(5,5) - - self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") - chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) - - self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalChannel.SetHint("Channel") - chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) - - self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') - chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) - - chatCommandGlobalSizer.AddGrowableCol(1) - - return chatCommandGlobalSizer - - def MakeBindString(self): - useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() - channel = self.chatCommandGlobalChannel.GetValue() - message = self.chatCommandGlobalMessage.GetValue() - - preface = "beginchat /" if useBeginchat else "" - - return f'{preface}send "{channel}" {message}' - - def Serialize(self): - return { - 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), - 'channel' : self.chatCommandGlobalChannel.GetValue(), - 'message' : self.chatCommandGlobalMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) - if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) - if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) +from UI.PowerBinderCommand import PowerBinderCommand #######Costume Change -class CostumeChangeCmd(PowerBindCmd): +class CostumeChangeCmd(PowerBinderCommand): + Name = "Costume Change" + Menu = "Social" + def BuildUI(self, dialog): costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) @@ -777,1024 +47,3 @@ def Serialize(self): def Deserialize(self, init): if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) - -####### Movement Command -class MovementCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - self.plusbutton.SetValue(True) - - self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.commandchoice = wx.Choice(dialog, choices = [ - "forward", "left", "right", "backward", "up", "down", - "turnleft", "turnright", "first", "autorun", "clicktomove", - ],) - sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) - self.commandchoice.SetSelection(0) - - self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - pre = post = '' - if self.plusbutton.GetValue() : pre = "+" - elif self.plusplusbutton.GetValue() : pre = "++" - elif self.minusbutton.GetValue() : pre = "-" - elif self.zerobutton.GetValue() : post = " 0" - elif self.onebutton.GetValue() : post = " 1" - - command = self.commandchoice.GetString(self.commandchoice.GetSelection()) - - return f"{pre}{command}{post}" - - def Serialize(self): - mod = '' - if self.plusbutton.GetValue() : mod = "plus" - elif self.plusplusbutton.GetValue() : mod = "plusplus" - elif self.minusbutton.GetValue() : mod = "minus" - elif self.zerobutton.GetValue() : mod = "zero" - elif self.onebutton.GetValue() : mod = "one" - - return { - 'mod' : mod, - 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), - } - - def Deserialize(self, init): - mod = init.get('mod', 'plus') - - if mod == 'plus' : self.plusbutton.SetValue(True) - elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) - elif mod == 'minus' : self.minusbutton.SetValue(True) - elif mod == 'zero' : self.zerobutton.SetValue(True) - elif mod == 'one' : self.onebutton.SetValue(True) - - self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) - -####### Graphics Command -class GraphicsCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.FlexGridSizer(2) - - self.visscalecb = wx.CheckBox(dialog, label = "visscale") - sizer.Add(self.visscalecb) - self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) - sizer.Add(self.visscalesc) - - self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") - sizer.Add(self.dofweightcb) - self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) - sizer.Add(self.dofweightsc) - - self.fsaacb = wx.CheckBox(dialog, label = "fsaa") - sizer.Add(self.fsaacb) - self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) - self.fsaach.SetSelection(0) - sizer.Add(self.fsaach) - - self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") - sizer.Add(self.bloomscalecb) - self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) - self.bloomscalech.SetSelection(0) - sizer.Add(self.bloomscalech) - - self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") - sizer.Add(self.bloomweightcb) - self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) - sizer.Add(self.bloomweightsc) - - self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") - sizer.Add(self.lodbiascb) - self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) - sizer.Add(self.lodbiassc) - - self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") - sizer.Add(self.renderscalecb) - self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) - sizer.Add(self.renderscalesc) - - return sizer - - def MakeBindString(self): - # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. - bindstrings = [] - if self.visscalecb.IsChecked(): - bindstrings.append("visscale " + str(self.visscalesc.GetValue())) - if self.dofweightcb.IsChecked(): - bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) - if self.fsaacb.IsChecked(): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bindstrings.append("fsaa " + fsaavalue) - if self.bloomscalecb.IsChecked(): - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - bindstrings.append("bloomscale " + bloomscalevalue) - if self.bloomweightcb.IsChecked(): - bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) - if self.lodbiascb.IsChecked(): - bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) - if self.renderscalecb.IsChecked(): - bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) - - return '$$'.join(bindstrings) - - def Serialize(self): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - return { - 'visscalecb' : self.visscalecb.IsChecked(), - 'visscalesc' : self.visscalesc.GetValue(), - 'dofweightcb' : self.dofweightcb.IsChecked(), - 'dofweightsc' : self.dofweightsc.GetValue(), - 'fsaacb' : self.fsaacb.IsChecked(), - 'fsaach' : fsaavalue, - 'bloomscalecb' : self.bloomscalecb.IsChecked(), - 'bloomscalech' : bloomscalevalue, - 'bloomweightcb' : self.bloomweightcb.IsChecked(), - 'bloomweightsc' : self.bloomweightsc.GetValue(), - 'lodbiascb' : self.lodbiascb.IsChecked(), - 'lodbiassc' : self.lodbiassc.GetValue(), - 'renderscalecb' : self.renderscalecb.IsChecked(), - 'renderscalesc' : self.renderscalesc.GetValue(), - } - - def Deserialize(self, init): - self.visscalecb.SetValue(init.get('visscalecb', False)) - self.visscalesc.SetValue(init.get('visscalesc', 1.0)) - self.dofweightcb.SetValue(init.get('dofweightcb', False)) - self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) - self.fsaacb.SetValue(init.get('fsaacb', False)) - self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) - self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) - self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) - self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) - self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) - self.lodbiascb.SetValue(init.get('lodbiascb', False)) - self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) - self.renderscalecb.SetValue(init.get('renderscalecb', False)) - self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) - -####### Custom Bind -class CustomBindCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.customBindName = wx.TextCtrl(dialog, -1) - self.customBindName.SetHint('Custom Bind Text') - sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - return self.customBindName.GetValue() - - def Serialize(self): - return { 'customBindName': self.customBindName.GetValue() } - - def Deserialize(self,init): - if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) - -####### Emote -class EmoteCmd(PowerBindCmd): - def BuildUI(self, dialog): - emoteSizer = wx.BoxSizer(wx.HORIZONTAL) - self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") - emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - self.emoteName = wx.Button(dialog, -1, "...") - self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) - emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) - - return emoteSizer - - def MakeBindString(self): - displayedEmoteName = self.emoteName.GetLabel() - actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] - - return actualEmotePayload - - def Serialize(self): - return {'emoteName': self.emoteName.GetLabel()} - - def Deserialize(self, init): - if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) - -####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): - def BuildUI(self, dialog): - mainSizer = wx.BoxSizer(wx.VERTICAL) - - lbSizer = wx.BoxSizer(wx.HORIZONTAL) - lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") - lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - profiles = Profile.GetAllProfileBindsDirs() - - self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) - lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) - - mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") - self.lbResetCB.SetValue(True) - - mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - return mainSizer - - def MakeBindString(self): - - # If the specified binds directory disappeared between runs, we'd crash, so handle that. - if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' - - config = wx.ConfigBase.Get() - if config.Exists('GameBindPath'): - bindpath = config.Read('GameBindPath') - else: - bindpath = config.Read('BindPath') - - reset = "" - if self.lbResetCB.GetValue(): - reset = "keybind_reset$$" - - resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' - return reset + 'bindloadfile ' + str(resetfilepath) - - def Serialize(self): - return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), - 'ResetKeybinds' : self.lbResetCB.GetValue(), - } - - def Deserialize(self, init): - if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) - self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) - -####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' - -####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' - -####### SG Mode -class SGModeCmd(PowerBindCmd): - def BuildUI(self, dialog): - sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) - sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") - self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") - - sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) - - return sgmodeSizer - - def MakeBindString(self): - if self.sgmodeOnRB.GetValue(): - return 'sgmodeset 1' - elif self.sgmodeOffRB.GetValue(): - return 'sgmodeset 0' - else: - return 'sgmode' - - def Serialize(self): - if self.sgmodeOnRB.GetValue(): - val = "On" - elif self.sgmodeOffRB.GetValue(): - val = "Off" - else: - val = "Toggle" - - return {"value" : val} - - def Deserialize(self, init): - val = init.get('value', '') - if val == "On": - self.sgmodeOnRB.SetValue(True) - elif val == "Off": - self.sgmodeOffRB.SetValue(True) - else: - self.sgmodeToggleRB.SetValue(True) - -####### Target Custom -class TargetCustomCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetCustomSizer = wx.GridBagSizer(5,5) - targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), - flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) - self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetCustomModeChoice.SetSelection(0) - targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) - self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) - self.targetCustomOptionalName.SetHint("Optional name to match") - targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) - self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") - targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) - self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") - targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) - self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") - targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) - self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") - targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) - self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") - targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) - self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") - targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) - self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") - targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) - self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") - targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) - - targetCustomSizer.AddGrowableCol(2) - - return targetCustomSizer - - def MakeBindString(self): - choice = self.targetCustomModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - targetCommand = "targetcustom" + mode.lower() - - enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" - friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" - defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" - alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" - mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" - notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" - base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" - notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" - - name = self.targetCustomOptionalName.GetValue() - - return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" - - def Serialize(self): - return { - 'mode' : self.targetCustomModeChoice.GetSelection(), - 'enemy' : self.targetCustomCBEnemies. IsChecked(), - 'friend' : self.targetCustomCBFriends. IsChecked(), - 'defeated' : self.targetCustomCBDefeated. IsChecked(), - 'alive' : self.targetCustomCBAlive. IsChecked(), - 'mypet' : self.targetCustomCBMyPets. IsChecked(), - 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), - 'base' : self.targetCustomCBBaseItems. IsChecked(), - 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), - 'name' : self.targetCustomOptionalName.GetValue(), - } - - def Deserialize(self, init): - if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) - if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) - if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) - if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) - if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) - if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) - if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) - if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) - if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) - if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - - -####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) - targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetEnemyModeChoice.SetSelection(0) - targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetEnemySizer - - def MakeBindString(self): - choice = self.targetEnemyModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetenemy" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetEnemyModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) - -####### Target Friend -class TargetFriendCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) - targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetFriendModeChoice.SetSelection(0) - targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetFriendSizer - - def MakeBindString(self): - choice = self.targetFriendModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetfriend" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetFriendModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) - -####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): - def BuildUI(self, dialog): - teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], - style=wx.ALIGN_CENTER_VERTICAL) - self.teamPetSelectNumber.SetSelection(0) - teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) - - return teamPetSelectSizer - - def MakeBindString(self): - teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' - targetNumber = self.teamPetSelectNumber.GetSelection()+1 - - return f"{teamOrPet}select {targetNumber}" - - def Serialize(self): - return { - 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', - 'targetNum': self.teamPetSelectNumber.GetSelection(), - } - - def Deserialize(self, init): - ToP = init.get('teamOrPet', '') - if ToP == 'pet': - self.teamPetSelectPetRB.SetValue(True) - else: - self.teamPetSelectTeamRB.SetValue(True) - if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) - -####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' - -####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) - for _, types in GameData.Inspirations.items(): - for _, info in types.items(): - for insp in info['tiers']: - name = re.sub(' ', '', str(insp)) - icon = GetIcon(f'Inspirations/{name}') - self.useInspByNameModeChoice.Append(insp, icon) - self.useInspByNameModeChoice.SetSelection(0) - useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) - - return useInspByNameSizer - - def MakeBindString(self): - choice = self.useInspByNameModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "inspexecname " + mode.lower() - - def GetAllInsps(self): - Insplist = [] - for _, info in GameData.Inspirations.items(): - for insp in info['tiers']: - Insplist.append(insp) - Insplist.append("---") - Insplist.pop(-1) # snip the terminal "---" - - return Insplist - - def Serialize(self): - return { 'insp' : self.useInspByNameModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) - -####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnRow.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) - self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnCol.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) - - return useInspRowColumnSizer - - def MakeBindString(self): - row = self.useInspRowColumnRow.GetSelection()+1 - col = self.useInspRowColumnCol.GetSelection()+1 - - return f"inspexectray {col} {row}" - - def Serialize(self): - return { - 'col' : self.useInspRowColumnCol.GetSelection(), - 'row' : self.useInspRowColumnRow.GetSelection(), - } - - def Deserialize(self, init): - if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) - if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) - -####### Use Power -class UsePowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - outerSizer = wx.BoxSizer(wx.HORIZONTAL) - - usePowerSizer = wx.GridBagSizer(5,5) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBToggle, (0,1)) - self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOn, (0,2)) - self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOff, (0,3)) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerName = PowerPicker(dialog) - usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) - usePowerSizer.AddGrowableCol(3) - - outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) - - return outerSizer - - def MakeBindString(self): - if self.usePowerRBToggle.GetValue(): - method = "powexecname" - elif self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') - return '' - - return f"{method} {self.usePowerName.GetLabel()}" - - def Serialize(self): - if self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - method = "powexecname" - return { - 'method': method, - 'pname' : self.usePowerName.GetLabel(), - 'picon' : self.usePowerName.IconFilename - } - - def Deserialize(self, init): - method = init.get('method', '') - if method == 'powexectoggleon': - self.usePowerRBOn.SetValue(True) - elif method == 'powexectoggleoff': - self.usePowerRBOff.SetValue(True) - else: - self.usePowerRBToggle.SetValue(True) - if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) - -####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): - def BuildUI(self, dialog): - usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTrayTray = wx.Choice(dialog, -1, - choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', - 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) - self.usePowerFromTrayTray.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) - self.usePowerFromTraySlot.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return usePowerFromTraySizer - - def MakeBindString(self): - choice = self.usePowerFromTrayTray - tray = choice.GetSelection() - - choice = self.usePowerFromTraySlot - slot = choice.GetSelection()+1 - - mode = "slot" - mode2 = '' - if tray > 3: - mode = "tray" - mode2 = f" {tray - 3}" - elif tray == 3: - mode = "alt2slot" - elif tray == 2: - mode = "altslot" - - return f"powexec{mode} {slot}{mode2}" - - def Serialize(self): - return { - 'tray' : self.usePowerFromTrayTray.GetSelection(), - 'slot' : self.usePowerFromTraySlot.GetSelection(), - } - - def Deserialize(self, init): - if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) - if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) - -####### Window Color -class WindowColorCmd(PowerBindCmd): - def BuildUI(self, dialog): - windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) - borderSizer = wx.BoxSizer(wx.VERTICAL) - self.ColorBorder.SetSizer(borderSizer) - self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) - borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) - - windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) - - RGBASizer = wx.FlexGridSizer(3, 4, 5) - - RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) - self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) - self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - windowColorSizer.Add(RGBASizer) - - self.UpdateFromSlider() - - return windowColorSizer - - def MakeBindString(self): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - return f"windowcolor {Rval} {Gval} {Bval} {Aval}" - - def Serialize(self): - return { - 'Rval' : self.RSlider.GetValue(), - 'Gval' : self.GSlider.GetValue(), - 'Bval' : self.BSlider.GetValue(), - 'Aval' : self.ASlider.GetValue(), - } - - def Deserialize(self, init): - self.RSlider.SetValue(init['Rval']) - self.GSlider.SetValue(init['Gval']) - self.BSlider.SetValue(init['Bval']) - self.ASlider.SetValue(init['Aval']) - self.UpdateFromSlider() - - def UpdateFromSlider(self, _ = None): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RReadout.SetValue(Rval) - self.GReadout.SetValue(Gval) - self.BReadout.SetValue(Bval) - self.AReadout.SetValue(Aval) - self.ColorBorder.Refresh() - - def UpdateFromText(self, _ = None): - Rval = self.RReadout.GetValue() - Gval = self.GReadout.GetValue() - Bval = self.BReadout.GetValue() - Aval = self.AReadout.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RSlider.SetValue(Rval) - self.GSlider.SetValue(Gval) - self.BSlider.SetValue(Bval) - self.ASlider.SetValue(Aval) - self.ColorBorder.Refresh() - -####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) - self.CommandChoice.SetSelection(0) - sizer.Add(self.CommandChoice, 0, wx.ALL, 5) - - self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), - value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) - sizer.Add(self.FilePath, 0, wx.ALL, 5) - - return sizer - - def MakeBindString(self): - command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] - return f'{command} "{self.FilePath.GetValue()}"' - - def Serialize(self): - return { - 'command' : self.CommandChoice.GetSelection(), - 'filename' : self.FilePath.GetValue(), - } - - def Deserialize(self, init): - self.CommandChoice.SetSelection(init.get('command', 0)) - self.FilePath.SetValue(init.get('filename', '')) - -####### Window Toggle -class WindowToggleCmd(PowerBindCmd): - def BuildUI(self, dialog): - self.WindowNames = { - 'Actions' : 'actions', - 'Auction House' : 'ah', - 'Badge' : 'badge', - 'Channel Search' : 'chansearch', - 'Chat' : 'chat', - 'Custom Chat 1' : 'chat1', - 'Custom Chat 2' : 'chat2', - 'Custom Chat 3' : 'chat3', - 'Custom Chat 4' : 'chat4', - 'Clues' : 'clue', - 'Combat Numbers' : 'combatnumbers', - 'Contacts' : 'contact', - 'Contact Finder' : 'contactfinder', - 'Costumes' : 'costume', - 'Email' : 'email', - 'Enhancements' : 'enhancements', - 'Friends' : 'friend', - 'Group' : 'group', - 'Help' : 'helpwindow', - 'Incarnate' : 'incarnate', - 'Inspirations' : 'insp', - 'League' : 'league', - 'LFG' : 'lfg', - 'Map' : 'map', - 'Mission' : 'mission', - 'Nav / Compass' : 'nav', - 'Options' : 'options', - 'Pets' : 'pet', - 'Petition' : 'petition', - 'Power Tray' : 'powers', - 'Power List' : 'powerlist', - 'Quit' : 'quit', - 'Recipes' : 'recipe', - 'Salvage' : 'salvage', - 'Search' : 'search', - 'Supergroup' : 'sg', - 'Target' : 'target', - 'Team' : 'team', - 'Tray' : 'tray', - 'Tray1' : 'tray1', - 'Tray2' : 'tray2', - 'Tray3' : 'tray3', - 'Tray4' : 'tray4', - 'Tray5' : 'tray5', - 'Tray6' : 'tray6', - 'Tray7' : 'tray7', - 'Tray8' : 'tray8', - 'Vault' : 'vault', - } - - self.ShortToggleCommands = { - 'Auction House' : 'ah', - 'Chat' : 'chat', - 'Help' : 'helpwindow', - 'Map' : 'map', - 'Nav / Compass' : 'nav', - 'Power Tray' : 'powers', - 'Target' : 'target', - 'Tray' : 'tray', - } - - windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) - windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) - self.windowToggleTray.SetSelection(0) - windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.windowShowRB = wx.RadioButton(dialog, -1, "Show") - self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") - - windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) - - return windowToggleSizer - - def MakeBindString(self): - choice = self.windowToggleTray - index = choice.GetSelection() - windowdesc = choice.GetString(index) - windowname = self.WindowNames[windowdesc] - - if self.windowShowRB.GetValue(): - return 'show ' + windowname - elif self.windowHideRB.GetValue(): - return 'windowhide ' + windowname - else: - if shortcmd := self.ShortToggleCommands.get(windowdesc, None): - return shortcmd - else: - return 'toggle ' + windowname - - - def Serialize(self): - choice = self.windowToggleTray - if self.windowShowRB.GetValue(): - action = "Show" - elif self.windowHideRB.GetValue(): - action = "Hide" - else: - action = "Toggle" - return { - 'window': choice.GetString(choice.GetSelection()), - 'action': action, - } - - def Deserialize(self, init): - choice = self.windowToggleTray - if window := init.get('window', ''): - if isinstance(window, int): - choice.SetSelection(window) - else: - choice.SetSelection(choice.FindString(window)) - - if choice.GetSelection() == wx.NOT_FOUND: - choice.SetSelection(0) - - action = init.get('action', '') - if action == "Show": - self.windowShowRB.SetValue(True) - elif action == "Hide": - self.windowHideRB.SetValue(True) - else: - self.windowToggleRB.SetValue(True) - - -# Must always add to this list when adding a new command class above -menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], - # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, - # but I'm leaving it here to remind myself that we do that. - } - -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/CustomBindCmd.py b/UI/PowerBinderCommand/CustomBindCmd.py index 4c02ab7..6d0a669 100644 --- a/UI/PowerBinderCommand/CustomBindCmd.py +++ b/UI/PowerBinderCommand/CustomBindCmd.py @@ -1,965 +1,11 @@ import wx -import re -import UI -import UI.EmotePicker -from UI.ControlGroup import ControlGroup -from UI.PowerPicker import PowerPicker -from Help import HelpButton -import wx.adv -from wx.adv import BitmapComboBox, EditableListBox -from pathlib import PureWindowsPath -import GameData -import Profile -from Icon import GetIcon - -class PowerBinderDialog(wx.Dialog): - def __init__(self, parent, button, init = {}): - wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) - - self.Page = parent.Page - self.EditDialog = PowerBinderEditDialog(self) - self.Button = button - self.AddStepMenu = self.makeAddStepMenu() - - sizer = wx.BoxSizer(wx.VERTICAL); - self.mainSizer = sizer - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) - AddStepButton = wx.Button(self, -1, 'Add Step') - AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) - AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) - choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) - choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) - sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) - - rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) - - self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) - self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) - self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) - rearrangeCtrl.Add(self.RearrangeList, 1) - - rearrangeButtons = wx.BoxSizer(wx.VERTICAL) - self.DelButton = wx.Button(self, -1, "Delete") - self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) - self.EditButton = wx.Button(self, -1, "Edit") - self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) - self.EditButton.Disable() - upButton = wx.Button(self, -1, "\u25B2") - upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) - downButton = wx.Button(self, -1, "\u25BC") - downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) - rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) - rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) - - sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.BindStringDisplay = wx.TextCtrl(self, -1) - self.BindStringDisplay.Disable() - choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, - wx.ALIGN_CENTER_VERTICAL) - choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) - - sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) - - sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) - - # need to dig around and get the OK button since we show this dialog modelessly now. - okButton = self.FindWindow(self.GetAffirmativeId()) - okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) - - # Wrap everything in a vbox to add some padding - vbox = wx.BoxSizer(wx.VERTICAL); - vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); - - self.SetSizerAndFit(vbox); - self.Layout() - self.Fit() - self.SetFocus() - - # if we are loading from profile, ie, have "init", build the list from it - if init: self.LoadFromData(init) - - def LoadFromData(self, init): - for item in init: - for type, data in item.items(): - commandClass = commandClasses.get(type, None) - if not commandClass: - commandClass = deprecatedCommandClasses.get(type, None) - if not commandClass: - wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") - continue - newCommand = commandClass(self.EditDialog, data) - index = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.SetClientData(index, newCommand) - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) - self.EditDialog.mainSizer.Hide(newCommand.UI) - self.UpdateBindStringDisplay() - - def SaveToData(self): - data = [] - index = 0 - for _ in self.RearrangeList.GetItems(): - # check whether we have an object already attached to this choice - cmdObject = self.RearrangeList.GetClientData(index) - commandClassName = commandRevClasses[type(cmdObject)] - data.append({commandClassName: cmdObject.Serialize()}) - index = index + 1 - return data - - def OnAddStepButton(self, evt): - button = evt.EventObject - if not self.AddStepMenu: - self.AddStepMenu = self.makeAddStepMenu() - button.PopupMenu(self.AddStepMenu) - - - def OnOKButton(self, _): - if self.Button.tgtTxtCtrl: - bindString = self.MakeBindString() - if bindString != self.Button.tgtTxtCtrl.GetValue(): - self.Button.tgtTxtCtrl.SetValue(bindString) - wx.App.Get().Main.Profile.SetModified() - self.Close() - - def OnRearrangeDelete(self, _): - current = self.RearrangeList.GetSelection() - if current == wx.NOT_FOUND: return - - self.RearrangeList.Delete(current) - self.UpdateBindStringDisplay() - - def OnRearrangeUp(self, _): - self.RearrangeList.MoveCurrentUp() - self.UpdateBindStringDisplay() - - def OnRearrangeDown(self, _): - self.RearrangeList.MoveCurrentDown() - self.UpdateBindStringDisplay() - - def OnRearrangeEdit(self, _): - index = self.RearrangeList.GetSelection() - - # check whether we have an object already attached to this choice - cmdObject = None - try: - cmdObject = self.RearrangeList.GetClientData(index) - except Exception: - pass - - if cmdObject: - self.ShowEditDialogFor(cmdObject) - self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) - else: - print("cmdObject was None") - self.UpdateBindStringDisplay() - - # OnAddStepMenu creates a new step and adds it to the rearrangelist - def OnAddStepMenu(self, evt): - menuitem = self.AddStepMenu.FindItemById(evt.GetId()) - chosenName = menuitem.GetItemLabel() - - # make a new command object, attached to the parent dialog - newCommandClass = commandClasses[chosenName] - newCommand = newCommandClass(self.EditDialog) - - # show the edit dialog if this command needs it - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) - if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): - self.EditDialog.mainSizer.Remove(newCommand.UI) - return - - newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.Select(newBindIndex) - self.RearrangeList.SetClientData(newBindIndex, newCommand) - - self.OnListSelect() - self.UpdateBindStringDisplay() - - def OnListSelect(self, _ = None): - selected = self.RearrangeList.GetSelection() - - if selected != wx.NOT_FOUND: - selCommand = self.RearrangeList.GetClientData(selected) - if selCommand.UI: - self.EditButton.Enable() - else: - self.EditButton.Disable() - - def UpdateBindStringDisplay(self): - self.BindStringDisplay.SetValue(self.MakeBindString()) - self.BindStringDisplay.SetToolTip(self.MakeBindString()) - - def MakeBindString(self): - cmdBindStrings = [] - for index in range(self.RearrangeList.GetCount()): - c = self.RearrangeList.GetClientData(index) - if c: cmdBindStrings.append(c.MakeBindString()) - - bindstring = ('$$'.join(cmdBindStrings)) - return bindstring - - def ShowEditDialogFor(self, command): - if not command.UI: return - - self.EditDialog.mainSizer.Show(command.UI) - - self.EditDialog.Layout() - self.EditDialog.Fit() - - self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') - returnval = self.EditDialog.ShowModal() - - self.EditDialog.mainSizer.Hide(command.UI) - - return returnval - - def makeAddStepMenu(self): - - stepMenu = wx.Menu() - - for subname in menuStructure: - submenu = wx.Menu() - stepMenu.AppendSubMenu(submenu, subname) - for classname in menuStructure[subname]: - submenu.Append(wx.ID_ANY, classname) - - stepMenu.Append(wx.ID_ANY, 'Custom Bind') - - return stepMenu - -class PowerBinderButton(wx.BitmapButton): - - def __init__(self, parent, tgtTxtCtrl, init = {}): - wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) - self.Init = init - self.Dialog = None - self.DialogParent = parent - - self.tgtTxtCtrl = tgtTxtCtrl - self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) - self.SetToolTip("Launch PowerBinder") - - def PowerBinderEventHandler(self, _): - self.PowerBinderDialog().Show() - - def LoadFromData(self, data): - self.PowerBinderDialog().LoadFromData(data) - - def SaveToData(self): - return self.PowerBinderDialog().SaveToData() - - def PowerBinderDialog(self): - if not self.Dialog: - self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) - return self.Dialog - - -class PowerBinderEditDialog(wx.Dialog): - def __init__(self, parent): - wx.Dialog.__init__(self, parent, -1, "Edit Step", - style = wx.DEFAULT_DIALOG_STYLE) - - outerSizer = wx.BoxSizer(wx.VERTICAL) - - self.mainSizer = wx.BoxSizer(wx.VERTICAL) - self.mainSizer.SetMinSize([500, 150]) - - self.Page = parent.Page - - self.mainSizer.Add( - self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), - 0, wx.EXPAND|wx.ALL, 10) - - outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) - - self.SetSizerAndFit(outerSizer) - self.Layout() - self.Fit() - -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" - - -####### Away From Keyboard -class AFKCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.Groups = {} - self.AttributeTable = { - 'Base' : { - 'Current Hit Points' : 'NT H', - 'Max Hit Points' : 'X H', - 'Current Endurance' : 'T E', - 'Max Endurance' : 'X EN', - 'Regeneration Rate' : 'N RAT', - 'Recovery Rate' : 'Y RA', - 'Endurance Consumption' : 'SU', - 'ToHit Bonus' : 'T B', - 'Accuracy Bonus' : 'CC', - 'Last Hit Chance' : 'T C', - 'Damage Bonus' : 'DA', - 'Healing Bonus' : 'NG B', - 'Recharge Time Bonus' : 'ME B', - 'Endurance Discount' : 'CE DIS', - 'Stealth Radius (PvP)' : 'PVP', - 'Stealth Radius (PvE)' : 'PVE', - 'Perception Radius' : 'RC', - 'Range Bonus' : 'GE B', - 'Threat Level' : 'AT L', - 'Experience to Next Level' : 'XT', - 'Experience Debt' : 'XP', - 'Influence / Infamy' : 'INF', - 'Inherent' : 'NH', - }, - 'Movement Speed' : { - 'Flying Speed' : 'FL', - 'Jumping Speed' : 'PI', - 'Max Jump Height' : 'X J', - 'Run Speed' : 'RU', - }, - 'Damage Resistance' : { - 'Smashing Resistance' : 'G R', - 'Lethal Resistance' : 'L R', - 'Fire Resistance' : 'RE R', - 'Cold Resistance' : 'COLD R', - 'Energy Resistance' : 'DamageType[4]', - 'Negative Energy Resistance' : 'GY R', - 'Psyonic Resistance' : 'NIC R', - 'Toxic Resistance' : 'XIC R', - }, - 'Defense' : { - 'Base Defense' : 'BAS', - 'Ranged Defense' : 'ED', - 'Melee Defense' : 'MEL', - 'AoE Defense' : '2', - 'Smashing Defense' : '3', - 'Lethal Defense' : '4', - 'Fire Defense' : '5', - 'Cold Defense' : '6', - 'Energy Defense' : '7', - 'Negative Energy Defense' : '8', - 'Psionic Defense' : '9', - 'Toxic Defense' : '1', - }, - 'Debuff Resistance' : { - 'Regeneration Resistance' : 'ON R', - 'Recovery Resistance' : 'RY R', - 'To Hit Resistance' : 'IT R', - 'Defense Resistance' : 'NSE RES', - }, - 'Status Effect Protection' : { - 'Hold Protection' : 'D P', - 'Immobilize Protection' : 'LIZE P', - 'Stun Protection' : 'N P', - 'Sleep Protection' : 'P P', - 'Knockback Protection' : 'K P', - 'Confuse Protection' : 'SE P', - 'Terrorize Protection' : 'ZE P', - 'Repel Protection' : 'EL P', - 'Teleport Protection' : 'T P', - }, - 'Status Effect Resistance' : { - 'Hold Resistance' : 'D R', - 'Immobilize Resistance' : 'LIZE R', - 'Stun Resistance' : 'N R', - 'Sleep Resistance' : 'P R', - 'Knockback Resistance' : 'K R', - 'Confuse Resistance' : 'SE R', - 'Terrorize Resistance' : 'ZE R', - 'Placate Resistance' : 'TE R', - 'Taunt Resistance' : 'NT R', - }, - 'Miscellaneous' : { - 'Level Shift' : 'L S', - }, - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.AttributeMenu = wx.Menu() - for group, controls in self.AttributeTable.items(): - submenu = wx.Menu() - self.AttributeMenu.AppendSubMenu(submenu, group) - for cb in controls: - submenu.Append(wx.ID_ANY, cb) - - self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) - - self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) - groupSizer.Add(self.editbox) - - newButton = self.editbox.GetNewButton() - newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) - - return groupSizer - - def MakeBindString(self): - map = {} - bindstrings = [] - for _, controls in self.AttributeTable.items(): - for cb, data in controls.items(): - map[cb] = data - - for string in self.editbox.GetStrings(): - if string: - bindstrings.append(f'monitorattribute {map[string]}') - - return '$$'.join(bindstrings) - - def Serialize(self): - return { - 'attributes' : self.editbox.GetStrings() - } - - def Deserialize(self, init): - self.editbox.SetStrings(init.get('attributes', [])) - - def OnNewButton(self, evt): - evt.GetEventObject().PopupMenu(self.AttributeMenu) - - def OnMenuItem(self, evt): - menuitem = evt.EventObject.FindItemById(evt.GetId()) - existingstrings = self.editbox.GetStrings() - existingstrings.append(menuitem.GetItemLabel()) - self.editbox.SetStrings(existingstrings) - -####### Auto Power -class AutoPowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) - autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.autoPowerName = PowerPicker(dialog) - autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) - - return autoPowerSizer - - def MakeBindString(self): - return f"powexecauto {self.autoPowerName.GetLabel()}" - - def Serialize(self): - return { - 'pname' : self.autoPowerName.GetLabel(), - 'picon' : self.autoPowerName.IconFilename - } - - def Deserialize(self, init): - if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.buffDisplayMap = { - 'Status Window' : { - 'Hide Auto' : 1, - 'Hide Toggles' : 2, - 'No Blinking' : 4, - 'No Stacking' : 8, - 'Numeric Stacking' : 16, - 'Hide Buff Numbers' : 32, - 'Stop Sending Buffs' : 64, - }, - 'Group Window' : { - 'Hide Auto' : 256, - 'Hide Toggles' : 512, - 'No Blinking' : 1024, - 'No Stacking' : 2048, - 'Numeric Stacking' : 4096, - 'Hide Buff Numbers' : 8192, - 'Stop Sending Buffs' : 16384, - }, - 'Pet Window' : { - 'Hide Auto' : 65536, - 'Hide Toggles' : 131072, - 'No Blinking' : 262144, - 'No Stacking' : 524288, - 'Numeric Stacking' : 1048576, - 'Hide Buff Numbers' : 2097152, - 'Stop Sending Buffs' : 4194304, - }, - } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - for group, controls in self.buffDisplayMap.items(): - self.Groups[group] = ControlGroup(dialog, self.Page, label = group) - groupid = self.Groups[group].GetStaticBox().GetId() - for cb, data in controls.items(): - self.Groups[group].AddControl( - ctlType = 'checkbox', - ctlName = f"{groupid}_{group}_{cb}", - label = cb, - data = data, - ) - - groupSizer.Add(self.Groups[group]) - - return groupSizer - - def CalculateValue(self): - page = wx.App.Get().Main.Profile.CustomBinds - - total = 0 - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] - if checkbox.IsChecked(): - total = total + checkbox.Data - return total - - def MakeBindString(self): - return f"optionset buffsettings {self.CalculateValue()}" - - def Serialize(self): - return { 'value' : self.CalculateValue() } - - def Deserialize(self, init): - value = init.get('value', 0) - - value = value or 0 # in case we had for some reason 'None' stashed in the init values - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] - checkbox.SetValue( checkbox.Data & value ) - -####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - chatCommandSizer = wx.GridBagSizer(5, 5) - self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") - chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) - # row 1 - self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) - self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) - self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) - # row 2 - self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) - self.chatCommandDuration.SetRange(1, 20) - self.chatCommandDuration.SetValue(7) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandDuration, (2,1)) - self.chatCommandChatSize = wx.Choice(dialog, -1, - choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) - self.chatCommandChatSize.SetSelection(5) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) - self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) - self.chatCommandChannel.SetSelection(0) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChannel, (2,5)) - # row 3 - self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") - chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) - self.chatCommandMessage = wx.TextCtrl(dialog, -1) - self.chatCommandMessage.SetHint('Chat Command Text') - chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) - - return chatCommandSizer - - def MakeBindString(self): - duration = self.chatCommandDuration.GetValue() - - choice = self.chatCommandChatSize - index = choice.GetSelection() - size = choice.GetString(index) - - duration = f"" if duration != 7 else "" - size = f"" if size != "1" else "" - - bdcolor = fgcolor = bgcolor = '' - if self.chatCommandUseColorsCB.IsChecked(): - bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - - bdcolor = f"" - fgcolor = f"" - bgcolor = f"" - - beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' - text = self.chatCommandMessage.GetValue() - - choice = self.chatCommandChannel - index = choice.GetSelection() - channel = choice.GetString(index) - - return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" - - def Serialize(self): - return { - 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), - 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), - 'channel' : self.chatCommandChannel .GetSelection(), - 'size' : self.chatCommandChatSize.GetSelection(), - 'duration' : self.chatCommandDuration.GetValue(), - 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'text' : self.chatCommandMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) - if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) - if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) - if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) - if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) - if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) - if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) - if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) - if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - - -####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): - def BuildUI(self, dialog): - chatCommandGlobalSizer = wx.GridBagSizer(5,5) - - self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") - chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) - - self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalChannel.SetHint("Channel") - chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) - - self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') - chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) - - chatCommandGlobalSizer.AddGrowableCol(1) - - return chatCommandGlobalSizer - - def MakeBindString(self): - useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() - channel = self.chatCommandGlobalChannel.GetValue() - message = self.chatCommandGlobalMessage.GetValue() - - preface = "beginchat /" if useBeginchat else "" - - return f'{preface}send "{channel}" {message}' - - def Serialize(self): - return { - 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), - 'channel' : self.chatCommandGlobalChannel.GetValue(), - 'message' : self.chatCommandGlobalMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) - if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) - if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) - -#######Costume Change -class CostumeChangeCmd(PowerBindCmd): - def BuildUI(self, dialog): - costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeCostume = wx.Choice(dialog, -1, - choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) - self.costumeChangeCostume.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeEmote = wx.Choice(dialog, -1, - choices = GameData.Emotes['costumechange']) - self.costumeChangeEmote.Insert("- None -", 0) - self.costumeChangeEmote.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return costumeChangeSizer - - def MakeBindString(self): - costumeNumber = self.costumeChangeCostume.GetSelection() - costumeEmote = self.costumeChangeEmote.GetSelection() - - if costumeEmote: # None, or 0 == "- None -" - ccCmd = 'cce' - emoteName = self.costumeChangeEmote.GetString(costumeEmote) - emoteName = " CC" + emoteName.replace(" ","") - else: - ccCmd = 'cc' - emoteName = '' - - return f"{ccCmd} {costumeNumber}{emoteName}" - - def Serialize(self): - return{ - 'costumeNumber': self.costumeChangeCostume.GetSelection(), - 'costumeEmote' : self.costumeChangeEmote.GetSelection(), - } - - def Deserialize(self, init): - if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) - if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) - -####### Movement Command -class MovementCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - self.plusbutton.SetValue(True) - - self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.commandchoice = wx.Choice(dialog, choices = [ - "forward", "left", "right", "backward", "up", "down", - "turnleft", "turnright", "first", "autorun", "clicktomove", - ],) - sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) - self.commandchoice.SetSelection(0) - - self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - pre = post = '' - if self.plusbutton.GetValue() : pre = "+" - elif self.plusplusbutton.GetValue() : pre = "++" - elif self.minusbutton.GetValue() : pre = "-" - elif self.zerobutton.GetValue() : post = " 0" - elif self.onebutton.GetValue() : post = " 1" - - command = self.commandchoice.GetString(self.commandchoice.GetSelection()) - - return f"{pre}{command}{post}" - - def Serialize(self): - mod = '' - if self.plusbutton.GetValue() : mod = "plus" - elif self.plusplusbutton.GetValue() : mod = "plusplus" - elif self.minusbutton.GetValue() : mod = "minus" - elif self.zerobutton.GetValue() : mod = "zero" - elif self.onebutton.GetValue() : mod = "one" - - return { - 'mod' : mod, - 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), - } - - def Deserialize(self, init): - mod = init.get('mod', 'plus') - - if mod == 'plus' : self.plusbutton.SetValue(True) - elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) - elif mod == 'minus' : self.minusbutton.SetValue(True) - elif mod == 'zero' : self.zerobutton.SetValue(True) - elif mod == 'one' : self.onebutton.SetValue(True) - - self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) - -####### Graphics Command -class GraphicsCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.FlexGridSizer(2) - - self.visscalecb = wx.CheckBox(dialog, label = "visscale") - sizer.Add(self.visscalecb) - self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) - sizer.Add(self.visscalesc) - - self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") - sizer.Add(self.dofweightcb) - self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) - sizer.Add(self.dofweightsc) - - self.fsaacb = wx.CheckBox(dialog, label = "fsaa") - sizer.Add(self.fsaacb) - self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) - self.fsaach.SetSelection(0) - sizer.Add(self.fsaach) - - self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") - sizer.Add(self.bloomscalecb) - self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) - self.bloomscalech.SetSelection(0) - sizer.Add(self.bloomscalech) - - self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") - sizer.Add(self.bloomweightcb) - self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) - sizer.Add(self.bloomweightsc) - - self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") - sizer.Add(self.lodbiascb) - self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) - sizer.Add(self.lodbiassc) - - self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") - sizer.Add(self.renderscalecb) - self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) - sizer.Add(self.renderscalesc) - - return sizer - - def MakeBindString(self): - # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. - bindstrings = [] - if self.visscalecb.IsChecked(): - bindstrings.append("visscale " + str(self.visscalesc.GetValue())) - if self.dofweightcb.IsChecked(): - bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) - if self.fsaacb.IsChecked(): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bindstrings.append("fsaa " + fsaavalue) - if self.bloomscalecb.IsChecked(): - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - bindstrings.append("bloomscale " + bloomscalevalue) - if self.bloomweightcb.IsChecked(): - bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) - if self.lodbiascb.IsChecked(): - bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) - if self.renderscalecb.IsChecked(): - bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) - - return '$$'.join(bindstrings) - - def Serialize(self): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - return { - 'visscalecb' : self.visscalecb.IsChecked(), - 'visscalesc' : self.visscalesc.GetValue(), - 'dofweightcb' : self.dofweightcb.IsChecked(), - 'dofweightsc' : self.dofweightsc.GetValue(), - 'fsaacb' : self.fsaacb.IsChecked(), - 'fsaach' : fsaavalue, - 'bloomscalecb' : self.bloomscalecb.IsChecked(), - 'bloomscalech' : bloomscalevalue, - 'bloomweightcb' : self.bloomweightcb.IsChecked(), - 'bloomweightsc' : self.bloomweightsc.GetValue(), - 'lodbiascb' : self.lodbiascb.IsChecked(), - 'lodbiassc' : self.lodbiassc.GetValue(), - 'renderscalecb' : self.renderscalecb.IsChecked(), - 'renderscalesc' : self.renderscalesc.GetValue(), - } - - def Deserialize(self, init): - self.visscalecb.SetValue(init.get('visscalecb', False)) - self.visscalesc.SetValue(init.get('visscalesc', 1.0)) - self.dofweightcb.SetValue(init.get('dofweightcb', False)) - self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) - self.fsaacb.SetValue(init.get('fsaacb', False)) - self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) - self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) - self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) - self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) - self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) - self.lodbiascb.SetValue(init.get('lodbiascb', False)) - self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) - self.renderscalecb.SetValue(init.get('renderscalecb', False)) - self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) +from UI.PowerBinderCommand import PowerBinderCommand ####### Custom Bind -class CustomBindCmd(PowerBindCmd): +class CustomBindCmd(PowerBinderCommand): + Name = "Custom Bind" + # Menu = '' # This one gets treated specially, and should NOT define Menu + def BuildUI(self, dialog): sizer = wx.BoxSizer(wx.HORIZONTAL) self.customBindName = wx.TextCtrl(dialog, -1) @@ -976,825 +22,3 @@ def Serialize(self): def Deserialize(self,init): if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) - -####### Emote -class EmoteCmd(PowerBindCmd): - def BuildUI(self, dialog): - emoteSizer = wx.BoxSizer(wx.HORIZONTAL) - self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") - emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - self.emoteName = wx.Button(dialog, -1, "...") - self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) - emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) - - return emoteSizer - - def MakeBindString(self): - displayedEmoteName = self.emoteName.GetLabel() - actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] - - return actualEmotePayload - - def Serialize(self): - return {'emoteName': self.emoteName.GetLabel()} - - def Deserialize(self, init): - if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) - -####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): - def BuildUI(self, dialog): - mainSizer = wx.BoxSizer(wx.VERTICAL) - - lbSizer = wx.BoxSizer(wx.HORIZONTAL) - lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") - lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - profiles = Profile.GetAllProfileBindsDirs() - - self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) - lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) - - mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") - self.lbResetCB.SetValue(True) - - mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - return mainSizer - - def MakeBindString(self): - - # If the specified binds directory disappeared between runs, we'd crash, so handle that. - if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' - - config = wx.ConfigBase.Get() - if config.Exists('GameBindPath'): - bindpath = config.Read('GameBindPath') - else: - bindpath = config.Read('BindPath') - - reset = "" - if self.lbResetCB.GetValue(): - reset = "keybind_reset$$" - - resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' - return reset + 'bindloadfile ' + str(resetfilepath) - - def Serialize(self): - return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), - 'ResetKeybinds' : self.lbResetCB.GetValue(), - } - - def Deserialize(self, init): - if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) - self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) - -####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' - -####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' - -####### SG Mode -class SGModeCmd(PowerBindCmd): - def BuildUI(self, dialog): - sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) - sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") - self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") - - sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) - - return sgmodeSizer - - def MakeBindString(self): - if self.sgmodeOnRB.GetValue(): - return 'sgmodeset 1' - elif self.sgmodeOffRB.GetValue(): - return 'sgmodeset 0' - else: - return 'sgmode' - - def Serialize(self): - if self.sgmodeOnRB.GetValue(): - val = "On" - elif self.sgmodeOffRB.GetValue(): - val = "Off" - else: - val = "Toggle" - - return {"value" : val} - - def Deserialize(self, init): - val = init.get('value', '') - if val == "On": - self.sgmodeOnRB.SetValue(True) - elif val == "Off": - self.sgmodeOffRB.SetValue(True) - else: - self.sgmodeToggleRB.SetValue(True) - -####### Target Custom -class TargetCustomCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetCustomSizer = wx.GridBagSizer(5,5) - targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), - flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) - self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetCustomModeChoice.SetSelection(0) - targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) - self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) - self.targetCustomOptionalName.SetHint("Optional name to match") - targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) - self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") - targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) - self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") - targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) - self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") - targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) - self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") - targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) - self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") - targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) - self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") - targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) - self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") - targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) - self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") - targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) - - targetCustomSizer.AddGrowableCol(2) - - return targetCustomSizer - - def MakeBindString(self): - choice = self.targetCustomModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - targetCommand = "targetcustom" + mode.lower() - - enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" - friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" - defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" - alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" - mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" - notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" - base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" - notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" - - name = self.targetCustomOptionalName.GetValue() - - return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" - - def Serialize(self): - return { - 'mode' : self.targetCustomModeChoice.GetSelection(), - 'enemy' : self.targetCustomCBEnemies. IsChecked(), - 'friend' : self.targetCustomCBFriends. IsChecked(), - 'defeated' : self.targetCustomCBDefeated. IsChecked(), - 'alive' : self.targetCustomCBAlive. IsChecked(), - 'mypet' : self.targetCustomCBMyPets. IsChecked(), - 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), - 'base' : self.targetCustomCBBaseItems. IsChecked(), - 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), - 'name' : self.targetCustomOptionalName.GetValue(), - } - - def Deserialize(self, init): - if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) - if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) - if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) - if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) - if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) - if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) - if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) - if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) - if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) - if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - - -####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) - targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetEnemyModeChoice.SetSelection(0) - targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetEnemySizer - - def MakeBindString(self): - choice = self.targetEnemyModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetenemy" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetEnemyModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) - -####### Target Friend -class TargetFriendCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) - targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetFriendModeChoice.SetSelection(0) - targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetFriendSizer - - def MakeBindString(self): - choice = self.targetFriendModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetfriend" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetFriendModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) - -####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): - def BuildUI(self, dialog): - teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], - style=wx.ALIGN_CENTER_VERTICAL) - self.teamPetSelectNumber.SetSelection(0) - teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) - - return teamPetSelectSizer - - def MakeBindString(self): - teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' - targetNumber = self.teamPetSelectNumber.GetSelection()+1 - - return f"{teamOrPet}select {targetNumber}" - - def Serialize(self): - return { - 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', - 'targetNum': self.teamPetSelectNumber.GetSelection(), - } - - def Deserialize(self, init): - ToP = init.get('teamOrPet', '') - if ToP == 'pet': - self.teamPetSelectPetRB.SetValue(True) - else: - self.teamPetSelectTeamRB.SetValue(True) - if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) - -####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' - -####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) - for _, types in GameData.Inspirations.items(): - for _, info in types.items(): - for insp in info['tiers']: - name = re.sub(' ', '', str(insp)) - icon = GetIcon(f'Inspirations/{name}') - self.useInspByNameModeChoice.Append(insp, icon) - self.useInspByNameModeChoice.SetSelection(0) - useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) - - return useInspByNameSizer - - def MakeBindString(self): - choice = self.useInspByNameModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "inspexecname " + mode.lower() - - def GetAllInsps(self): - Insplist = [] - for _, info in GameData.Inspirations.items(): - for insp in info['tiers']: - Insplist.append(insp) - Insplist.append("---") - Insplist.pop(-1) # snip the terminal "---" - - return Insplist - - def Serialize(self): - return { 'insp' : self.useInspByNameModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) - -####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnRow.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) - self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnCol.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) - - return useInspRowColumnSizer - - def MakeBindString(self): - row = self.useInspRowColumnRow.GetSelection()+1 - col = self.useInspRowColumnCol.GetSelection()+1 - - return f"inspexectray {col} {row}" - - def Serialize(self): - return { - 'col' : self.useInspRowColumnCol.GetSelection(), - 'row' : self.useInspRowColumnRow.GetSelection(), - } - - def Deserialize(self, init): - if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) - if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) - -####### Use Power -class UsePowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - outerSizer = wx.BoxSizer(wx.HORIZONTAL) - - usePowerSizer = wx.GridBagSizer(5,5) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBToggle, (0,1)) - self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOn, (0,2)) - self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOff, (0,3)) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerName = PowerPicker(dialog) - usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) - usePowerSizer.AddGrowableCol(3) - - outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) - - return outerSizer - - def MakeBindString(self): - if self.usePowerRBToggle.GetValue(): - method = "powexecname" - elif self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') - return '' - - return f"{method} {self.usePowerName.GetLabel()}" - - def Serialize(self): - if self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - method = "powexecname" - return { - 'method': method, - 'pname' : self.usePowerName.GetLabel(), - 'picon' : self.usePowerName.IconFilename - } - - def Deserialize(self, init): - method = init.get('method', '') - if method == 'powexectoggleon': - self.usePowerRBOn.SetValue(True) - elif method == 'powexectoggleoff': - self.usePowerRBOff.SetValue(True) - else: - self.usePowerRBToggle.SetValue(True) - if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) - -####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): - def BuildUI(self, dialog): - usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTrayTray = wx.Choice(dialog, -1, - choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', - 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) - self.usePowerFromTrayTray.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) - self.usePowerFromTraySlot.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return usePowerFromTraySizer - - def MakeBindString(self): - choice = self.usePowerFromTrayTray - tray = choice.GetSelection() - - choice = self.usePowerFromTraySlot - slot = choice.GetSelection()+1 - - mode = "slot" - mode2 = '' - if tray > 3: - mode = "tray" - mode2 = f" {tray - 3}" - elif tray == 3: - mode = "alt2slot" - elif tray == 2: - mode = "altslot" - - return f"powexec{mode} {slot}{mode2}" - - def Serialize(self): - return { - 'tray' : self.usePowerFromTrayTray.GetSelection(), - 'slot' : self.usePowerFromTraySlot.GetSelection(), - } - - def Deserialize(self, init): - if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) - if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) - -####### Window Color -class WindowColorCmd(PowerBindCmd): - def BuildUI(self, dialog): - windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) - borderSizer = wx.BoxSizer(wx.VERTICAL) - self.ColorBorder.SetSizer(borderSizer) - self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) - borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) - - windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) - - RGBASizer = wx.FlexGridSizer(3, 4, 5) - - RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) - self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) - self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - windowColorSizer.Add(RGBASizer) - - self.UpdateFromSlider() - - return windowColorSizer - - def MakeBindString(self): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - return f"windowcolor {Rval} {Gval} {Bval} {Aval}" - - def Serialize(self): - return { - 'Rval' : self.RSlider.GetValue(), - 'Gval' : self.GSlider.GetValue(), - 'Bval' : self.BSlider.GetValue(), - 'Aval' : self.ASlider.GetValue(), - } - - def Deserialize(self, init): - self.RSlider.SetValue(init['Rval']) - self.GSlider.SetValue(init['Gval']) - self.BSlider.SetValue(init['Bval']) - self.ASlider.SetValue(init['Aval']) - self.UpdateFromSlider() - - def UpdateFromSlider(self, _ = None): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RReadout.SetValue(Rval) - self.GReadout.SetValue(Gval) - self.BReadout.SetValue(Bval) - self.AReadout.SetValue(Aval) - self.ColorBorder.Refresh() - - def UpdateFromText(self, _ = None): - Rval = self.RReadout.GetValue() - Gval = self.GReadout.GetValue() - Bval = self.BReadout.GetValue() - Aval = self.AReadout.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RSlider.SetValue(Rval) - self.GSlider.SetValue(Gval) - self.BSlider.SetValue(Bval) - self.ASlider.SetValue(Aval) - self.ColorBorder.Refresh() - -####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) - self.CommandChoice.SetSelection(0) - sizer.Add(self.CommandChoice, 0, wx.ALL, 5) - - self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), - value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) - sizer.Add(self.FilePath, 0, wx.ALL, 5) - - return sizer - - def MakeBindString(self): - command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] - return f'{command} "{self.FilePath.GetValue()}"' - - def Serialize(self): - return { - 'command' : self.CommandChoice.GetSelection(), - 'filename' : self.FilePath.GetValue(), - } - - def Deserialize(self, init): - self.CommandChoice.SetSelection(init.get('command', 0)) - self.FilePath.SetValue(init.get('filename', '')) - -####### Window Toggle -class WindowToggleCmd(PowerBindCmd): - def BuildUI(self, dialog): - self.WindowNames = { - 'Actions' : 'actions', - 'Auction House' : 'ah', - 'Badge' : 'badge', - 'Channel Search' : 'chansearch', - 'Chat' : 'chat', - 'Custom Chat 1' : 'chat1', - 'Custom Chat 2' : 'chat2', - 'Custom Chat 3' : 'chat3', - 'Custom Chat 4' : 'chat4', - 'Clues' : 'clue', - 'Combat Numbers' : 'combatnumbers', - 'Contacts' : 'contact', - 'Contact Finder' : 'contactfinder', - 'Costumes' : 'costume', - 'Email' : 'email', - 'Enhancements' : 'enhancements', - 'Friends' : 'friend', - 'Group' : 'group', - 'Help' : 'helpwindow', - 'Incarnate' : 'incarnate', - 'Inspirations' : 'insp', - 'League' : 'league', - 'LFG' : 'lfg', - 'Map' : 'map', - 'Mission' : 'mission', - 'Nav / Compass' : 'nav', - 'Options' : 'options', - 'Pets' : 'pet', - 'Petition' : 'petition', - 'Power Tray' : 'powers', - 'Power List' : 'powerlist', - 'Quit' : 'quit', - 'Recipes' : 'recipe', - 'Salvage' : 'salvage', - 'Search' : 'search', - 'Supergroup' : 'sg', - 'Target' : 'target', - 'Team' : 'team', - 'Tray' : 'tray', - 'Tray1' : 'tray1', - 'Tray2' : 'tray2', - 'Tray3' : 'tray3', - 'Tray4' : 'tray4', - 'Tray5' : 'tray5', - 'Tray6' : 'tray6', - 'Tray7' : 'tray7', - 'Tray8' : 'tray8', - 'Vault' : 'vault', - } - - self.ShortToggleCommands = { - 'Auction House' : 'ah', - 'Chat' : 'chat', - 'Help' : 'helpwindow', - 'Map' : 'map', - 'Nav / Compass' : 'nav', - 'Power Tray' : 'powers', - 'Target' : 'target', - 'Tray' : 'tray', - } - - windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) - windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) - self.windowToggleTray.SetSelection(0) - windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.windowShowRB = wx.RadioButton(dialog, -1, "Show") - self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") - - windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) - - return windowToggleSizer - - def MakeBindString(self): - choice = self.windowToggleTray - index = choice.GetSelection() - windowdesc = choice.GetString(index) - windowname = self.WindowNames[windowdesc] - - if self.windowShowRB.GetValue(): - return 'show ' + windowname - elif self.windowHideRB.GetValue(): - return 'windowhide ' + windowname - else: - if shortcmd := self.ShortToggleCommands.get(windowdesc, None): - return shortcmd - else: - return 'toggle ' + windowname - - - def Serialize(self): - choice = self.windowToggleTray - if self.windowShowRB.GetValue(): - action = "Show" - elif self.windowHideRB.GetValue(): - action = "Hide" - else: - action = "Toggle" - return { - 'window': choice.GetString(choice.GetSelection()), - 'action': action, - } - - def Deserialize(self, init): - choice = self.windowToggleTray - if window := init.get('window', ''): - if isinstance(window, int): - choice.SetSelection(window) - else: - choice.SetSelection(choice.FindString(window)) - - if choice.GetSelection() == wx.NOT_FOUND: - choice.SetSelection(0) - - action = init.get('action', '') - if action == "Show": - self.windowShowRB.SetValue(True) - elif action == "Hide": - self.windowHideRB.SetValue(True) - else: - self.windowToggleRB.SetValue(True) - - -# Must always add to this list when adding a new command class above -menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], - # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, - # but I'm leaving it here to remind myself that we do that. - } - -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/EmoteCmd.py b/UI/PowerBinderCommand/EmoteCmd.py index 4c02ab7..b205643 100644 --- a/UI/PowerBinderCommand/EmoteCmd.py +++ b/UI/PowerBinderCommand/EmoteCmd.py @@ -1,984 +1,12 @@ import wx -import re -import UI import UI.EmotePicker -from UI.ControlGroup import ControlGroup -from UI.PowerPicker import PowerPicker -from Help import HelpButton -import wx.adv -from wx.adv import BitmapComboBox, EditableListBox -from pathlib import PureWindowsPath -import GameData -import Profile -from Icon import GetIcon - -class PowerBinderDialog(wx.Dialog): - def __init__(self, parent, button, init = {}): - wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) - - self.Page = parent.Page - self.EditDialog = PowerBinderEditDialog(self) - self.Button = button - self.AddStepMenu = self.makeAddStepMenu() - - sizer = wx.BoxSizer(wx.VERTICAL); - self.mainSizer = sizer - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) - AddStepButton = wx.Button(self, -1, 'Add Step') - AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) - AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) - choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) - choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) - sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) - - rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) - - self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) - self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) - self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) - rearrangeCtrl.Add(self.RearrangeList, 1) - - rearrangeButtons = wx.BoxSizer(wx.VERTICAL) - self.DelButton = wx.Button(self, -1, "Delete") - self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) - self.EditButton = wx.Button(self, -1, "Edit") - self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) - self.EditButton.Disable() - upButton = wx.Button(self, -1, "\u25B2") - upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) - downButton = wx.Button(self, -1, "\u25BC") - downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) - rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) - rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) - - sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.BindStringDisplay = wx.TextCtrl(self, -1) - self.BindStringDisplay.Disable() - choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, - wx.ALIGN_CENTER_VERTICAL) - choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) - - sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) - - sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) - - # need to dig around and get the OK button since we show this dialog modelessly now. - okButton = self.FindWindow(self.GetAffirmativeId()) - okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) - - # Wrap everything in a vbox to add some padding - vbox = wx.BoxSizer(wx.VERTICAL); - vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); - - self.SetSizerAndFit(vbox); - self.Layout() - self.Fit() - self.SetFocus() - - # if we are loading from profile, ie, have "init", build the list from it - if init: self.LoadFromData(init) - - def LoadFromData(self, init): - for item in init: - for type, data in item.items(): - commandClass = commandClasses.get(type, None) - if not commandClass: - commandClass = deprecatedCommandClasses.get(type, None) - if not commandClass: - wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") - continue - newCommand = commandClass(self.EditDialog, data) - index = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.SetClientData(index, newCommand) - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) - self.EditDialog.mainSizer.Hide(newCommand.UI) - self.UpdateBindStringDisplay() - - def SaveToData(self): - data = [] - index = 0 - for _ in self.RearrangeList.GetItems(): - # check whether we have an object already attached to this choice - cmdObject = self.RearrangeList.GetClientData(index) - commandClassName = commandRevClasses[type(cmdObject)] - data.append({commandClassName: cmdObject.Serialize()}) - index = index + 1 - return data - - def OnAddStepButton(self, evt): - button = evt.EventObject - if not self.AddStepMenu: - self.AddStepMenu = self.makeAddStepMenu() - button.PopupMenu(self.AddStepMenu) - - - def OnOKButton(self, _): - if self.Button.tgtTxtCtrl: - bindString = self.MakeBindString() - if bindString != self.Button.tgtTxtCtrl.GetValue(): - self.Button.tgtTxtCtrl.SetValue(bindString) - wx.App.Get().Main.Profile.SetModified() - self.Close() - - def OnRearrangeDelete(self, _): - current = self.RearrangeList.GetSelection() - if current == wx.NOT_FOUND: return - - self.RearrangeList.Delete(current) - self.UpdateBindStringDisplay() - - def OnRearrangeUp(self, _): - self.RearrangeList.MoveCurrentUp() - self.UpdateBindStringDisplay() - - def OnRearrangeDown(self, _): - self.RearrangeList.MoveCurrentDown() - self.UpdateBindStringDisplay() - - def OnRearrangeEdit(self, _): - index = self.RearrangeList.GetSelection() - - # check whether we have an object already attached to this choice - cmdObject = None - try: - cmdObject = self.RearrangeList.GetClientData(index) - except Exception: - pass - - if cmdObject: - self.ShowEditDialogFor(cmdObject) - self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) - else: - print("cmdObject was None") - self.UpdateBindStringDisplay() - - # OnAddStepMenu creates a new step and adds it to the rearrangelist - def OnAddStepMenu(self, evt): - menuitem = self.AddStepMenu.FindItemById(evt.GetId()) - chosenName = menuitem.GetItemLabel() - - # make a new command object, attached to the parent dialog - newCommandClass = commandClasses[chosenName] - newCommand = newCommandClass(self.EditDialog) - - # show the edit dialog if this command needs it - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) - if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): - self.EditDialog.mainSizer.Remove(newCommand.UI) - return - - newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.Select(newBindIndex) - self.RearrangeList.SetClientData(newBindIndex, newCommand) - - self.OnListSelect() - self.UpdateBindStringDisplay() - - def OnListSelect(self, _ = None): - selected = self.RearrangeList.GetSelection() - - if selected != wx.NOT_FOUND: - selCommand = self.RearrangeList.GetClientData(selected) - if selCommand.UI: - self.EditButton.Enable() - else: - self.EditButton.Disable() - - def UpdateBindStringDisplay(self): - self.BindStringDisplay.SetValue(self.MakeBindString()) - self.BindStringDisplay.SetToolTip(self.MakeBindString()) - - def MakeBindString(self): - cmdBindStrings = [] - for index in range(self.RearrangeList.GetCount()): - c = self.RearrangeList.GetClientData(index) - if c: cmdBindStrings.append(c.MakeBindString()) - - bindstring = ('$$'.join(cmdBindStrings)) - return bindstring - - def ShowEditDialogFor(self, command): - if not command.UI: return - - self.EditDialog.mainSizer.Show(command.UI) - - self.EditDialog.Layout() - self.EditDialog.Fit() - - self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') - returnval = self.EditDialog.ShowModal() - - self.EditDialog.mainSizer.Hide(command.UI) - - return returnval - - def makeAddStepMenu(self): - - stepMenu = wx.Menu() - - for subname in menuStructure: - submenu = wx.Menu() - stepMenu.AppendSubMenu(submenu, subname) - for classname in menuStructure[subname]: - submenu.Append(wx.ID_ANY, classname) - - stepMenu.Append(wx.ID_ANY, 'Custom Bind') - - return stepMenu - -class PowerBinderButton(wx.BitmapButton): - - def __init__(self, parent, tgtTxtCtrl, init = {}): - wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) - self.Init = init - self.Dialog = None - self.DialogParent = parent - - self.tgtTxtCtrl = tgtTxtCtrl - self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) - self.SetToolTip("Launch PowerBinder") - - def PowerBinderEventHandler(self, _): - self.PowerBinderDialog().Show() - - def LoadFromData(self, data): - self.PowerBinderDialog().LoadFromData(data) - - def SaveToData(self): - return self.PowerBinderDialog().SaveToData() - - def PowerBinderDialog(self): - if not self.Dialog: - self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) - return self.Dialog - - -class PowerBinderEditDialog(wx.Dialog): - def __init__(self, parent): - wx.Dialog.__init__(self, parent, -1, "Edit Step", - style = wx.DEFAULT_DIALOG_STYLE) - - outerSizer = wx.BoxSizer(wx.VERTICAL) - - self.mainSizer = wx.BoxSizer(wx.VERTICAL) - self.mainSizer.SetMinSize([500, 150]) - - self.Page = parent.Page - - self.mainSizer.Add( - self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), - 0, wx.EXPAND|wx.ALL, 10) - - outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) - - self.SetSizerAndFit(outerSizer) - self.Layout() - self.Fit() - -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" - - -####### Away From Keyboard -class AFKCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.Groups = {} - self.AttributeTable = { - 'Base' : { - 'Current Hit Points' : 'NT H', - 'Max Hit Points' : 'X H', - 'Current Endurance' : 'T E', - 'Max Endurance' : 'X EN', - 'Regeneration Rate' : 'N RAT', - 'Recovery Rate' : 'Y RA', - 'Endurance Consumption' : 'SU', - 'ToHit Bonus' : 'T B', - 'Accuracy Bonus' : 'CC', - 'Last Hit Chance' : 'T C', - 'Damage Bonus' : 'DA', - 'Healing Bonus' : 'NG B', - 'Recharge Time Bonus' : 'ME B', - 'Endurance Discount' : 'CE DIS', - 'Stealth Radius (PvP)' : 'PVP', - 'Stealth Radius (PvE)' : 'PVE', - 'Perception Radius' : 'RC', - 'Range Bonus' : 'GE B', - 'Threat Level' : 'AT L', - 'Experience to Next Level' : 'XT', - 'Experience Debt' : 'XP', - 'Influence / Infamy' : 'INF', - 'Inherent' : 'NH', - }, - 'Movement Speed' : { - 'Flying Speed' : 'FL', - 'Jumping Speed' : 'PI', - 'Max Jump Height' : 'X J', - 'Run Speed' : 'RU', - }, - 'Damage Resistance' : { - 'Smashing Resistance' : 'G R', - 'Lethal Resistance' : 'L R', - 'Fire Resistance' : 'RE R', - 'Cold Resistance' : 'COLD R', - 'Energy Resistance' : 'DamageType[4]', - 'Negative Energy Resistance' : 'GY R', - 'Psyonic Resistance' : 'NIC R', - 'Toxic Resistance' : 'XIC R', - }, - 'Defense' : { - 'Base Defense' : 'BAS', - 'Ranged Defense' : 'ED', - 'Melee Defense' : 'MEL', - 'AoE Defense' : '2', - 'Smashing Defense' : '3', - 'Lethal Defense' : '4', - 'Fire Defense' : '5', - 'Cold Defense' : '6', - 'Energy Defense' : '7', - 'Negative Energy Defense' : '8', - 'Psionic Defense' : '9', - 'Toxic Defense' : '1', - }, - 'Debuff Resistance' : { - 'Regeneration Resistance' : 'ON R', - 'Recovery Resistance' : 'RY R', - 'To Hit Resistance' : 'IT R', - 'Defense Resistance' : 'NSE RES', - }, - 'Status Effect Protection' : { - 'Hold Protection' : 'D P', - 'Immobilize Protection' : 'LIZE P', - 'Stun Protection' : 'N P', - 'Sleep Protection' : 'P P', - 'Knockback Protection' : 'K P', - 'Confuse Protection' : 'SE P', - 'Terrorize Protection' : 'ZE P', - 'Repel Protection' : 'EL P', - 'Teleport Protection' : 'T P', - }, - 'Status Effect Resistance' : { - 'Hold Resistance' : 'D R', - 'Immobilize Resistance' : 'LIZE R', - 'Stun Resistance' : 'N R', - 'Sleep Resistance' : 'P R', - 'Knockback Resistance' : 'K R', - 'Confuse Resistance' : 'SE R', - 'Terrorize Resistance' : 'ZE R', - 'Placate Resistance' : 'TE R', - 'Taunt Resistance' : 'NT R', - }, - 'Miscellaneous' : { - 'Level Shift' : 'L S', - }, - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.AttributeMenu = wx.Menu() - for group, controls in self.AttributeTable.items(): - submenu = wx.Menu() - self.AttributeMenu.AppendSubMenu(submenu, group) - for cb in controls: - submenu.Append(wx.ID_ANY, cb) - - self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) - - self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) - groupSizer.Add(self.editbox) - - newButton = self.editbox.GetNewButton() - newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) - - return groupSizer - - def MakeBindString(self): - map = {} - bindstrings = [] - for _, controls in self.AttributeTable.items(): - for cb, data in controls.items(): - map[cb] = data - - for string in self.editbox.GetStrings(): - if string: - bindstrings.append(f'monitorattribute {map[string]}') - - return '$$'.join(bindstrings) - - def Serialize(self): - return { - 'attributes' : self.editbox.GetStrings() - } - - def Deserialize(self, init): - self.editbox.SetStrings(init.get('attributes', [])) - - def OnNewButton(self, evt): - evt.GetEventObject().PopupMenu(self.AttributeMenu) - - def OnMenuItem(self, evt): - menuitem = evt.EventObject.FindItemById(evt.GetId()) - existingstrings = self.editbox.GetStrings() - existingstrings.append(menuitem.GetItemLabel()) - self.editbox.SetStrings(existingstrings) - -####### Auto Power -class AutoPowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) - autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.autoPowerName = PowerPicker(dialog) - autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) - - return autoPowerSizer - - def MakeBindString(self): - return f"powexecauto {self.autoPowerName.GetLabel()}" - - def Serialize(self): - return { - 'pname' : self.autoPowerName.GetLabel(), - 'picon' : self.autoPowerName.IconFilename - } - - def Deserialize(self, init): - if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.buffDisplayMap = { - 'Status Window' : { - 'Hide Auto' : 1, - 'Hide Toggles' : 2, - 'No Blinking' : 4, - 'No Stacking' : 8, - 'Numeric Stacking' : 16, - 'Hide Buff Numbers' : 32, - 'Stop Sending Buffs' : 64, - }, - 'Group Window' : { - 'Hide Auto' : 256, - 'Hide Toggles' : 512, - 'No Blinking' : 1024, - 'No Stacking' : 2048, - 'Numeric Stacking' : 4096, - 'Hide Buff Numbers' : 8192, - 'Stop Sending Buffs' : 16384, - }, - 'Pet Window' : { - 'Hide Auto' : 65536, - 'Hide Toggles' : 131072, - 'No Blinking' : 262144, - 'No Stacking' : 524288, - 'Numeric Stacking' : 1048576, - 'Hide Buff Numbers' : 2097152, - 'Stop Sending Buffs' : 4194304, - }, - } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - for group, controls in self.buffDisplayMap.items(): - self.Groups[group] = ControlGroup(dialog, self.Page, label = group) - groupid = self.Groups[group].GetStaticBox().GetId() - for cb, data in controls.items(): - self.Groups[group].AddControl( - ctlType = 'checkbox', - ctlName = f"{groupid}_{group}_{cb}", - label = cb, - data = data, - ) - - groupSizer.Add(self.Groups[group]) - - return groupSizer - - def CalculateValue(self): - page = wx.App.Get().Main.Profile.CustomBinds - - total = 0 - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] - if checkbox.IsChecked(): - total = total + checkbox.Data - return total - - def MakeBindString(self): - return f"optionset buffsettings {self.CalculateValue()}" - - def Serialize(self): - return { 'value' : self.CalculateValue() } - - def Deserialize(self, init): - value = init.get('value', 0) - - value = value or 0 # in case we had for some reason 'None' stashed in the init values - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] - checkbox.SetValue( checkbox.Data & value ) - -####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - chatCommandSizer = wx.GridBagSizer(5, 5) - self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") - chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) - # row 1 - self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) - self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) - self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) - # row 2 - self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) - self.chatCommandDuration.SetRange(1, 20) - self.chatCommandDuration.SetValue(7) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandDuration, (2,1)) - self.chatCommandChatSize = wx.Choice(dialog, -1, - choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) - self.chatCommandChatSize.SetSelection(5) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) - self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) - self.chatCommandChannel.SetSelection(0) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChannel, (2,5)) - # row 3 - self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") - chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) - self.chatCommandMessage = wx.TextCtrl(dialog, -1) - self.chatCommandMessage.SetHint('Chat Command Text') - chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) - - return chatCommandSizer - - def MakeBindString(self): - duration = self.chatCommandDuration.GetValue() - - choice = self.chatCommandChatSize - index = choice.GetSelection() - size = choice.GetString(index) - - duration = f"" if duration != 7 else "" - size = f"" if size != "1" else "" - - bdcolor = fgcolor = bgcolor = '' - if self.chatCommandUseColorsCB.IsChecked(): - bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - - bdcolor = f"" - fgcolor = f"" - bgcolor = f"" - - beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' - text = self.chatCommandMessage.GetValue() - - choice = self.chatCommandChannel - index = choice.GetSelection() - channel = choice.GetString(index) - - return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" - - def Serialize(self): - return { - 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), - 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), - 'channel' : self.chatCommandChannel .GetSelection(), - 'size' : self.chatCommandChatSize.GetSelection(), - 'duration' : self.chatCommandDuration.GetValue(), - 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'text' : self.chatCommandMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) - if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) - if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) - if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) - if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) - if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) - if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) - if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) - if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - - -####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): - def BuildUI(self, dialog): - chatCommandGlobalSizer = wx.GridBagSizer(5,5) - - self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") - chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) - - self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalChannel.SetHint("Channel") - chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) - - self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') - chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) - - chatCommandGlobalSizer.AddGrowableCol(1) - - return chatCommandGlobalSizer - - def MakeBindString(self): - useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() - channel = self.chatCommandGlobalChannel.GetValue() - message = self.chatCommandGlobalMessage.GetValue() - - preface = "beginchat /" if useBeginchat else "" - - return f'{preface}send "{channel}" {message}' - - def Serialize(self): - return { - 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), - 'channel' : self.chatCommandGlobalChannel.GetValue(), - 'message' : self.chatCommandGlobalMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) - if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) - if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) - -#######Costume Change -class CostumeChangeCmd(PowerBindCmd): - def BuildUI(self, dialog): - costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeCostume = wx.Choice(dialog, -1, - choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) - self.costumeChangeCostume.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeEmote = wx.Choice(dialog, -1, - choices = GameData.Emotes['costumechange']) - self.costumeChangeEmote.Insert("- None -", 0) - self.costumeChangeEmote.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return costumeChangeSizer - - def MakeBindString(self): - costumeNumber = self.costumeChangeCostume.GetSelection() - costumeEmote = self.costumeChangeEmote.GetSelection() - - if costumeEmote: # None, or 0 == "- None -" - ccCmd = 'cce' - emoteName = self.costumeChangeEmote.GetString(costumeEmote) - emoteName = " CC" + emoteName.replace(" ","") - else: - ccCmd = 'cc' - emoteName = '' - - return f"{ccCmd} {costumeNumber}{emoteName}" - - def Serialize(self): - return{ - 'costumeNumber': self.costumeChangeCostume.GetSelection(), - 'costumeEmote' : self.costumeChangeEmote.GetSelection(), - } - - def Deserialize(self, init): - if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) - if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) - -####### Movement Command -class MovementCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - self.plusbutton.SetValue(True) - - self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.commandchoice = wx.Choice(dialog, choices = [ - "forward", "left", "right", "backward", "up", "down", - "turnleft", "turnright", "first", "autorun", "clicktomove", - ],) - sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) - self.commandchoice.SetSelection(0) - - self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - pre = post = '' - if self.plusbutton.GetValue() : pre = "+" - elif self.plusplusbutton.GetValue() : pre = "++" - elif self.minusbutton.GetValue() : pre = "-" - elif self.zerobutton.GetValue() : post = " 0" - elif self.onebutton.GetValue() : post = " 1" - - command = self.commandchoice.GetString(self.commandchoice.GetSelection()) - - return f"{pre}{command}{post}" - - def Serialize(self): - mod = '' - if self.plusbutton.GetValue() : mod = "plus" - elif self.plusplusbutton.GetValue() : mod = "plusplus" - elif self.minusbutton.GetValue() : mod = "minus" - elif self.zerobutton.GetValue() : mod = "zero" - elif self.onebutton.GetValue() : mod = "one" - - return { - 'mod' : mod, - 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), - } - - def Deserialize(self, init): - mod = init.get('mod', 'plus') - - if mod == 'plus' : self.plusbutton.SetValue(True) - elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) - elif mod == 'minus' : self.minusbutton.SetValue(True) - elif mod == 'zero' : self.zerobutton.SetValue(True) - elif mod == 'one' : self.onebutton.SetValue(True) - - self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) - -####### Graphics Command -class GraphicsCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.FlexGridSizer(2) - - self.visscalecb = wx.CheckBox(dialog, label = "visscale") - sizer.Add(self.visscalecb) - self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) - sizer.Add(self.visscalesc) - - self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") - sizer.Add(self.dofweightcb) - self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) - sizer.Add(self.dofweightsc) - - self.fsaacb = wx.CheckBox(dialog, label = "fsaa") - sizer.Add(self.fsaacb) - self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) - self.fsaach.SetSelection(0) - sizer.Add(self.fsaach) - - self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") - sizer.Add(self.bloomscalecb) - self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) - self.bloomscalech.SetSelection(0) - sizer.Add(self.bloomscalech) - - self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") - sizer.Add(self.bloomweightcb) - self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) - sizer.Add(self.bloomweightsc) - - self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") - sizer.Add(self.lodbiascb) - self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) - sizer.Add(self.lodbiassc) - - self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") - sizer.Add(self.renderscalecb) - self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) - sizer.Add(self.renderscalesc) - - return sizer - - def MakeBindString(self): - # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. - bindstrings = [] - if self.visscalecb.IsChecked(): - bindstrings.append("visscale " + str(self.visscalesc.GetValue())) - if self.dofweightcb.IsChecked(): - bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) - if self.fsaacb.IsChecked(): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bindstrings.append("fsaa " + fsaavalue) - if self.bloomscalecb.IsChecked(): - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - bindstrings.append("bloomscale " + bloomscalevalue) - if self.bloomweightcb.IsChecked(): - bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) - if self.lodbiascb.IsChecked(): - bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) - if self.renderscalecb.IsChecked(): - bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) - - return '$$'.join(bindstrings) - - def Serialize(self): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - return { - 'visscalecb' : self.visscalecb.IsChecked(), - 'visscalesc' : self.visscalesc.GetValue(), - 'dofweightcb' : self.dofweightcb.IsChecked(), - 'dofweightsc' : self.dofweightsc.GetValue(), - 'fsaacb' : self.fsaacb.IsChecked(), - 'fsaach' : fsaavalue, - 'bloomscalecb' : self.bloomscalecb.IsChecked(), - 'bloomscalech' : bloomscalevalue, - 'bloomweightcb' : self.bloomweightcb.IsChecked(), - 'bloomweightsc' : self.bloomweightsc.GetValue(), - 'lodbiascb' : self.lodbiascb.IsChecked(), - 'lodbiassc' : self.lodbiassc.GetValue(), - 'renderscalecb' : self.renderscalecb.IsChecked(), - 'renderscalesc' : self.renderscalesc.GetValue(), - } - - def Deserialize(self, init): - self.visscalecb.SetValue(init.get('visscalecb', False)) - self.visscalesc.SetValue(init.get('visscalesc', 1.0)) - self.dofweightcb.SetValue(init.get('dofweightcb', False)) - self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) - self.fsaacb.SetValue(init.get('fsaacb', False)) - self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) - self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) - self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) - self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) - self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) - self.lodbiascb.SetValue(init.get('lodbiascb', False)) - self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) - self.renderscalecb.SetValue(init.get('renderscalecb', False)) - self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) - -####### Custom Bind -class CustomBindCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.customBindName = wx.TextCtrl(dialog, -1) - self.customBindName.SetHint('Custom Bind Text') - sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - return self.customBindName.GetValue() - - def Serialize(self): - return { 'customBindName': self.customBindName.GetValue() } - - def Deserialize(self,init): - if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) +from UI.PowerBinderCommand import PowerBinderCommand ####### Emote -class EmoteCmd(PowerBindCmd): +class EmoteCmd(PowerBinderCommand): + Name = "Emote" + Menu = "Social" + def BuildUI(self, dialog): emoteSizer = wx.BoxSizer(wx.HORIZONTAL) self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") @@ -1001,800 +29,3 @@ def Serialize(self): def Deserialize(self, init): if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) - -####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): - def BuildUI(self, dialog): - mainSizer = wx.BoxSizer(wx.VERTICAL) - - lbSizer = wx.BoxSizer(wx.HORIZONTAL) - lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") - lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - profiles = Profile.GetAllProfileBindsDirs() - - self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) - lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) - - mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") - self.lbResetCB.SetValue(True) - - mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - return mainSizer - - def MakeBindString(self): - - # If the specified binds directory disappeared between runs, we'd crash, so handle that. - if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' - - config = wx.ConfigBase.Get() - if config.Exists('GameBindPath'): - bindpath = config.Read('GameBindPath') - else: - bindpath = config.Read('BindPath') - - reset = "" - if self.lbResetCB.GetValue(): - reset = "keybind_reset$$" - - resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' - return reset + 'bindloadfile ' + str(resetfilepath) - - def Serialize(self): - return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), - 'ResetKeybinds' : self.lbResetCB.GetValue(), - } - - def Deserialize(self, init): - if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) - self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) - -####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' - -####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' - -####### SG Mode -class SGModeCmd(PowerBindCmd): - def BuildUI(self, dialog): - sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) - sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") - self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") - - sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) - - return sgmodeSizer - - def MakeBindString(self): - if self.sgmodeOnRB.GetValue(): - return 'sgmodeset 1' - elif self.sgmodeOffRB.GetValue(): - return 'sgmodeset 0' - else: - return 'sgmode' - - def Serialize(self): - if self.sgmodeOnRB.GetValue(): - val = "On" - elif self.sgmodeOffRB.GetValue(): - val = "Off" - else: - val = "Toggle" - - return {"value" : val} - - def Deserialize(self, init): - val = init.get('value', '') - if val == "On": - self.sgmodeOnRB.SetValue(True) - elif val == "Off": - self.sgmodeOffRB.SetValue(True) - else: - self.sgmodeToggleRB.SetValue(True) - -####### Target Custom -class TargetCustomCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetCustomSizer = wx.GridBagSizer(5,5) - targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), - flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) - self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetCustomModeChoice.SetSelection(0) - targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) - self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) - self.targetCustomOptionalName.SetHint("Optional name to match") - targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) - self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") - targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) - self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") - targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) - self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") - targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) - self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") - targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) - self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") - targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) - self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") - targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) - self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") - targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) - self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") - targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) - - targetCustomSizer.AddGrowableCol(2) - - return targetCustomSizer - - def MakeBindString(self): - choice = self.targetCustomModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - targetCommand = "targetcustom" + mode.lower() - - enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" - friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" - defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" - alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" - mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" - notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" - base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" - notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" - - name = self.targetCustomOptionalName.GetValue() - - return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" - - def Serialize(self): - return { - 'mode' : self.targetCustomModeChoice.GetSelection(), - 'enemy' : self.targetCustomCBEnemies. IsChecked(), - 'friend' : self.targetCustomCBFriends. IsChecked(), - 'defeated' : self.targetCustomCBDefeated. IsChecked(), - 'alive' : self.targetCustomCBAlive. IsChecked(), - 'mypet' : self.targetCustomCBMyPets. IsChecked(), - 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), - 'base' : self.targetCustomCBBaseItems. IsChecked(), - 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), - 'name' : self.targetCustomOptionalName.GetValue(), - } - - def Deserialize(self, init): - if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) - if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) - if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) - if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) - if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) - if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) - if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) - if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) - if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) - if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - - -####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) - targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetEnemyModeChoice.SetSelection(0) - targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetEnemySizer - - def MakeBindString(self): - choice = self.targetEnemyModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetenemy" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetEnemyModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) - -####### Target Friend -class TargetFriendCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) - targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetFriendModeChoice.SetSelection(0) - targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetFriendSizer - - def MakeBindString(self): - choice = self.targetFriendModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetfriend" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetFriendModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) - -####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): - def BuildUI(self, dialog): - teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], - style=wx.ALIGN_CENTER_VERTICAL) - self.teamPetSelectNumber.SetSelection(0) - teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) - - return teamPetSelectSizer - - def MakeBindString(self): - teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' - targetNumber = self.teamPetSelectNumber.GetSelection()+1 - - return f"{teamOrPet}select {targetNumber}" - - def Serialize(self): - return { - 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', - 'targetNum': self.teamPetSelectNumber.GetSelection(), - } - - def Deserialize(self, init): - ToP = init.get('teamOrPet', '') - if ToP == 'pet': - self.teamPetSelectPetRB.SetValue(True) - else: - self.teamPetSelectTeamRB.SetValue(True) - if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) - -####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' - -####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) - for _, types in GameData.Inspirations.items(): - for _, info in types.items(): - for insp in info['tiers']: - name = re.sub(' ', '', str(insp)) - icon = GetIcon(f'Inspirations/{name}') - self.useInspByNameModeChoice.Append(insp, icon) - self.useInspByNameModeChoice.SetSelection(0) - useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) - - return useInspByNameSizer - - def MakeBindString(self): - choice = self.useInspByNameModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "inspexecname " + mode.lower() - - def GetAllInsps(self): - Insplist = [] - for _, info in GameData.Inspirations.items(): - for insp in info['tiers']: - Insplist.append(insp) - Insplist.append("---") - Insplist.pop(-1) # snip the terminal "---" - - return Insplist - - def Serialize(self): - return { 'insp' : self.useInspByNameModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) - -####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnRow.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) - self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnCol.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) - - return useInspRowColumnSizer - - def MakeBindString(self): - row = self.useInspRowColumnRow.GetSelection()+1 - col = self.useInspRowColumnCol.GetSelection()+1 - - return f"inspexectray {col} {row}" - - def Serialize(self): - return { - 'col' : self.useInspRowColumnCol.GetSelection(), - 'row' : self.useInspRowColumnRow.GetSelection(), - } - - def Deserialize(self, init): - if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) - if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) - -####### Use Power -class UsePowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - outerSizer = wx.BoxSizer(wx.HORIZONTAL) - - usePowerSizer = wx.GridBagSizer(5,5) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBToggle, (0,1)) - self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOn, (0,2)) - self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOff, (0,3)) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerName = PowerPicker(dialog) - usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) - usePowerSizer.AddGrowableCol(3) - - outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) - - return outerSizer - - def MakeBindString(self): - if self.usePowerRBToggle.GetValue(): - method = "powexecname" - elif self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') - return '' - - return f"{method} {self.usePowerName.GetLabel()}" - - def Serialize(self): - if self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - method = "powexecname" - return { - 'method': method, - 'pname' : self.usePowerName.GetLabel(), - 'picon' : self.usePowerName.IconFilename - } - - def Deserialize(self, init): - method = init.get('method', '') - if method == 'powexectoggleon': - self.usePowerRBOn.SetValue(True) - elif method == 'powexectoggleoff': - self.usePowerRBOff.SetValue(True) - else: - self.usePowerRBToggle.SetValue(True) - if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) - -####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): - def BuildUI(self, dialog): - usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTrayTray = wx.Choice(dialog, -1, - choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', - 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) - self.usePowerFromTrayTray.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) - self.usePowerFromTraySlot.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return usePowerFromTraySizer - - def MakeBindString(self): - choice = self.usePowerFromTrayTray - tray = choice.GetSelection() - - choice = self.usePowerFromTraySlot - slot = choice.GetSelection()+1 - - mode = "slot" - mode2 = '' - if tray > 3: - mode = "tray" - mode2 = f" {tray - 3}" - elif tray == 3: - mode = "alt2slot" - elif tray == 2: - mode = "altslot" - - return f"powexec{mode} {slot}{mode2}" - - def Serialize(self): - return { - 'tray' : self.usePowerFromTrayTray.GetSelection(), - 'slot' : self.usePowerFromTraySlot.GetSelection(), - } - - def Deserialize(self, init): - if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) - if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) - -####### Window Color -class WindowColorCmd(PowerBindCmd): - def BuildUI(self, dialog): - windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) - borderSizer = wx.BoxSizer(wx.VERTICAL) - self.ColorBorder.SetSizer(borderSizer) - self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) - borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) - - windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) - - RGBASizer = wx.FlexGridSizer(3, 4, 5) - - RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) - self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) - self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - windowColorSizer.Add(RGBASizer) - - self.UpdateFromSlider() - - return windowColorSizer - - def MakeBindString(self): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - return f"windowcolor {Rval} {Gval} {Bval} {Aval}" - - def Serialize(self): - return { - 'Rval' : self.RSlider.GetValue(), - 'Gval' : self.GSlider.GetValue(), - 'Bval' : self.BSlider.GetValue(), - 'Aval' : self.ASlider.GetValue(), - } - - def Deserialize(self, init): - self.RSlider.SetValue(init['Rval']) - self.GSlider.SetValue(init['Gval']) - self.BSlider.SetValue(init['Bval']) - self.ASlider.SetValue(init['Aval']) - self.UpdateFromSlider() - - def UpdateFromSlider(self, _ = None): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RReadout.SetValue(Rval) - self.GReadout.SetValue(Gval) - self.BReadout.SetValue(Bval) - self.AReadout.SetValue(Aval) - self.ColorBorder.Refresh() - - def UpdateFromText(self, _ = None): - Rval = self.RReadout.GetValue() - Gval = self.GReadout.GetValue() - Bval = self.BReadout.GetValue() - Aval = self.AReadout.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RSlider.SetValue(Rval) - self.GSlider.SetValue(Gval) - self.BSlider.SetValue(Bval) - self.ASlider.SetValue(Aval) - self.ColorBorder.Refresh() - -####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) - self.CommandChoice.SetSelection(0) - sizer.Add(self.CommandChoice, 0, wx.ALL, 5) - - self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), - value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) - sizer.Add(self.FilePath, 0, wx.ALL, 5) - - return sizer - - def MakeBindString(self): - command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] - return f'{command} "{self.FilePath.GetValue()}"' - - def Serialize(self): - return { - 'command' : self.CommandChoice.GetSelection(), - 'filename' : self.FilePath.GetValue(), - } - - def Deserialize(self, init): - self.CommandChoice.SetSelection(init.get('command', 0)) - self.FilePath.SetValue(init.get('filename', '')) - -####### Window Toggle -class WindowToggleCmd(PowerBindCmd): - def BuildUI(self, dialog): - self.WindowNames = { - 'Actions' : 'actions', - 'Auction House' : 'ah', - 'Badge' : 'badge', - 'Channel Search' : 'chansearch', - 'Chat' : 'chat', - 'Custom Chat 1' : 'chat1', - 'Custom Chat 2' : 'chat2', - 'Custom Chat 3' : 'chat3', - 'Custom Chat 4' : 'chat4', - 'Clues' : 'clue', - 'Combat Numbers' : 'combatnumbers', - 'Contacts' : 'contact', - 'Contact Finder' : 'contactfinder', - 'Costumes' : 'costume', - 'Email' : 'email', - 'Enhancements' : 'enhancements', - 'Friends' : 'friend', - 'Group' : 'group', - 'Help' : 'helpwindow', - 'Incarnate' : 'incarnate', - 'Inspirations' : 'insp', - 'League' : 'league', - 'LFG' : 'lfg', - 'Map' : 'map', - 'Mission' : 'mission', - 'Nav / Compass' : 'nav', - 'Options' : 'options', - 'Pets' : 'pet', - 'Petition' : 'petition', - 'Power Tray' : 'powers', - 'Power List' : 'powerlist', - 'Quit' : 'quit', - 'Recipes' : 'recipe', - 'Salvage' : 'salvage', - 'Search' : 'search', - 'Supergroup' : 'sg', - 'Target' : 'target', - 'Team' : 'team', - 'Tray' : 'tray', - 'Tray1' : 'tray1', - 'Tray2' : 'tray2', - 'Tray3' : 'tray3', - 'Tray4' : 'tray4', - 'Tray5' : 'tray5', - 'Tray6' : 'tray6', - 'Tray7' : 'tray7', - 'Tray8' : 'tray8', - 'Vault' : 'vault', - } - - self.ShortToggleCommands = { - 'Auction House' : 'ah', - 'Chat' : 'chat', - 'Help' : 'helpwindow', - 'Map' : 'map', - 'Nav / Compass' : 'nav', - 'Power Tray' : 'powers', - 'Target' : 'target', - 'Tray' : 'tray', - } - - windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) - windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) - self.windowToggleTray.SetSelection(0) - windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.windowShowRB = wx.RadioButton(dialog, -1, "Show") - self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") - - windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) - - return windowToggleSizer - - def MakeBindString(self): - choice = self.windowToggleTray - index = choice.GetSelection() - windowdesc = choice.GetString(index) - windowname = self.WindowNames[windowdesc] - - if self.windowShowRB.GetValue(): - return 'show ' + windowname - elif self.windowHideRB.GetValue(): - return 'windowhide ' + windowname - else: - if shortcmd := self.ShortToggleCommands.get(windowdesc, None): - return shortcmd - else: - return 'toggle ' + windowname - - - def Serialize(self): - choice = self.windowToggleTray - if self.windowShowRB.GetValue(): - action = "Show" - elif self.windowHideRB.GetValue(): - action = "Hide" - else: - action = "Toggle" - return { - 'window': choice.GetString(choice.GetSelection()), - 'action': action, - } - - def Deserialize(self, init): - choice = self.windowToggleTray - if window := init.get('window', ''): - if isinstance(window, int): - choice.SetSelection(window) - else: - choice.SetSelection(choice.FindString(window)) - - if choice.GetSelection() == wx.NOT_FOUND: - choice.SetSelection(0) - - action = init.get('action', '') - if action == "Show": - self.windowShowRB.SetValue(True) - elif action == "Hide": - self.windowHideRB.SetValue(True) - else: - self.windowToggleRB.SetValue(True) - - -# Must always add to this list when adding a new command class above -menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], - # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, - # but I'm leaving it here to remind myself that we do that. - } - -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/GraphicsCmd.py b/UI/PowerBinderCommand/GraphicsCmd.py index 4c02ab7..8168e31 100644 --- a/UI/PowerBinderCommand/GraphicsCmd.py +++ b/UI/PowerBinderCommand/GraphicsCmd.py @@ -1,851 +1,11 @@ import wx -import re -import UI -import UI.EmotePicker -from UI.ControlGroup import ControlGroup -from UI.PowerPicker import PowerPicker -from Help import HelpButton -import wx.adv -from wx.adv import BitmapComboBox, EditableListBox -from pathlib import PureWindowsPath -import GameData -import Profile -from Icon import GetIcon - -class PowerBinderDialog(wx.Dialog): - def __init__(self, parent, button, init = {}): - wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) - - self.Page = parent.Page - self.EditDialog = PowerBinderEditDialog(self) - self.Button = button - self.AddStepMenu = self.makeAddStepMenu() - - sizer = wx.BoxSizer(wx.VERTICAL); - self.mainSizer = sizer - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) - AddStepButton = wx.Button(self, -1, 'Add Step') - AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) - AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) - choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) - choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) - sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) - - rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) - - self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) - self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) - self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) - rearrangeCtrl.Add(self.RearrangeList, 1) - - rearrangeButtons = wx.BoxSizer(wx.VERTICAL) - self.DelButton = wx.Button(self, -1, "Delete") - self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) - self.EditButton = wx.Button(self, -1, "Edit") - self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) - self.EditButton.Disable() - upButton = wx.Button(self, -1, "\u25B2") - upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) - downButton = wx.Button(self, -1, "\u25BC") - downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) - rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) - rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) - - sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.BindStringDisplay = wx.TextCtrl(self, -1) - self.BindStringDisplay.Disable() - choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, - wx.ALIGN_CENTER_VERTICAL) - choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) - - sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) - - sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) - - # need to dig around and get the OK button since we show this dialog modelessly now. - okButton = self.FindWindow(self.GetAffirmativeId()) - okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) - - # Wrap everything in a vbox to add some padding - vbox = wx.BoxSizer(wx.VERTICAL); - vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); - - self.SetSizerAndFit(vbox); - self.Layout() - self.Fit() - self.SetFocus() - - # if we are loading from profile, ie, have "init", build the list from it - if init: self.LoadFromData(init) - - def LoadFromData(self, init): - for item in init: - for type, data in item.items(): - commandClass = commandClasses.get(type, None) - if not commandClass: - commandClass = deprecatedCommandClasses.get(type, None) - if not commandClass: - wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") - continue - newCommand = commandClass(self.EditDialog, data) - index = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.SetClientData(index, newCommand) - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) - self.EditDialog.mainSizer.Hide(newCommand.UI) - self.UpdateBindStringDisplay() - - def SaveToData(self): - data = [] - index = 0 - for _ in self.RearrangeList.GetItems(): - # check whether we have an object already attached to this choice - cmdObject = self.RearrangeList.GetClientData(index) - commandClassName = commandRevClasses[type(cmdObject)] - data.append({commandClassName: cmdObject.Serialize()}) - index = index + 1 - return data - - def OnAddStepButton(self, evt): - button = evt.EventObject - if not self.AddStepMenu: - self.AddStepMenu = self.makeAddStepMenu() - button.PopupMenu(self.AddStepMenu) - - - def OnOKButton(self, _): - if self.Button.tgtTxtCtrl: - bindString = self.MakeBindString() - if bindString != self.Button.tgtTxtCtrl.GetValue(): - self.Button.tgtTxtCtrl.SetValue(bindString) - wx.App.Get().Main.Profile.SetModified() - self.Close() - - def OnRearrangeDelete(self, _): - current = self.RearrangeList.GetSelection() - if current == wx.NOT_FOUND: return - - self.RearrangeList.Delete(current) - self.UpdateBindStringDisplay() - - def OnRearrangeUp(self, _): - self.RearrangeList.MoveCurrentUp() - self.UpdateBindStringDisplay() - - def OnRearrangeDown(self, _): - self.RearrangeList.MoveCurrentDown() - self.UpdateBindStringDisplay() - - def OnRearrangeEdit(self, _): - index = self.RearrangeList.GetSelection() - - # check whether we have an object already attached to this choice - cmdObject = None - try: - cmdObject = self.RearrangeList.GetClientData(index) - except Exception: - pass - - if cmdObject: - self.ShowEditDialogFor(cmdObject) - self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) - else: - print("cmdObject was None") - self.UpdateBindStringDisplay() - - # OnAddStepMenu creates a new step and adds it to the rearrangelist - def OnAddStepMenu(self, evt): - menuitem = self.AddStepMenu.FindItemById(evt.GetId()) - chosenName = menuitem.GetItemLabel() - - # make a new command object, attached to the parent dialog - newCommandClass = commandClasses[chosenName] - newCommand = newCommandClass(self.EditDialog) - - # show the edit dialog if this command needs it - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) - if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): - self.EditDialog.mainSizer.Remove(newCommand.UI) - return - - newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.Select(newBindIndex) - self.RearrangeList.SetClientData(newBindIndex, newCommand) - - self.OnListSelect() - self.UpdateBindStringDisplay() - - def OnListSelect(self, _ = None): - selected = self.RearrangeList.GetSelection() - - if selected != wx.NOT_FOUND: - selCommand = self.RearrangeList.GetClientData(selected) - if selCommand.UI: - self.EditButton.Enable() - else: - self.EditButton.Disable() - - def UpdateBindStringDisplay(self): - self.BindStringDisplay.SetValue(self.MakeBindString()) - self.BindStringDisplay.SetToolTip(self.MakeBindString()) - - def MakeBindString(self): - cmdBindStrings = [] - for index in range(self.RearrangeList.GetCount()): - c = self.RearrangeList.GetClientData(index) - if c: cmdBindStrings.append(c.MakeBindString()) - - bindstring = ('$$'.join(cmdBindStrings)) - return bindstring - - def ShowEditDialogFor(self, command): - if not command.UI: return - - self.EditDialog.mainSizer.Show(command.UI) - - self.EditDialog.Layout() - self.EditDialog.Fit() - - self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') - returnval = self.EditDialog.ShowModal() - - self.EditDialog.mainSizer.Hide(command.UI) - - return returnval - - def makeAddStepMenu(self): - - stepMenu = wx.Menu() - - for subname in menuStructure: - submenu = wx.Menu() - stepMenu.AppendSubMenu(submenu, subname) - for classname in menuStructure[subname]: - submenu.Append(wx.ID_ANY, classname) - - stepMenu.Append(wx.ID_ANY, 'Custom Bind') - - return stepMenu - -class PowerBinderButton(wx.BitmapButton): - - def __init__(self, parent, tgtTxtCtrl, init = {}): - wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) - self.Init = init - self.Dialog = None - self.DialogParent = parent - - self.tgtTxtCtrl = tgtTxtCtrl - self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) - self.SetToolTip("Launch PowerBinder") - - def PowerBinderEventHandler(self, _): - self.PowerBinderDialog().Show() - - def LoadFromData(self, data): - self.PowerBinderDialog().LoadFromData(data) - - def SaveToData(self): - return self.PowerBinderDialog().SaveToData() - - def PowerBinderDialog(self): - if not self.Dialog: - self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) - return self.Dialog - - -class PowerBinderEditDialog(wx.Dialog): - def __init__(self, parent): - wx.Dialog.__init__(self, parent, -1, "Edit Step", - style = wx.DEFAULT_DIALOG_STYLE) - - outerSizer = wx.BoxSizer(wx.VERTICAL) - - self.mainSizer = wx.BoxSizer(wx.VERTICAL) - self.mainSizer.SetMinSize([500, 150]) - - self.Page = parent.Page - - self.mainSizer.Add( - self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), - 0, wx.EXPAND|wx.ALL, 10) - - outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) - - self.SetSizerAndFit(outerSizer) - self.Layout() - self.Fit() - -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" - - -####### Away From Keyboard -class AFKCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.Groups = {} - self.AttributeTable = { - 'Base' : { - 'Current Hit Points' : 'NT H', - 'Max Hit Points' : 'X H', - 'Current Endurance' : 'T E', - 'Max Endurance' : 'X EN', - 'Regeneration Rate' : 'N RAT', - 'Recovery Rate' : 'Y RA', - 'Endurance Consumption' : 'SU', - 'ToHit Bonus' : 'T B', - 'Accuracy Bonus' : 'CC', - 'Last Hit Chance' : 'T C', - 'Damage Bonus' : 'DA', - 'Healing Bonus' : 'NG B', - 'Recharge Time Bonus' : 'ME B', - 'Endurance Discount' : 'CE DIS', - 'Stealth Radius (PvP)' : 'PVP', - 'Stealth Radius (PvE)' : 'PVE', - 'Perception Radius' : 'RC', - 'Range Bonus' : 'GE B', - 'Threat Level' : 'AT L', - 'Experience to Next Level' : 'XT', - 'Experience Debt' : 'XP', - 'Influence / Infamy' : 'INF', - 'Inherent' : 'NH', - }, - 'Movement Speed' : { - 'Flying Speed' : 'FL', - 'Jumping Speed' : 'PI', - 'Max Jump Height' : 'X J', - 'Run Speed' : 'RU', - }, - 'Damage Resistance' : { - 'Smashing Resistance' : 'G R', - 'Lethal Resistance' : 'L R', - 'Fire Resistance' : 'RE R', - 'Cold Resistance' : 'COLD R', - 'Energy Resistance' : 'DamageType[4]', - 'Negative Energy Resistance' : 'GY R', - 'Psyonic Resistance' : 'NIC R', - 'Toxic Resistance' : 'XIC R', - }, - 'Defense' : { - 'Base Defense' : 'BAS', - 'Ranged Defense' : 'ED', - 'Melee Defense' : 'MEL', - 'AoE Defense' : '2', - 'Smashing Defense' : '3', - 'Lethal Defense' : '4', - 'Fire Defense' : '5', - 'Cold Defense' : '6', - 'Energy Defense' : '7', - 'Negative Energy Defense' : '8', - 'Psionic Defense' : '9', - 'Toxic Defense' : '1', - }, - 'Debuff Resistance' : { - 'Regeneration Resistance' : 'ON R', - 'Recovery Resistance' : 'RY R', - 'To Hit Resistance' : 'IT R', - 'Defense Resistance' : 'NSE RES', - }, - 'Status Effect Protection' : { - 'Hold Protection' : 'D P', - 'Immobilize Protection' : 'LIZE P', - 'Stun Protection' : 'N P', - 'Sleep Protection' : 'P P', - 'Knockback Protection' : 'K P', - 'Confuse Protection' : 'SE P', - 'Terrorize Protection' : 'ZE P', - 'Repel Protection' : 'EL P', - 'Teleport Protection' : 'T P', - }, - 'Status Effect Resistance' : { - 'Hold Resistance' : 'D R', - 'Immobilize Resistance' : 'LIZE R', - 'Stun Resistance' : 'N R', - 'Sleep Resistance' : 'P R', - 'Knockback Resistance' : 'K R', - 'Confuse Resistance' : 'SE R', - 'Terrorize Resistance' : 'ZE R', - 'Placate Resistance' : 'TE R', - 'Taunt Resistance' : 'NT R', - }, - 'Miscellaneous' : { - 'Level Shift' : 'L S', - }, - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.AttributeMenu = wx.Menu() - for group, controls in self.AttributeTable.items(): - submenu = wx.Menu() - self.AttributeMenu.AppendSubMenu(submenu, group) - for cb in controls: - submenu.Append(wx.ID_ANY, cb) - - self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) - - self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) - groupSizer.Add(self.editbox) - - newButton = self.editbox.GetNewButton() - newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) - - return groupSizer - - def MakeBindString(self): - map = {} - bindstrings = [] - for _, controls in self.AttributeTable.items(): - for cb, data in controls.items(): - map[cb] = data - - for string in self.editbox.GetStrings(): - if string: - bindstrings.append(f'monitorattribute {map[string]}') - - return '$$'.join(bindstrings) - - def Serialize(self): - return { - 'attributes' : self.editbox.GetStrings() - } - - def Deserialize(self, init): - self.editbox.SetStrings(init.get('attributes', [])) - - def OnNewButton(self, evt): - evt.GetEventObject().PopupMenu(self.AttributeMenu) - - def OnMenuItem(self, evt): - menuitem = evt.EventObject.FindItemById(evt.GetId()) - existingstrings = self.editbox.GetStrings() - existingstrings.append(menuitem.GetItemLabel()) - self.editbox.SetStrings(existingstrings) - -####### Auto Power -class AutoPowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) - autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.autoPowerName = PowerPicker(dialog) - autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) - - return autoPowerSizer - - def MakeBindString(self): - return f"powexecauto {self.autoPowerName.GetLabel()}" - - def Serialize(self): - return { - 'pname' : self.autoPowerName.GetLabel(), - 'picon' : self.autoPowerName.IconFilename - } - - def Deserialize(self, init): - if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.buffDisplayMap = { - 'Status Window' : { - 'Hide Auto' : 1, - 'Hide Toggles' : 2, - 'No Blinking' : 4, - 'No Stacking' : 8, - 'Numeric Stacking' : 16, - 'Hide Buff Numbers' : 32, - 'Stop Sending Buffs' : 64, - }, - 'Group Window' : { - 'Hide Auto' : 256, - 'Hide Toggles' : 512, - 'No Blinking' : 1024, - 'No Stacking' : 2048, - 'Numeric Stacking' : 4096, - 'Hide Buff Numbers' : 8192, - 'Stop Sending Buffs' : 16384, - }, - 'Pet Window' : { - 'Hide Auto' : 65536, - 'Hide Toggles' : 131072, - 'No Blinking' : 262144, - 'No Stacking' : 524288, - 'Numeric Stacking' : 1048576, - 'Hide Buff Numbers' : 2097152, - 'Stop Sending Buffs' : 4194304, - }, - } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - for group, controls in self.buffDisplayMap.items(): - self.Groups[group] = ControlGroup(dialog, self.Page, label = group) - groupid = self.Groups[group].GetStaticBox().GetId() - for cb, data in controls.items(): - self.Groups[group].AddControl( - ctlType = 'checkbox', - ctlName = f"{groupid}_{group}_{cb}", - label = cb, - data = data, - ) - - groupSizer.Add(self.Groups[group]) - - return groupSizer - - def CalculateValue(self): - page = wx.App.Get().Main.Profile.CustomBinds - - total = 0 - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] - if checkbox.IsChecked(): - total = total + checkbox.Data - return total - - def MakeBindString(self): - return f"optionset buffsettings {self.CalculateValue()}" - - def Serialize(self): - return { 'value' : self.CalculateValue() } - - def Deserialize(self, init): - value = init.get('value', 0) - - value = value or 0 # in case we had for some reason 'None' stashed in the init values - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] - checkbox.SetValue( checkbox.Data & value ) - -####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - chatCommandSizer = wx.GridBagSizer(5, 5) - self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") - chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) - # row 1 - self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) - self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) - self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) - # row 2 - self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) - self.chatCommandDuration.SetRange(1, 20) - self.chatCommandDuration.SetValue(7) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandDuration, (2,1)) - self.chatCommandChatSize = wx.Choice(dialog, -1, - choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) - self.chatCommandChatSize.SetSelection(5) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) - self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) - self.chatCommandChannel.SetSelection(0) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChannel, (2,5)) - # row 3 - self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") - chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) - self.chatCommandMessage = wx.TextCtrl(dialog, -1) - self.chatCommandMessage.SetHint('Chat Command Text') - chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) - - return chatCommandSizer - - def MakeBindString(self): - duration = self.chatCommandDuration.GetValue() - - choice = self.chatCommandChatSize - index = choice.GetSelection() - size = choice.GetString(index) - - duration = f"" if duration != 7 else "" - size = f"" if size != "1" else "" - - bdcolor = fgcolor = bgcolor = '' - if self.chatCommandUseColorsCB.IsChecked(): - bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - - bdcolor = f"" - fgcolor = f"" - bgcolor = f"" - - beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' - text = self.chatCommandMessage.GetValue() - - choice = self.chatCommandChannel - index = choice.GetSelection() - channel = choice.GetString(index) - - return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" - - def Serialize(self): - return { - 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), - 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), - 'channel' : self.chatCommandChannel .GetSelection(), - 'size' : self.chatCommandChatSize.GetSelection(), - 'duration' : self.chatCommandDuration.GetValue(), - 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'text' : self.chatCommandMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) - if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) - if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) - if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) - if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) - if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) - if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) - if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) - if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - - -####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): - def BuildUI(self, dialog): - chatCommandGlobalSizer = wx.GridBagSizer(5,5) - - self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") - chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) - - self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalChannel.SetHint("Channel") - chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) - - self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') - chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) - - chatCommandGlobalSizer.AddGrowableCol(1) - - return chatCommandGlobalSizer - - def MakeBindString(self): - useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() - channel = self.chatCommandGlobalChannel.GetValue() - message = self.chatCommandGlobalMessage.GetValue() - - preface = "beginchat /" if useBeginchat else "" - - return f'{preface}send "{channel}" {message}' - - def Serialize(self): - return { - 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), - 'channel' : self.chatCommandGlobalChannel.GetValue(), - 'message' : self.chatCommandGlobalMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) - if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) - if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) - -#######Costume Change -class CostumeChangeCmd(PowerBindCmd): - def BuildUI(self, dialog): - costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeCostume = wx.Choice(dialog, -1, - choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) - self.costumeChangeCostume.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeEmote = wx.Choice(dialog, -1, - choices = GameData.Emotes['costumechange']) - self.costumeChangeEmote.Insert("- None -", 0) - self.costumeChangeEmote.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return costumeChangeSizer - - def MakeBindString(self): - costumeNumber = self.costumeChangeCostume.GetSelection() - costumeEmote = self.costumeChangeEmote.GetSelection() - - if costumeEmote: # None, or 0 == "- None -" - ccCmd = 'cce' - emoteName = self.costumeChangeEmote.GetString(costumeEmote) - emoteName = " CC" + emoteName.replace(" ","") - else: - ccCmd = 'cc' - emoteName = '' - - return f"{ccCmd} {costumeNumber}{emoteName}" - - def Serialize(self): - return{ - 'costumeNumber': self.costumeChangeCostume.GetSelection(), - 'costumeEmote' : self.costumeChangeEmote.GetSelection(), - } - - def Deserialize(self, init): - if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) - if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) - -####### Movement Command -class MovementCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - self.plusbutton.SetValue(True) - - self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.commandchoice = wx.Choice(dialog, choices = [ - "forward", "left", "right", "backward", "up", "down", - "turnleft", "turnright", "first", "autorun", "clicktomove", - ],) - sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) - self.commandchoice.SetSelection(0) - - self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - pre = post = '' - if self.plusbutton.GetValue() : pre = "+" - elif self.plusplusbutton.GetValue() : pre = "++" - elif self.minusbutton.GetValue() : pre = "-" - elif self.zerobutton.GetValue() : post = " 0" - elif self.onebutton.GetValue() : post = " 1" - - command = self.commandchoice.GetString(self.commandchoice.GetSelection()) - - return f"{pre}{command}{post}" - - def Serialize(self): - mod = '' - if self.plusbutton.GetValue() : mod = "plus" - elif self.plusplusbutton.GetValue() : mod = "plusplus" - elif self.minusbutton.GetValue() : mod = "minus" - elif self.zerobutton.GetValue() : mod = "zero" - elif self.onebutton.GetValue() : mod = "one" - - return { - 'mod' : mod, - 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), - } - - def Deserialize(self, init): - mod = init.get('mod', 'plus') - - if mod == 'plus' : self.plusbutton.SetValue(True) - elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) - elif mod == 'minus' : self.minusbutton.SetValue(True) - elif mod == 'zero' : self.zerobutton.SetValue(True) - elif mod == 'one' : self.onebutton.SetValue(True) - - self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) +from UI.PowerBinderCommand import PowerBinderCommand ####### Graphics Command -class GraphicsCmd(PowerBindCmd): +class GraphicsCmd(PowerBinderCommand): + Name = "Graphics Settings" + Menu = "Graphics / UI" + def BuildUI(self, dialog): sizer = wx.FlexGridSizer(2) @@ -957,844 +117,3 @@ def Deserialize(self, init): self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) self.renderscalecb.SetValue(init.get('renderscalecb', False)) self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) - -####### Custom Bind -class CustomBindCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.customBindName = wx.TextCtrl(dialog, -1) - self.customBindName.SetHint('Custom Bind Text') - sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - return self.customBindName.GetValue() - - def Serialize(self): - return { 'customBindName': self.customBindName.GetValue() } - - def Deserialize(self,init): - if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) - -####### Emote -class EmoteCmd(PowerBindCmd): - def BuildUI(self, dialog): - emoteSizer = wx.BoxSizer(wx.HORIZONTAL) - self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") - emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - self.emoteName = wx.Button(dialog, -1, "...") - self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) - emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) - - return emoteSizer - - def MakeBindString(self): - displayedEmoteName = self.emoteName.GetLabel() - actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] - - return actualEmotePayload - - def Serialize(self): - return {'emoteName': self.emoteName.GetLabel()} - - def Deserialize(self, init): - if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) - -####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): - def BuildUI(self, dialog): - mainSizer = wx.BoxSizer(wx.VERTICAL) - - lbSizer = wx.BoxSizer(wx.HORIZONTAL) - lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") - lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - profiles = Profile.GetAllProfileBindsDirs() - - self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) - lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) - - mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") - self.lbResetCB.SetValue(True) - - mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - return mainSizer - - def MakeBindString(self): - - # If the specified binds directory disappeared between runs, we'd crash, so handle that. - if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' - - config = wx.ConfigBase.Get() - if config.Exists('GameBindPath'): - bindpath = config.Read('GameBindPath') - else: - bindpath = config.Read('BindPath') - - reset = "" - if self.lbResetCB.GetValue(): - reset = "keybind_reset$$" - - resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' - return reset + 'bindloadfile ' + str(resetfilepath) - - def Serialize(self): - return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), - 'ResetKeybinds' : self.lbResetCB.GetValue(), - } - - def Deserialize(self, init): - if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) - self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) - -####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' - -####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' - -####### SG Mode -class SGModeCmd(PowerBindCmd): - def BuildUI(self, dialog): - sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) - sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") - self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") - - sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) - - return sgmodeSizer - - def MakeBindString(self): - if self.sgmodeOnRB.GetValue(): - return 'sgmodeset 1' - elif self.sgmodeOffRB.GetValue(): - return 'sgmodeset 0' - else: - return 'sgmode' - - def Serialize(self): - if self.sgmodeOnRB.GetValue(): - val = "On" - elif self.sgmodeOffRB.GetValue(): - val = "Off" - else: - val = "Toggle" - - return {"value" : val} - - def Deserialize(self, init): - val = init.get('value', '') - if val == "On": - self.sgmodeOnRB.SetValue(True) - elif val == "Off": - self.sgmodeOffRB.SetValue(True) - else: - self.sgmodeToggleRB.SetValue(True) - -####### Target Custom -class TargetCustomCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetCustomSizer = wx.GridBagSizer(5,5) - targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), - flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) - self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetCustomModeChoice.SetSelection(0) - targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) - self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) - self.targetCustomOptionalName.SetHint("Optional name to match") - targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) - self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") - targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) - self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") - targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) - self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") - targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) - self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") - targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) - self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") - targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) - self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") - targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) - self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") - targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) - self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") - targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) - - targetCustomSizer.AddGrowableCol(2) - - return targetCustomSizer - - def MakeBindString(self): - choice = self.targetCustomModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - targetCommand = "targetcustom" + mode.lower() - - enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" - friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" - defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" - alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" - mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" - notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" - base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" - notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" - - name = self.targetCustomOptionalName.GetValue() - - return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" - - def Serialize(self): - return { - 'mode' : self.targetCustomModeChoice.GetSelection(), - 'enemy' : self.targetCustomCBEnemies. IsChecked(), - 'friend' : self.targetCustomCBFriends. IsChecked(), - 'defeated' : self.targetCustomCBDefeated. IsChecked(), - 'alive' : self.targetCustomCBAlive. IsChecked(), - 'mypet' : self.targetCustomCBMyPets. IsChecked(), - 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), - 'base' : self.targetCustomCBBaseItems. IsChecked(), - 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), - 'name' : self.targetCustomOptionalName.GetValue(), - } - - def Deserialize(self, init): - if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) - if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) - if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) - if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) - if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) - if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) - if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) - if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) - if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) - if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - - -####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) - targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetEnemyModeChoice.SetSelection(0) - targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetEnemySizer - - def MakeBindString(self): - choice = self.targetEnemyModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetenemy" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetEnemyModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) - -####### Target Friend -class TargetFriendCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) - targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetFriendModeChoice.SetSelection(0) - targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetFriendSizer - - def MakeBindString(self): - choice = self.targetFriendModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetfriend" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetFriendModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) - -####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): - def BuildUI(self, dialog): - teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], - style=wx.ALIGN_CENTER_VERTICAL) - self.teamPetSelectNumber.SetSelection(0) - teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) - - return teamPetSelectSizer - - def MakeBindString(self): - teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' - targetNumber = self.teamPetSelectNumber.GetSelection()+1 - - return f"{teamOrPet}select {targetNumber}" - - def Serialize(self): - return { - 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', - 'targetNum': self.teamPetSelectNumber.GetSelection(), - } - - def Deserialize(self, init): - ToP = init.get('teamOrPet', '') - if ToP == 'pet': - self.teamPetSelectPetRB.SetValue(True) - else: - self.teamPetSelectTeamRB.SetValue(True) - if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) - -####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' - -####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) - for _, types in GameData.Inspirations.items(): - for _, info in types.items(): - for insp in info['tiers']: - name = re.sub(' ', '', str(insp)) - icon = GetIcon(f'Inspirations/{name}') - self.useInspByNameModeChoice.Append(insp, icon) - self.useInspByNameModeChoice.SetSelection(0) - useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) - - return useInspByNameSizer - - def MakeBindString(self): - choice = self.useInspByNameModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "inspexecname " + mode.lower() - - def GetAllInsps(self): - Insplist = [] - for _, info in GameData.Inspirations.items(): - for insp in info['tiers']: - Insplist.append(insp) - Insplist.append("---") - Insplist.pop(-1) # snip the terminal "---" - - return Insplist - - def Serialize(self): - return { 'insp' : self.useInspByNameModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) - -####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnRow.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) - self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnCol.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) - - return useInspRowColumnSizer - - def MakeBindString(self): - row = self.useInspRowColumnRow.GetSelection()+1 - col = self.useInspRowColumnCol.GetSelection()+1 - - return f"inspexectray {col} {row}" - - def Serialize(self): - return { - 'col' : self.useInspRowColumnCol.GetSelection(), - 'row' : self.useInspRowColumnRow.GetSelection(), - } - - def Deserialize(self, init): - if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) - if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) - -####### Use Power -class UsePowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - outerSizer = wx.BoxSizer(wx.HORIZONTAL) - - usePowerSizer = wx.GridBagSizer(5,5) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBToggle, (0,1)) - self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOn, (0,2)) - self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOff, (0,3)) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerName = PowerPicker(dialog) - usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) - usePowerSizer.AddGrowableCol(3) - - outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) - - return outerSizer - - def MakeBindString(self): - if self.usePowerRBToggle.GetValue(): - method = "powexecname" - elif self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') - return '' - - return f"{method} {self.usePowerName.GetLabel()}" - - def Serialize(self): - if self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - method = "powexecname" - return { - 'method': method, - 'pname' : self.usePowerName.GetLabel(), - 'picon' : self.usePowerName.IconFilename - } - - def Deserialize(self, init): - method = init.get('method', '') - if method == 'powexectoggleon': - self.usePowerRBOn.SetValue(True) - elif method == 'powexectoggleoff': - self.usePowerRBOff.SetValue(True) - else: - self.usePowerRBToggle.SetValue(True) - if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) - -####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): - def BuildUI(self, dialog): - usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTrayTray = wx.Choice(dialog, -1, - choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', - 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) - self.usePowerFromTrayTray.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) - self.usePowerFromTraySlot.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return usePowerFromTraySizer - - def MakeBindString(self): - choice = self.usePowerFromTrayTray - tray = choice.GetSelection() - - choice = self.usePowerFromTraySlot - slot = choice.GetSelection()+1 - - mode = "slot" - mode2 = '' - if tray > 3: - mode = "tray" - mode2 = f" {tray - 3}" - elif tray == 3: - mode = "alt2slot" - elif tray == 2: - mode = "altslot" - - return f"powexec{mode} {slot}{mode2}" - - def Serialize(self): - return { - 'tray' : self.usePowerFromTrayTray.GetSelection(), - 'slot' : self.usePowerFromTraySlot.GetSelection(), - } - - def Deserialize(self, init): - if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) - if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) - -####### Window Color -class WindowColorCmd(PowerBindCmd): - def BuildUI(self, dialog): - windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) - borderSizer = wx.BoxSizer(wx.VERTICAL) - self.ColorBorder.SetSizer(borderSizer) - self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) - borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) - - windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) - - RGBASizer = wx.FlexGridSizer(3, 4, 5) - - RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) - self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) - self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - windowColorSizer.Add(RGBASizer) - - self.UpdateFromSlider() - - return windowColorSizer - - def MakeBindString(self): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - return f"windowcolor {Rval} {Gval} {Bval} {Aval}" - - def Serialize(self): - return { - 'Rval' : self.RSlider.GetValue(), - 'Gval' : self.GSlider.GetValue(), - 'Bval' : self.BSlider.GetValue(), - 'Aval' : self.ASlider.GetValue(), - } - - def Deserialize(self, init): - self.RSlider.SetValue(init['Rval']) - self.GSlider.SetValue(init['Gval']) - self.BSlider.SetValue(init['Bval']) - self.ASlider.SetValue(init['Aval']) - self.UpdateFromSlider() - - def UpdateFromSlider(self, _ = None): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RReadout.SetValue(Rval) - self.GReadout.SetValue(Gval) - self.BReadout.SetValue(Bval) - self.AReadout.SetValue(Aval) - self.ColorBorder.Refresh() - - def UpdateFromText(self, _ = None): - Rval = self.RReadout.GetValue() - Gval = self.GReadout.GetValue() - Bval = self.BReadout.GetValue() - Aval = self.AReadout.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RSlider.SetValue(Rval) - self.GSlider.SetValue(Gval) - self.BSlider.SetValue(Bval) - self.ASlider.SetValue(Aval) - self.ColorBorder.Refresh() - -####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) - self.CommandChoice.SetSelection(0) - sizer.Add(self.CommandChoice, 0, wx.ALL, 5) - - self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), - value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) - sizer.Add(self.FilePath, 0, wx.ALL, 5) - - return sizer - - def MakeBindString(self): - command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] - return f'{command} "{self.FilePath.GetValue()}"' - - def Serialize(self): - return { - 'command' : self.CommandChoice.GetSelection(), - 'filename' : self.FilePath.GetValue(), - } - - def Deserialize(self, init): - self.CommandChoice.SetSelection(init.get('command', 0)) - self.FilePath.SetValue(init.get('filename', '')) - -####### Window Toggle -class WindowToggleCmd(PowerBindCmd): - def BuildUI(self, dialog): - self.WindowNames = { - 'Actions' : 'actions', - 'Auction House' : 'ah', - 'Badge' : 'badge', - 'Channel Search' : 'chansearch', - 'Chat' : 'chat', - 'Custom Chat 1' : 'chat1', - 'Custom Chat 2' : 'chat2', - 'Custom Chat 3' : 'chat3', - 'Custom Chat 4' : 'chat4', - 'Clues' : 'clue', - 'Combat Numbers' : 'combatnumbers', - 'Contacts' : 'contact', - 'Contact Finder' : 'contactfinder', - 'Costumes' : 'costume', - 'Email' : 'email', - 'Enhancements' : 'enhancements', - 'Friends' : 'friend', - 'Group' : 'group', - 'Help' : 'helpwindow', - 'Incarnate' : 'incarnate', - 'Inspirations' : 'insp', - 'League' : 'league', - 'LFG' : 'lfg', - 'Map' : 'map', - 'Mission' : 'mission', - 'Nav / Compass' : 'nav', - 'Options' : 'options', - 'Pets' : 'pet', - 'Petition' : 'petition', - 'Power Tray' : 'powers', - 'Power List' : 'powerlist', - 'Quit' : 'quit', - 'Recipes' : 'recipe', - 'Salvage' : 'salvage', - 'Search' : 'search', - 'Supergroup' : 'sg', - 'Target' : 'target', - 'Team' : 'team', - 'Tray' : 'tray', - 'Tray1' : 'tray1', - 'Tray2' : 'tray2', - 'Tray3' : 'tray3', - 'Tray4' : 'tray4', - 'Tray5' : 'tray5', - 'Tray6' : 'tray6', - 'Tray7' : 'tray7', - 'Tray8' : 'tray8', - 'Vault' : 'vault', - } - - self.ShortToggleCommands = { - 'Auction House' : 'ah', - 'Chat' : 'chat', - 'Help' : 'helpwindow', - 'Map' : 'map', - 'Nav / Compass' : 'nav', - 'Power Tray' : 'powers', - 'Target' : 'target', - 'Tray' : 'tray', - } - - windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) - windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) - self.windowToggleTray.SetSelection(0) - windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.windowShowRB = wx.RadioButton(dialog, -1, "Show") - self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") - - windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) - - return windowToggleSizer - - def MakeBindString(self): - choice = self.windowToggleTray - index = choice.GetSelection() - windowdesc = choice.GetString(index) - windowname = self.WindowNames[windowdesc] - - if self.windowShowRB.GetValue(): - return 'show ' + windowname - elif self.windowHideRB.GetValue(): - return 'windowhide ' + windowname - else: - if shortcmd := self.ShortToggleCommands.get(windowdesc, None): - return shortcmd - else: - return 'toggle ' + windowname - - - def Serialize(self): - choice = self.windowToggleTray - if self.windowShowRB.GetValue(): - action = "Show" - elif self.windowHideRB.GetValue(): - action = "Hide" - else: - action = "Toggle" - return { - 'window': choice.GetString(choice.GetSelection()), - 'action': action, - } - - def Deserialize(self, init): - choice = self.windowToggleTray - if window := init.get('window', ''): - if isinstance(window, int): - choice.SetSelection(window) - else: - choice.SetSelection(choice.FindString(window)) - - if choice.GetSelection() == wx.NOT_FOUND: - choice.SetSelection(0) - - action = init.get('action', '') - if action == "Show": - self.windowShowRB.SetValue(True) - elif action == "Hide": - self.windowHideRB.SetValue(True) - else: - self.windowToggleRB.SetValue(True) - - -# Must always add to this list when adding a new command class above -menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], - # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, - # but I'm leaving it here to remind myself that we do that. - } - -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/LoadBindsDir.py b/UI/PowerBinderCommand/LoadBindsDir.py index 4c02ab7..a061a05 100644 --- a/UI/PowerBinderCommand/LoadBindsDir.py +++ b/UI/PowerBinderCommand/LoadBindsDir.py @@ -1,1009 +1,13 @@ import wx -import re -import UI -import UI.EmotePicker -from UI.ControlGroup import ControlGroup -from UI.PowerPicker import PowerPicker -from Help import HelpButton -import wx.adv -from wx.adv import BitmapComboBox, EditableListBox from pathlib import PureWindowsPath -import GameData import Profile -from Icon import GetIcon - -class PowerBinderDialog(wx.Dialog): - def __init__(self, parent, button, init = {}): - wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) - - self.Page = parent.Page - self.EditDialog = PowerBinderEditDialog(self) - self.Button = button - self.AddStepMenu = self.makeAddStepMenu() - - sizer = wx.BoxSizer(wx.VERTICAL); - self.mainSizer = sizer - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) - AddStepButton = wx.Button(self, -1, 'Add Step') - AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) - AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) - choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) - choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) - sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) - - rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) - - self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) - self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) - self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) - rearrangeCtrl.Add(self.RearrangeList, 1) - - rearrangeButtons = wx.BoxSizer(wx.VERTICAL) - self.DelButton = wx.Button(self, -1, "Delete") - self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) - self.EditButton = wx.Button(self, -1, "Edit") - self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) - self.EditButton.Disable() - upButton = wx.Button(self, -1, "\u25B2") - upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) - downButton = wx.Button(self, -1, "\u25BC") - downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) - rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) - rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) - - sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.BindStringDisplay = wx.TextCtrl(self, -1) - self.BindStringDisplay.Disable() - choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, - wx.ALIGN_CENTER_VERTICAL) - choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) - - sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) - - sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) - - # need to dig around and get the OK button since we show this dialog modelessly now. - okButton = self.FindWindow(self.GetAffirmativeId()) - okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) - - # Wrap everything in a vbox to add some padding - vbox = wx.BoxSizer(wx.VERTICAL); - vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); - - self.SetSizerAndFit(vbox); - self.Layout() - self.Fit() - self.SetFocus() - - # if we are loading from profile, ie, have "init", build the list from it - if init: self.LoadFromData(init) - - def LoadFromData(self, init): - for item in init: - for type, data in item.items(): - commandClass = commandClasses.get(type, None) - if not commandClass: - commandClass = deprecatedCommandClasses.get(type, None) - if not commandClass: - wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") - continue - newCommand = commandClass(self.EditDialog, data) - index = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.SetClientData(index, newCommand) - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) - self.EditDialog.mainSizer.Hide(newCommand.UI) - self.UpdateBindStringDisplay() - - def SaveToData(self): - data = [] - index = 0 - for _ in self.RearrangeList.GetItems(): - # check whether we have an object already attached to this choice - cmdObject = self.RearrangeList.GetClientData(index) - commandClassName = commandRevClasses[type(cmdObject)] - data.append({commandClassName: cmdObject.Serialize()}) - index = index + 1 - return data - - def OnAddStepButton(self, evt): - button = evt.EventObject - if not self.AddStepMenu: - self.AddStepMenu = self.makeAddStepMenu() - button.PopupMenu(self.AddStepMenu) - - - def OnOKButton(self, _): - if self.Button.tgtTxtCtrl: - bindString = self.MakeBindString() - if bindString != self.Button.tgtTxtCtrl.GetValue(): - self.Button.tgtTxtCtrl.SetValue(bindString) - wx.App.Get().Main.Profile.SetModified() - self.Close() - - def OnRearrangeDelete(self, _): - current = self.RearrangeList.GetSelection() - if current == wx.NOT_FOUND: return - - self.RearrangeList.Delete(current) - self.UpdateBindStringDisplay() - - def OnRearrangeUp(self, _): - self.RearrangeList.MoveCurrentUp() - self.UpdateBindStringDisplay() - - def OnRearrangeDown(self, _): - self.RearrangeList.MoveCurrentDown() - self.UpdateBindStringDisplay() - - def OnRearrangeEdit(self, _): - index = self.RearrangeList.GetSelection() - - # check whether we have an object already attached to this choice - cmdObject = None - try: - cmdObject = self.RearrangeList.GetClientData(index) - except Exception: - pass - - if cmdObject: - self.ShowEditDialogFor(cmdObject) - self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) - else: - print("cmdObject was None") - self.UpdateBindStringDisplay() - - # OnAddStepMenu creates a new step and adds it to the rearrangelist - def OnAddStepMenu(self, evt): - menuitem = self.AddStepMenu.FindItemById(evt.GetId()) - chosenName = menuitem.GetItemLabel() - - # make a new command object, attached to the parent dialog - newCommandClass = commandClasses[chosenName] - newCommand = newCommandClass(self.EditDialog) - - # show the edit dialog if this command needs it - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) - if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): - self.EditDialog.mainSizer.Remove(newCommand.UI) - return - - newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.Select(newBindIndex) - self.RearrangeList.SetClientData(newBindIndex, newCommand) - - self.OnListSelect() - self.UpdateBindStringDisplay() - - def OnListSelect(self, _ = None): - selected = self.RearrangeList.GetSelection() - - if selected != wx.NOT_FOUND: - selCommand = self.RearrangeList.GetClientData(selected) - if selCommand.UI: - self.EditButton.Enable() - else: - self.EditButton.Disable() - - def UpdateBindStringDisplay(self): - self.BindStringDisplay.SetValue(self.MakeBindString()) - self.BindStringDisplay.SetToolTip(self.MakeBindString()) - - def MakeBindString(self): - cmdBindStrings = [] - for index in range(self.RearrangeList.GetCount()): - c = self.RearrangeList.GetClientData(index) - if c: cmdBindStrings.append(c.MakeBindString()) - - bindstring = ('$$'.join(cmdBindStrings)) - return bindstring - - def ShowEditDialogFor(self, command): - if not command.UI: return - - self.EditDialog.mainSizer.Show(command.UI) - - self.EditDialog.Layout() - self.EditDialog.Fit() - - self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') - returnval = self.EditDialog.ShowModal() - - self.EditDialog.mainSizer.Hide(command.UI) - - return returnval - - def makeAddStepMenu(self): - - stepMenu = wx.Menu() - - for subname in menuStructure: - submenu = wx.Menu() - stepMenu.AppendSubMenu(submenu, subname) - for classname in menuStructure[subname]: - submenu.Append(wx.ID_ANY, classname) - - stepMenu.Append(wx.ID_ANY, 'Custom Bind') - - return stepMenu - -class PowerBinderButton(wx.BitmapButton): - - def __init__(self, parent, tgtTxtCtrl, init = {}): - wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) - self.Init = init - self.Dialog = None - self.DialogParent = parent - - self.tgtTxtCtrl = tgtTxtCtrl - self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) - self.SetToolTip("Launch PowerBinder") - - def PowerBinderEventHandler(self, _): - self.PowerBinderDialog().Show() - - def LoadFromData(self, data): - self.PowerBinderDialog().LoadFromData(data) - - def SaveToData(self): - return self.PowerBinderDialog().SaveToData() - - def PowerBinderDialog(self): - if not self.Dialog: - self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) - return self.Dialog - - -class PowerBinderEditDialog(wx.Dialog): - def __init__(self, parent): - wx.Dialog.__init__(self, parent, -1, "Edit Step", - style = wx.DEFAULT_DIALOG_STYLE) - - outerSizer = wx.BoxSizer(wx.VERTICAL) - - self.mainSizer = wx.BoxSizer(wx.VERTICAL) - self.mainSizer.SetMinSize([500, 150]) - - self.Page = parent.Page - - self.mainSizer.Add( - self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), - 0, wx.EXPAND|wx.ALL, 10) - - outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) - - self.SetSizerAndFit(outerSizer) - self.Layout() - self.Fit() - -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" - - -####### Away From Keyboard -class AFKCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.Groups = {} - self.AttributeTable = { - 'Base' : { - 'Current Hit Points' : 'NT H', - 'Max Hit Points' : 'X H', - 'Current Endurance' : 'T E', - 'Max Endurance' : 'X EN', - 'Regeneration Rate' : 'N RAT', - 'Recovery Rate' : 'Y RA', - 'Endurance Consumption' : 'SU', - 'ToHit Bonus' : 'T B', - 'Accuracy Bonus' : 'CC', - 'Last Hit Chance' : 'T C', - 'Damage Bonus' : 'DA', - 'Healing Bonus' : 'NG B', - 'Recharge Time Bonus' : 'ME B', - 'Endurance Discount' : 'CE DIS', - 'Stealth Radius (PvP)' : 'PVP', - 'Stealth Radius (PvE)' : 'PVE', - 'Perception Radius' : 'RC', - 'Range Bonus' : 'GE B', - 'Threat Level' : 'AT L', - 'Experience to Next Level' : 'XT', - 'Experience Debt' : 'XP', - 'Influence / Infamy' : 'INF', - 'Inherent' : 'NH', - }, - 'Movement Speed' : { - 'Flying Speed' : 'FL', - 'Jumping Speed' : 'PI', - 'Max Jump Height' : 'X J', - 'Run Speed' : 'RU', - }, - 'Damage Resistance' : { - 'Smashing Resistance' : 'G R', - 'Lethal Resistance' : 'L R', - 'Fire Resistance' : 'RE R', - 'Cold Resistance' : 'COLD R', - 'Energy Resistance' : 'DamageType[4]', - 'Negative Energy Resistance' : 'GY R', - 'Psyonic Resistance' : 'NIC R', - 'Toxic Resistance' : 'XIC R', - }, - 'Defense' : { - 'Base Defense' : 'BAS', - 'Ranged Defense' : 'ED', - 'Melee Defense' : 'MEL', - 'AoE Defense' : '2', - 'Smashing Defense' : '3', - 'Lethal Defense' : '4', - 'Fire Defense' : '5', - 'Cold Defense' : '6', - 'Energy Defense' : '7', - 'Negative Energy Defense' : '8', - 'Psionic Defense' : '9', - 'Toxic Defense' : '1', - }, - 'Debuff Resistance' : { - 'Regeneration Resistance' : 'ON R', - 'Recovery Resistance' : 'RY R', - 'To Hit Resistance' : 'IT R', - 'Defense Resistance' : 'NSE RES', - }, - 'Status Effect Protection' : { - 'Hold Protection' : 'D P', - 'Immobilize Protection' : 'LIZE P', - 'Stun Protection' : 'N P', - 'Sleep Protection' : 'P P', - 'Knockback Protection' : 'K P', - 'Confuse Protection' : 'SE P', - 'Terrorize Protection' : 'ZE P', - 'Repel Protection' : 'EL P', - 'Teleport Protection' : 'T P', - }, - 'Status Effect Resistance' : { - 'Hold Resistance' : 'D R', - 'Immobilize Resistance' : 'LIZE R', - 'Stun Resistance' : 'N R', - 'Sleep Resistance' : 'P R', - 'Knockback Resistance' : 'K R', - 'Confuse Resistance' : 'SE R', - 'Terrorize Resistance' : 'ZE R', - 'Placate Resistance' : 'TE R', - 'Taunt Resistance' : 'NT R', - }, - 'Miscellaneous' : { - 'Level Shift' : 'L S', - }, - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.AttributeMenu = wx.Menu() - for group, controls in self.AttributeTable.items(): - submenu = wx.Menu() - self.AttributeMenu.AppendSubMenu(submenu, group) - for cb in controls: - submenu.Append(wx.ID_ANY, cb) - - self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) - - self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) - groupSizer.Add(self.editbox) - - newButton = self.editbox.GetNewButton() - newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) - - return groupSizer - - def MakeBindString(self): - map = {} - bindstrings = [] - for _, controls in self.AttributeTable.items(): - for cb, data in controls.items(): - map[cb] = data - - for string in self.editbox.GetStrings(): - if string: - bindstrings.append(f'monitorattribute {map[string]}') - - return '$$'.join(bindstrings) - - def Serialize(self): - return { - 'attributes' : self.editbox.GetStrings() - } - - def Deserialize(self, init): - self.editbox.SetStrings(init.get('attributes', [])) - - def OnNewButton(self, evt): - evt.GetEventObject().PopupMenu(self.AttributeMenu) - - def OnMenuItem(self, evt): - menuitem = evt.EventObject.FindItemById(evt.GetId()) - existingstrings = self.editbox.GetStrings() - existingstrings.append(menuitem.GetItemLabel()) - self.editbox.SetStrings(existingstrings) - -####### Auto Power -class AutoPowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) - autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.autoPowerName = PowerPicker(dialog) - autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) - - return autoPowerSizer - - def MakeBindString(self): - return f"powexecauto {self.autoPowerName.GetLabel()}" - - def Serialize(self): - return { - 'pname' : self.autoPowerName.GetLabel(), - 'picon' : self.autoPowerName.IconFilename - } - - def Deserialize(self, init): - if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.buffDisplayMap = { - 'Status Window' : { - 'Hide Auto' : 1, - 'Hide Toggles' : 2, - 'No Blinking' : 4, - 'No Stacking' : 8, - 'Numeric Stacking' : 16, - 'Hide Buff Numbers' : 32, - 'Stop Sending Buffs' : 64, - }, - 'Group Window' : { - 'Hide Auto' : 256, - 'Hide Toggles' : 512, - 'No Blinking' : 1024, - 'No Stacking' : 2048, - 'Numeric Stacking' : 4096, - 'Hide Buff Numbers' : 8192, - 'Stop Sending Buffs' : 16384, - }, - 'Pet Window' : { - 'Hide Auto' : 65536, - 'Hide Toggles' : 131072, - 'No Blinking' : 262144, - 'No Stacking' : 524288, - 'Numeric Stacking' : 1048576, - 'Hide Buff Numbers' : 2097152, - 'Stop Sending Buffs' : 4194304, - }, - } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - for group, controls in self.buffDisplayMap.items(): - self.Groups[group] = ControlGroup(dialog, self.Page, label = group) - groupid = self.Groups[group].GetStaticBox().GetId() - for cb, data in controls.items(): - self.Groups[group].AddControl( - ctlType = 'checkbox', - ctlName = f"{groupid}_{group}_{cb}", - label = cb, - data = data, - ) - - groupSizer.Add(self.Groups[group]) - - return groupSizer - - def CalculateValue(self): - page = wx.App.Get().Main.Profile.CustomBinds - - total = 0 - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] - if checkbox.IsChecked(): - total = total + checkbox.Data - return total - - def MakeBindString(self): - return f"optionset buffsettings {self.CalculateValue()}" - - def Serialize(self): - return { 'value' : self.CalculateValue() } - - def Deserialize(self, init): - value = init.get('value', 0) - - value = value or 0 # in case we had for some reason 'None' stashed in the init values - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] - checkbox.SetValue( checkbox.Data & value ) - -####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - chatCommandSizer = wx.GridBagSizer(5, 5) - self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") - chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) - # row 1 - self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) - self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) - self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) - # row 2 - self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) - self.chatCommandDuration.SetRange(1, 20) - self.chatCommandDuration.SetValue(7) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandDuration, (2,1)) - self.chatCommandChatSize = wx.Choice(dialog, -1, - choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) - self.chatCommandChatSize.SetSelection(5) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) - self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) - self.chatCommandChannel.SetSelection(0) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChannel, (2,5)) - # row 3 - self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") - chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) - self.chatCommandMessage = wx.TextCtrl(dialog, -1) - self.chatCommandMessage.SetHint('Chat Command Text') - chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) - - return chatCommandSizer - - def MakeBindString(self): - duration = self.chatCommandDuration.GetValue() - - choice = self.chatCommandChatSize - index = choice.GetSelection() - size = choice.GetString(index) - - duration = f"" if duration != 7 else "" - size = f"" if size != "1" else "" - - bdcolor = fgcolor = bgcolor = '' - if self.chatCommandUseColorsCB.IsChecked(): - bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - - bdcolor = f"" - fgcolor = f"" - bgcolor = f"" - - beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' - text = self.chatCommandMessage.GetValue() - - choice = self.chatCommandChannel - index = choice.GetSelection() - channel = choice.GetString(index) - - return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" - - def Serialize(self): - return { - 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), - 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), - 'channel' : self.chatCommandChannel .GetSelection(), - 'size' : self.chatCommandChatSize.GetSelection(), - 'duration' : self.chatCommandDuration.GetValue(), - 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'text' : self.chatCommandMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) - if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) - if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) - if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) - if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) - if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) - if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) - if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) - if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - - -####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): - def BuildUI(self, dialog): - chatCommandGlobalSizer = wx.GridBagSizer(5,5) - - self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") - chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) - - self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalChannel.SetHint("Channel") - chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) - - self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') - chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) - - chatCommandGlobalSizer.AddGrowableCol(1) - - return chatCommandGlobalSizer - - def MakeBindString(self): - useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() - channel = self.chatCommandGlobalChannel.GetValue() - message = self.chatCommandGlobalMessage.GetValue() - - preface = "beginchat /" if useBeginchat else "" - - return f'{preface}send "{channel}" {message}' - - def Serialize(self): - return { - 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), - 'channel' : self.chatCommandGlobalChannel.GetValue(), - 'message' : self.chatCommandGlobalMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) - if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) - if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) - -#######Costume Change -class CostumeChangeCmd(PowerBindCmd): - def BuildUI(self, dialog): - costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeCostume = wx.Choice(dialog, -1, - choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) - self.costumeChangeCostume.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeEmote = wx.Choice(dialog, -1, - choices = GameData.Emotes['costumechange']) - self.costumeChangeEmote.Insert("- None -", 0) - self.costumeChangeEmote.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return costumeChangeSizer - - def MakeBindString(self): - costumeNumber = self.costumeChangeCostume.GetSelection() - costumeEmote = self.costumeChangeEmote.GetSelection() - - if costumeEmote: # None, or 0 == "- None -" - ccCmd = 'cce' - emoteName = self.costumeChangeEmote.GetString(costumeEmote) - emoteName = " CC" + emoteName.replace(" ","") - else: - ccCmd = 'cc' - emoteName = '' - - return f"{ccCmd} {costumeNumber}{emoteName}" - - def Serialize(self): - return{ - 'costumeNumber': self.costumeChangeCostume.GetSelection(), - 'costumeEmote' : self.costumeChangeEmote.GetSelection(), - } - - def Deserialize(self, init): - if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) - if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) - -####### Movement Command -class MovementCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - self.plusbutton.SetValue(True) - - self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.commandchoice = wx.Choice(dialog, choices = [ - "forward", "left", "right", "backward", "up", "down", - "turnleft", "turnright", "first", "autorun", "clicktomove", - ],) - sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) - self.commandchoice.SetSelection(0) - - self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - pre = post = '' - if self.plusbutton.GetValue() : pre = "+" - elif self.plusplusbutton.GetValue() : pre = "++" - elif self.minusbutton.GetValue() : pre = "-" - elif self.zerobutton.GetValue() : post = " 0" - elif self.onebutton.GetValue() : post = " 1" - - command = self.commandchoice.GetString(self.commandchoice.GetSelection()) - - return f"{pre}{command}{post}" - - def Serialize(self): - mod = '' - if self.plusbutton.GetValue() : mod = "plus" - elif self.plusplusbutton.GetValue() : mod = "plusplus" - elif self.minusbutton.GetValue() : mod = "minus" - elif self.zerobutton.GetValue() : mod = "zero" - elif self.onebutton.GetValue() : mod = "one" - - return { - 'mod' : mod, - 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), - } - - def Deserialize(self, init): - mod = init.get('mod', 'plus') - - if mod == 'plus' : self.plusbutton.SetValue(True) - elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) - elif mod == 'minus' : self.minusbutton.SetValue(True) - elif mod == 'zero' : self.zerobutton.SetValue(True) - elif mod == 'one' : self.onebutton.SetValue(True) - - self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) - -####### Graphics Command -class GraphicsCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.FlexGridSizer(2) - - self.visscalecb = wx.CheckBox(dialog, label = "visscale") - sizer.Add(self.visscalecb) - self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) - sizer.Add(self.visscalesc) - - self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") - sizer.Add(self.dofweightcb) - self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) - sizer.Add(self.dofweightsc) - - self.fsaacb = wx.CheckBox(dialog, label = "fsaa") - sizer.Add(self.fsaacb) - self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) - self.fsaach.SetSelection(0) - sizer.Add(self.fsaach) - - self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") - sizer.Add(self.bloomscalecb) - self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) - self.bloomscalech.SetSelection(0) - sizer.Add(self.bloomscalech) - - self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") - sizer.Add(self.bloomweightcb) - self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) - sizer.Add(self.bloomweightsc) - - self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") - sizer.Add(self.lodbiascb) - self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) - sizer.Add(self.lodbiassc) - - self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") - sizer.Add(self.renderscalecb) - self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) - sizer.Add(self.renderscalesc) - - return sizer - - def MakeBindString(self): - # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. - bindstrings = [] - if self.visscalecb.IsChecked(): - bindstrings.append("visscale " + str(self.visscalesc.GetValue())) - if self.dofweightcb.IsChecked(): - bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) - if self.fsaacb.IsChecked(): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bindstrings.append("fsaa " + fsaavalue) - if self.bloomscalecb.IsChecked(): - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - bindstrings.append("bloomscale " + bloomscalevalue) - if self.bloomweightcb.IsChecked(): - bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) - if self.lodbiascb.IsChecked(): - bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) - if self.renderscalecb.IsChecked(): - bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) - - return '$$'.join(bindstrings) - - def Serialize(self): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - return { - 'visscalecb' : self.visscalecb.IsChecked(), - 'visscalesc' : self.visscalesc.GetValue(), - 'dofweightcb' : self.dofweightcb.IsChecked(), - 'dofweightsc' : self.dofweightsc.GetValue(), - 'fsaacb' : self.fsaacb.IsChecked(), - 'fsaach' : fsaavalue, - 'bloomscalecb' : self.bloomscalecb.IsChecked(), - 'bloomscalech' : bloomscalevalue, - 'bloomweightcb' : self.bloomweightcb.IsChecked(), - 'bloomweightsc' : self.bloomweightsc.GetValue(), - 'lodbiascb' : self.lodbiascb.IsChecked(), - 'lodbiassc' : self.lodbiassc.GetValue(), - 'renderscalecb' : self.renderscalecb.IsChecked(), - 'renderscalesc' : self.renderscalesc.GetValue(), - } - - def Deserialize(self, init): - self.visscalecb.SetValue(init.get('visscalecb', False)) - self.visscalesc.SetValue(init.get('visscalesc', 1.0)) - self.dofweightcb.SetValue(init.get('dofweightcb', False)) - self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) - self.fsaacb.SetValue(init.get('fsaacb', False)) - self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) - self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) - self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) - self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) - self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) - self.lodbiascb.SetValue(init.get('lodbiascb', False)) - self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) - self.renderscalecb.SetValue(init.get('renderscalecb', False)) - self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) - -####### Custom Bind -class CustomBindCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.customBindName = wx.TextCtrl(dialog, -1) - self.customBindName.SetHint('Custom Bind Text') - sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - return self.customBindName.GetValue() - - def Serialize(self): - return { 'customBindName': self.customBindName.GetValue() } - - def Deserialize(self,init): - if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) - -####### Emote -class EmoteCmd(PowerBindCmd): - def BuildUI(self, dialog): - emoteSizer = wx.BoxSizer(wx.HORIZONTAL) - self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") - emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - self.emoteName = wx.Button(dialog, -1, "...") - self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) - emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) - - return emoteSizer - - def MakeBindString(self): - displayedEmoteName = self.emoteName.GetLabel() - actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] - - return actualEmotePayload - - def Serialize(self): - return {'emoteName': self.emoteName.GetLabel()} - - def Deserialize(self, init): - if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) +from UI.PowerBinderCommand import PowerBinderCommand ####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): +class LoadBindsDir(PowerBinderCommand): + Name = "Load Binds Directory" + Menu = "Misc" + def BuildUI(self, dialog): mainSizer = wx.BoxSizer(wx.VERTICAL) @@ -1051,750 +55,3 @@ def Serialize(self): def Deserialize(self, init): if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) - -####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' - -####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' - -####### SG Mode -class SGModeCmd(PowerBindCmd): - def BuildUI(self, dialog): - sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) - sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") - self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") - - sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) - - return sgmodeSizer - - def MakeBindString(self): - if self.sgmodeOnRB.GetValue(): - return 'sgmodeset 1' - elif self.sgmodeOffRB.GetValue(): - return 'sgmodeset 0' - else: - return 'sgmode' - - def Serialize(self): - if self.sgmodeOnRB.GetValue(): - val = "On" - elif self.sgmodeOffRB.GetValue(): - val = "Off" - else: - val = "Toggle" - - return {"value" : val} - - def Deserialize(self, init): - val = init.get('value', '') - if val == "On": - self.sgmodeOnRB.SetValue(True) - elif val == "Off": - self.sgmodeOffRB.SetValue(True) - else: - self.sgmodeToggleRB.SetValue(True) - -####### Target Custom -class TargetCustomCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetCustomSizer = wx.GridBagSizer(5,5) - targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), - flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) - self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetCustomModeChoice.SetSelection(0) - targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) - self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) - self.targetCustomOptionalName.SetHint("Optional name to match") - targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) - self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") - targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) - self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") - targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) - self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") - targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) - self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") - targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) - self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") - targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) - self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") - targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) - self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") - targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) - self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") - targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) - - targetCustomSizer.AddGrowableCol(2) - - return targetCustomSizer - - def MakeBindString(self): - choice = self.targetCustomModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - targetCommand = "targetcustom" + mode.lower() - - enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" - friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" - defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" - alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" - mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" - notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" - base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" - notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" - - name = self.targetCustomOptionalName.GetValue() - - return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" - - def Serialize(self): - return { - 'mode' : self.targetCustomModeChoice.GetSelection(), - 'enemy' : self.targetCustomCBEnemies. IsChecked(), - 'friend' : self.targetCustomCBFriends. IsChecked(), - 'defeated' : self.targetCustomCBDefeated. IsChecked(), - 'alive' : self.targetCustomCBAlive. IsChecked(), - 'mypet' : self.targetCustomCBMyPets. IsChecked(), - 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), - 'base' : self.targetCustomCBBaseItems. IsChecked(), - 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), - 'name' : self.targetCustomOptionalName.GetValue(), - } - - def Deserialize(self, init): - if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) - if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) - if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) - if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) - if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) - if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) - if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) - if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) - if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) - if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - - -####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) - targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetEnemyModeChoice.SetSelection(0) - targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetEnemySizer - - def MakeBindString(self): - choice = self.targetEnemyModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetenemy" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetEnemyModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) - -####### Target Friend -class TargetFriendCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) - targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetFriendModeChoice.SetSelection(0) - targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetFriendSizer - - def MakeBindString(self): - choice = self.targetFriendModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetfriend" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetFriendModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) - -####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): - def BuildUI(self, dialog): - teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], - style=wx.ALIGN_CENTER_VERTICAL) - self.teamPetSelectNumber.SetSelection(0) - teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) - - return teamPetSelectSizer - - def MakeBindString(self): - teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' - targetNumber = self.teamPetSelectNumber.GetSelection()+1 - - return f"{teamOrPet}select {targetNumber}" - - def Serialize(self): - return { - 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', - 'targetNum': self.teamPetSelectNumber.GetSelection(), - } - - def Deserialize(self, init): - ToP = init.get('teamOrPet', '') - if ToP == 'pet': - self.teamPetSelectPetRB.SetValue(True) - else: - self.teamPetSelectTeamRB.SetValue(True) - if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) - -####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' - -####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) - for _, types in GameData.Inspirations.items(): - for _, info in types.items(): - for insp in info['tiers']: - name = re.sub(' ', '', str(insp)) - icon = GetIcon(f'Inspirations/{name}') - self.useInspByNameModeChoice.Append(insp, icon) - self.useInspByNameModeChoice.SetSelection(0) - useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) - - return useInspByNameSizer - - def MakeBindString(self): - choice = self.useInspByNameModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "inspexecname " + mode.lower() - - def GetAllInsps(self): - Insplist = [] - for _, info in GameData.Inspirations.items(): - for insp in info['tiers']: - Insplist.append(insp) - Insplist.append("---") - Insplist.pop(-1) # snip the terminal "---" - - return Insplist - - def Serialize(self): - return { 'insp' : self.useInspByNameModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) - -####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnRow.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) - self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnCol.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) - - return useInspRowColumnSizer - - def MakeBindString(self): - row = self.useInspRowColumnRow.GetSelection()+1 - col = self.useInspRowColumnCol.GetSelection()+1 - - return f"inspexectray {col} {row}" - - def Serialize(self): - return { - 'col' : self.useInspRowColumnCol.GetSelection(), - 'row' : self.useInspRowColumnRow.GetSelection(), - } - - def Deserialize(self, init): - if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) - if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) - -####### Use Power -class UsePowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - outerSizer = wx.BoxSizer(wx.HORIZONTAL) - - usePowerSizer = wx.GridBagSizer(5,5) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBToggle, (0,1)) - self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOn, (0,2)) - self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOff, (0,3)) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerName = PowerPicker(dialog) - usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) - usePowerSizer.AddGrowableCol(3) - - outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) - - return outerSizer - - def MakeBindString(self): - if self.usePowerRBToggle.GetValue(): - method = "powexecname" - elif self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') - return '' - - return f"{method} {self.usePowerName.GetLabel()}" - - def Serialize(self): - if self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - method = "powexecname" - return { - 'method': method, - 'pname' : self.usePowerName.GetLabel(), - 'picon' : self.usePowerName.IconFilename - } - - def Deserialize(self, init): - method = init.get('method', '') - if method == 'powexectoggleon': - self.usePowerRBOn.SetValue(True) - elif method == 'powexectoggleoff': - self.usePowerRBOff.SetValue(True) - else: - self.usePowerRBToggle.SetValue(True) - if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) - -####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): - def BuildUI(self, dialog): - usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTrayTray = wx.Choice(dialog, -1, - choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', - 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) - self.usePowerFromTrayTray.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) - self.usePowerFromTraySlot.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return usePowerFromTraySizer - - def MakeBindString(self): - choice = self.usePowerFromTrayTray - tray = choice.GetSelection() - - choice = self.usePowerFromTraySlot - slot = choice.GetSelection()+1 - - mode = "slot" - mode2 = '' - if tray > 3: - mode = "tray" - mode2 = f" {tray - 3}" - elif tray == 3: - mode = "alt2slot" - elif tray == 2: - mode = "altslot" - - return f"powexec{mode} {slot}{mode2}" - - def Serialize(self): - return { - 'tray' : self.usePowerFromTrayTray.GetSelection(), - 'slot' : self.usePowerFromTraySlot.GetSelection(), - } - - def Deserialize(self, init): - if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) - if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) - -####### Window Color -class WindowColorCmd(PowerBindCmd): - def BuildUI(self, dialog): - windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) - borderSizer = wx.BoxSizer(wx.VERTICAL) - self.ColorBorder.SetSizer(borderSizer) - self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) - borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) - - windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) - - RGBASizer = wx.FlexGridSizer(3, 4, 5) - - RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) - self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) - self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - windowColorSizer.Add(RGBASizer) - - self.UpdateFromSlider() - - return windowColorSizer - - def MakeBindString(self): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - return f"windowcolor {Rval} {Gval} {Bval} {Aval}" - - def Serialize(self): - return { - 'Rval' : self.RSlider.GetValue(), - 'Gval' : self.GSlider.GetValue(), - 'Bval' : self.BSlider.GetValue(), - 'Aval' : self.ASlider.GetValue(), - } - - def Deserialize(self, init): - self.RSlider.SetValue(init['Rval']) - self.GSlider.SetValue(init['Gval']) - self.BSlider.SetValue(init['Bval']) - self.ASlider.SetValue(init['Aval']) - self.UpdateFromSlider() - - def UpdateFromSlider(self, _ = None): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RReadout.SetValue(Rval) - self.GReadout.SetValue(Gval) - self.BReadout.SetValue(Bval) - self.AReadout.SetValue(Aval) - self.ColorBorder.Refresh() - - def UpdateFromText(self, _ = None): - Rval = self.RReadout.GetValue() - Gval = self.GReadout.GetValue() - Bval = self.BReadout.GetValue() - Aval = self.AReadout.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RSlider.SetValue(Rval) - self.GSlider.SetValue(Gval) - self.BSlider.SetValue(Bval) - self.ASlider.SetValue(Aval) - self.ColorBorder.Refresh() - -####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) - self.CommandChoice.SetSelection(0) - sizer.Add(self.CommandChoice, 0, wx.ALL, 5) - - self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), - value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) - sizer.Add(self.FilePath, 0, wx.ALL, 5) - - return sizer - - def MakeBindString(self): - command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] - return f'{command} "{self.FilePath.GetValue()}"' - - def Serialize(self): - return { - 'command' : self.CommandChoice.GetSelection(), - 'filename' : self.FilePath.GetValue(), - } - - def Deserialize(self, init): - self.CommandChoice.SetSelection(init.get('command', 0)) - self.FilePath.SetValue(init.get('filename', '')) - -####### Window Toggle -class WindowToggleCmd(PowerBindCmd): - def BuildUI(self, dialog): - self.WindowNames = { - 'Actions' : 'actions', - 'Auction House' : 'ah', - 'Badge' : 'badge', - 'Channel Search' : 'chansearch', - 'Chat' : 'chat', - 'Custom Chat 1' : 'chat1', - 'Custom Chat 2' : 'chat2', - 'Custom Chat 3' : 'chat3', - 'Custom Chat 4' : 'chat4', - 'Clues' : 'clue', - 'Combat Numbers' : 'combatnumbers', - 'Contacts' : 'contact', - 'Contact Finder' : 'contactfinder', - 'Costumes' : 'costume', - 'Email' : 'email', - 'Enhancements' : 'enhancements', - 'Friends' : 'friend', - 'Group' : 'group', - 'Help' : 'helpwindow', - 'Incarnate' : 'incarnate', - 'Inspirations' : 'insp', - 'League' : 'league', - 'LFG' : 'lfg', - 'Map' : 'map', - 'Mission' : 'mission', - 'Nav / Compass' : 'nav', - 'Options' : 'options', - 'Pets' : 'pet', - 'Petition' : 'petition', - 'Power Tray' : 'powers', - 'Power List' : 'powerlist', - 'Quit' : 'quit', - 'Recipes' : 'recipe', - 'Salvage' : 'salvage', - 'Search' : 'search', - 'Supergroup' : 'sg', - 'Target' : 'target', - 'Team' : 'team', - 'Tray' : 'tray', - 'Tray1' : 'tray1', - 'Tray2' : 'tray2', - 'Tray3' : 'tray3', - 'Tray4' : 'tray4', - 'Tray5' : 'tray5', - 'Tray6' : 'tray6', - 'Tray7' : 'tray7', - 'Tray8' : 'tray8', - 'Vault' : 'vault', - } - - self.ShortToggleCommands = { - 'Auction House' : 'ah', - 'Chat' : 'chat', - 'Help' : 'helpwindow', - 'Map' : 'map', - 'Nav / Compass' : 'nav', - 'Power Tray' : 'powers', - 'Target' : 'target', - 'Tray' : 'tray', - } - - windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) - windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) - self.windowToggleTray.SetSelection(0) - windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.windowShowRB = wx.RadioButton(dialog, -1, "Show") - self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") - - windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) - - return windowToggleSizer - - def MakeBindString(self): - choice = self.windowToggleTray - index = choice.GetSelection() - windowdesc = choice.GetString(index) - windowname = self.WindowNames[windowdesc] - - if self.windowShowRB.GetValue(): - return 'show ' + windowname - elif self.windowHideRB.GetValue(): - return 'windowhide ' + windowname - else: - if shortcmd := self.ShortToggleCommands.get(windowdesc, None): - return shortcmd - else: - return 'toggle ' + windowname - - - def Serialize(self): - choice = self.windowToggleTray - if self.windowShowRB.GetValue(): - action = "Show" - elif self.windowHideRB.GetValue(): - action = "Hide" - else: - action = "Toggle" - return { - 'window': choice.GetString(choice.GetSelection()), - 'action': action, - } - - def Deserialize(self, init): - choice = self.windowToggleTray - if window := init.get('window', ''): - if isinstance(window, int): - choice.SetSelection(window) - else: - choice.SetSelection(choice.FindString(window)) - - if choice.GetSelection() == wx.NOT_FOUND: - choice.SetSelection(0) - - action = init.get('action', '') - if action == "Show": - self.windowShowRB.SetValue(True) - elif action == "Hide": - self.windowHideRB.SetValue(True) - else: - self.windowToggleRB.SetValue(True) - - -# Must always add to this list when adding a new command class above -menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], - # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, - # but I'm leaving it here to remind myself that we do that. - } - -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/MovementCmd.py b/UI/PowerBinderCommand/MovementCmd.py index 4c02ab7..156e3ec 100644 --- a/UI/PowerBinderCommand/MovementCmd.py +++ b/UI/PowerBinderCommand/MovementCmd.py @@ -1,785 +1,11 @@ import wx -import re -import UI -import UI.EmotePicker -from UI.ControlGroup import ControlGroup -from UI.PowerPicker import PowerPicker -from Help import HelpButton -import wx.adv -from wx.adv import BitmapComboBox, EditableListBox -from pathlib import PureWindowsPath -import GameData -import Profile -from Icon import GetIcon - -class PowerBinderDialog(wx.Dialog): - def __init__(self, parent, button, init = {}): - wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) - - self.Page = parent.Page - self.EditDialog = PowerBinderEditDialog(self) - self.Button = button - self.AddStepMenu = self.makeAddStepMenu() - - sizer = wx.BoxSizer(wx.VERTICAL); - self.mainSizer = sizer - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) - AddStepButton = wx.Button(self, -1, 'Add Step') - AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) - AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) - choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) - choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) - sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) - - rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) - - self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) - self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) - self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) - rearrangeCtrl.Add(self.RearrangeList, 1) - - rearrangeButtons = wx.BoxSizer(wx.VERTICAL) - self.DelButton = wx.Button(self, -1, "Delete") - self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) - self.EditButton = wx.Button(self, -1, "Edit") - self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) - self.EditButton.Disable() - upButton = wx.Button(self, -1, "\u25B2") - upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) - downButton = wx.Button(self, -1, "\u25BC") - downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) - rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) - rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) - - sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.BindStringDisplay = wx.TextCtrl(self, -1) - self.BindStringDisplay.Disable() - choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, - wx.ALIGN_CENTER_VERTICAL) - choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) - - sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) - - sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) - - # need to dig around and get the OK button since we show this dialog modelessly now. - okButton = self.FindWindow(self.GetAffirmativeId()) - okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) - - # Wrap everything in a vbox to add some padding - vbox = wx.BoxSizer(wx.VERTICAL); - vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); - - self.SetSizerAndFit(vbox); - self.Layout() - self.Fit() - self.SetFocus() - - # if we are loading from profile, ie, have "init", build the list from it - if init: self.LoadFromData(init) - - def LoadFromData(self, init): - for item in init: - for type, data in item.items(): - commandClass = commandClasses.get(type, None) - if not commandClass: - commandClass = deprecatedCommandClasses.get(type, None) - if not commandClass: - wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") - continue - newCommand = commandClass(self.EditDialog, data) - index = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.SetClientData(index, newCommand) - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) - self.EditDialog.mainSizer.Hide(newCommand.UI) - self.UpdateBindStringDisplay() - - def SaveToData(self): - data = [] - index = 0 - for _ in self.RearrangeList.GetItems(): - # check whether we have an object already attached to this choice - cmdObject = self.RearrangeList.GetClientData(index) - commandClassName = commandRevClasses[type(cmdObject)] - data.append({commandClassName: cmdObject.Serialize()}) - index = index + 1 - return data - - def OnAddStepButton(self, evt): - button = evt.EventObject - if not self.AddStepMenu: - self.AddStepMenu = self.makeAddStepMenu() - button.PopupMenu(self.AddStepMenu) - - - def OnOKButton(self, _): - if self.Button.tgtTxtCtrl: - bindString = self.MakeBindString() - if bindString != self.Button.tgtTxtCtrl.GetValue(): - self.Button.tgtTxtCtrl.SetValue(bindString) - wx.App.Get().Main.Profile.SetModified() - self.Close() - - def OnRearrangeDelete(self, _): - current = self.RearrangeList.GetSelection() - if current == wx.NOT_FOUND: return - - self.RearrangeList.Delete(current) - self.UpdateBindStringDisplay() - - def OnRearrangeUp(self, _): - self.RearrangeList.MoveCurrentUp() - self.UpdateBindStringDisplay() - - def OnRearrangeDown(self, _): - self.RearrangeList.MoveCurrentDown() - self.UpdateBindStringDisplay() - - def OnRearrangeEdit(self, _): - index = self.RearrangeList.GetSelection() - - # check whether we have an object already attached to this choice - cmdObject = None - try: - cmdObject = self.RearrangeList.GetClientData(index) - except Exception: - pass - - if cmdObject: - self.ShowEditDialogFor(cmdObject) - self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) - else: - print("cmdObject was None") - self.UpdateBindStringDisplay() - - # OnAddStepMenu creates a new step and adds it to the rearrangelist - def OnAddStepMenu(self, evt): - menuitem = self.AddStepMenu.FindItemById(evt.GetId()) - chosenName = menuitem.GetItemLabel() - - # make a new command object, attached to the parent dialog - newCommandClass = commandClasses[chosenName] - newCommand = newCommandClass(self.EditDialog) - - # show the edit dialog if this command needs it - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) - if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): - self.EditDialog.mainSizer.Remove(newCommand.UI) - return - - newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.Select(newBindIndex) - self.RearrangeList.SetClientData(newBindIndex, newCommand) - - self.OnListSelect() - self.UpdateBindStringDisplay() - - def OnListSelect(self, _ = None): - selected = self.RearrangeList.GetSelection() - - if selected != wx.NOT_FOUND: - selCommand = self.RearrangeList.GetClientData(selected) - if selCommand.UI: - self.EditButton.Enable() - else: - self.EditButton.Disable() - - def UpdateBindStringDisplay(self): - self.BindStringDisplay.SetValue(self.MakeBindString()) - self.BindStringDisplay.SetToolTip(self.MakeBindString()) - - def MakeBindString(self): - cmdBindStrings = [] - for index in range(self.RearrangeList.GetCount()): - c = self.RearrangeList.GetClientData(index) - if c: cmdBindStrings.append(c.MakeBindString()) - - bindstring = ('$$'.join(cmdBindStrings)) - return bindstring - - def ShowEditDialogFor(self, command): - if not command.UI: return - - self.EditDialog.mainSizer.Show(command.UI) - - self.EditDialog.Layout() - self.EditDialog.Fit() - - self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') - returnval = self.EditDialog.ShowModal() - - self.EditDialog.mainSizer.Hide(command.UI) - - return returnval - - def makeAddStepMenu(self): - - stepMenu = wx.Menu() - - for subname in menuStructure: - submenu = wx.Menu() - stepMenu.AppendSubMenu(submenu, subname) - for classname in menuStructure[subname]: - submenu.Append(wx.ID_ANY, classname) - - stepMenu.Append(wx.ID_ANY, 'Custom Bind') - - return stepMenu - -class PowerBinderButton(wx.BitmapButton): - - def __init__(self, parent, tgtTxtCtrl, init = {}): - wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) - self.Init = init - self.Dialog = None - self.DialogParent = parent - - self.tgtTxtCtrl = tgtTxtCtrl - self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) - self.SetToolTip("Launch PowerBinder") - - def PowerBinderEventHandler(self, _): - self.PowerBinderDialog().Show() - - def LoadFromData(self, data): - self.PowerBinderDialog().LoadFromData(data) - - def SaveToData(self): - return self.PowerBinderDialog().SaveToData() - - def PowerBinderDialog(self): - if not self.Dialog: - self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) - return self.Dialog - - -class PowerBinderEditDialog(wx.Dialog): - def __init__(self, parent): - wx.Dialog.__init__(self, parent, -1, "Edit Step", - style = wx.DEFAULT_DIALOG_STYLE) - - outerSizer = wx.BoxSizer(wx.VERTICAL) - - self.mainSizer = wx.BoxSizer(wx.VERTICAL) - self.mainSizer.SetMinSize([500, 150]) - - self.Page = parent.Page - - self.mainSizer.Add( - self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), - 0, wx.EXPAND|wx.ALL, 10) - - outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) - - self.SetSizerAndFit(outerSizer) - self.Layout() - self.Fit() - -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" - - -####### Away From Keyboard -class AFKCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.Groups = {} - self.AttributeTable = { - 'Base' : { - 'Current Hit Points' : 'NT H', - 'Max Hit Points' : 'X H', - 'Current Endurance' : 'T E', - 'Max Endurance' : 'X EN', - 'Regeneration Rate' : 'N RAT', - 'Recovery Rate' : 'Y RA', - 'Endurance Consumption' : 'SU', - 'ToHit Bonus' : 'T B', - 'Accuracy Bonus' : 'CC', - 'Last Hit Chance' : 'T C', - 'Damage Bonus' : 'DA', - 'Healing Bonus' : 'NG B', - 'Recharge Time Bonus' : 'ME B', - 'Endurance Discount' : 'CE DIS', - 'Stealth Radius (PvP)' : 'PVP', - 'Stealth Radius (PvE)' : 'PVE', - 'Perception Radius' : 'RC', - 'Range Bonus' : 'GE B', - 'Threat Level' : 'AT L', - 'Experience to Next Level' : 'XT', - 'Experience Debt' : 'XP', - 'Influence / Infamy' : 'INF', - 'Inherent' : 'NH', - }, - 'Movement Speed' : { - 'Flying Speed' : 'FL', - 'Jumping Speed' : 'PI', - 'Max Jump Height' : 'X J', - 'Run Speed' : 'RU', - }, - 'Damage Resistance' : { - 'Smashing Resistance' : 'G R', - 'Lethal Resistance' : 'L R', - 'Fire Resistance' : 'RE R', - 'Cold Resistance' : 'COLD R', - 'Energy Resistance' : 'DamageType[4]', - 'Negative Energy Resistance' : 'GY R', - 'Psyonic Resistance' : 'NIC R', - 'Toxic Resistance' : 'XIC R', - }, - 'Defense' : { - 'Base Defense' : 'BAS', - 'Ranged Defense' : 'ED', - 'Melee Defense' : 'MEL', - 'AoE Defense' : '2', - 'Smashing Defense' : '3', - 'Lethal Defense' : '4', - 'Fire Defense' : '5', - 'Cold Defense' : '6', - 'Energy Defense' : '7', - 'Negative Energy Defense' : '8', - 'Psionic Defense' : '9', - 'Toxic Defense' : '1', - }, - 'Debuff Resistance' : { - 'Regeneration Resistance' : 'ON R', - 'Recovery Resistance' : 'RY R', - 'To Hit Resistance' : 'IT R', - 'Defense Resistance' : 'NSE RES', - }, - 'Status Effect Protection' : { - 'Hold Protection' : 'D P', - 'Immobilize Protection' : 'LIZE P', - 'Stun Protection' : 'N P', - 'Sleep Protection' : 'P P', - 'Knockback Protection' : 'K P', - 'Confuse Protection' : 'SE P', - 'Terrorize Protection' : 'ZE P', - 'Repel Protection' : 'EL P', - 'Teleport Protection' : 'T P', - }, - 'Status Effect Resistance' : { - 'Hold Resistance' : 'D R', - 'Immobilize Resistance' : 'LIZE R', - 'Stun Resistance' : 'N R', - 'Sleep Resistance' : 'P R', - 'Knockback Resistance' : 'K R', - 'Confuse Resistance' : 'SE R', - 'Terrorize Resistance' : 'ZE R', - 'Placate Resistance' : 'TE R', - 'Taunt Resistance' : 'NT R', - }, - 'Miscellaneous' : { - 'Level Shift' : 'L S', - }, - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.AttributeMenu = wx.Menu() - for group, controls in self.AttributeTable.items(): - submenu = wx.Menu() - self.AttributeMenu.AppendSubMenu(submenu, group) - for cb in controls: - submenu.Append(wx.ID_ANY, cb) - - self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) - - self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) - groupSizer.Add(self.editbox) - - newButton = self.editbox.GetNewButton() - newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) - - return groupSizer - - def MakeBindString(self): - map = {} - bindstrings = [] - for _, controls in self.AttributeTable.items(): - for cb, data in controls.items(): - map[cb] = data - - for string in self.editbox.GetStrings(): - if string: - bindstrings.append(f'monitorattribute {map[string]}') - - return '$$'.join(bindstrings) - - def Serialize(self): - return { - 'attributes' : self.editbox.GetStrings() - } - - def Deserialize(self, init): - self.editbox.SetStrings(init.get('attributes', [])) - - def OnNewButton(self, evt): - evt.GetEventObject().PopupMenu(self.AttributeMenu) - - def OnMenuItem(self, evt): - menuitem = evt.EventObject.FindItemById(evt.GetId()) - existingstrings = self.editbox.GetStrings() - existingstrings.append(menuitem.GetItemLabel()) - self.editbox.SetStrings(existingstrings) - -####### Auto Power -class AutoPowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) - autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.autoPowerName = PowerPicker(dialog) - autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) - - return autoPowerSizer - - def MakeBindString(self): - return f"powexecauto {self.autoPowerName.GetLabel()}" - - def Serialize(self): - return { - 'pname' : self.autoPowerName.GetLabel(), - 'picon' : self.autoPowerName.IconFilename - } - - def Deserialize(self, init): - if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.buffDisplayMap = { - 'Status Window' : { - 'Hide Auto' : 1, - 'Hide Toggles' : 2, - 'No Blinking' : 4, - 'No Stacking' : 8, - 'Numeric Stacking' : 16, - 'Hide Buff Numbers' : 32, - 'Stop Sending Buffs' : 64, - }, - 'Group Window' : { - 'Hide Auto' : 256, - 'Hide Toggles' : 512, - 'No Blinking' : 1024, - 'No Stacking' : 2048, - 'Numeric Stacking' : 4096, - 'Hide Buff Numbers' : 8192, - 'Stop Sending Buffs' : 16384, - }, - 'Pet Window' : { - 'Hide Auto' : 65536, - 'Hide Toggles' : 131072, - 'No Blinking' : 262144, - 'No Stacking' : 524288, - 'Numeric Stacking' : 1048576, - 'Hide Buff Numbers' : 2097152, - 'Stop Sending Buffs' : 4194304, - }, - } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - for group, controls in self.buffDisplayMap.items(): - self.Groups[group] = ControlGroup(dialog, self.Page, label = group) - groupid = self.Groups[group].GetStaticBox().GetId() - for cb, data in controls.items(): - self.Groups[group].AddControl( - ctlType = 'checkbox', - ctlName = f"{groupid}_{group}_{cb}", - label = cb, - data = data, - ) - - groupSizer.Add(self.Groups[group]) - - return groupSizer - - def CalculateValue(self): - page = wx.App.Get().Main.Profile.CustomBinds - - total = 0 - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] - if checkbox.IsChecked(): - total = total + checkbox.Data - return total - - def MakeBindString(self): - return f"optionset buffsettings {self.CalculateValue()}" - - def Serialize(self): - return { 'value' : self.CalculateValue() } - - def Deserialize(self, init): - value = init.get('value', 0) - - value = value or 0 # in case we had for some reason 'None' stashed in the init values - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] - checkbox.SetValue( checkbox.Data & value ) - -####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - chatCommandSizer = wx.GridBagSizer(5, 5) - self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") - chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) - # row 1 - self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) - self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) - self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) - # row 2 - self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) - self.chatCommandDuration.SetRange(1, 20) - self.chatCommandDuration.SetValue(7) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandDuration, (2,1)) - self.chatCommandChatSize = wx.Choice(dialog, -1, - choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) - self.chatCommandChatSize.SetSelection(5) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) - self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) - self.chatCommandChannel.SetSelection(0) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChannel, (2,5)) - # row 3 - self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") - chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) - self.chatCommandMessage = wx.TextCtrl(dialog, -1) - self.chatCommandMessage.SetHint('Chat Command Text') - chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) - - return chatCommandSizer - - def MakeBindString(self): - duration = self.chatCommandDuration.GetValue() - - choice = self.chatCommandChatSize - index = choice.GetSelection() - size = choice.GetString(index) - - duration = f"" if duration != 7 else "" - size = f"" if size != "1" else "" - - bdcolor = fgcolor = bgcolor = '' - if self.chatCommandUseColorsCB.IsChecked(): - bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - - bdcolor = f"" - fgcolor = f"" - bgcolor = f"" - - beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' - text = self.chatCommandMessage.GetValue() - - choice = self.chatCommandChannel - index = choice.GetSelection() - channel = choice.GetString(index) - - return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" - - def Serialize(self): - return { - 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), - 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), - 'channel' : self.chatCommandChannel .GetSelection(), - 'size' : self.chatCommandChatSize.GetSelection(), - 'duration' : self.chatCommandDuration.GetValue(), - 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'text' : self.chatCommandMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) - if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) - if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) - if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) - if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) - if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) - if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) - if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) - if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - - -####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): - def BuildUI(self, dialog): - chatCommandGlobalSizer = wx.GridBagSizer(5,5) - - self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") - chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) - - self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalChannel.SetHint("Channel") - chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) - - self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') - chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) - - chatCommandGlobalSizer.AddGrowableCol(1) - - return chatCommandGlobalSizer - - def MakeBindString(self): - useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() - channel = self.chatCommandGlobalChannel.GetValue() - message = self.chatCommandGlobalMessage.GetValue() - - preface = "beginchat /" if useBeginchat else "" - - return f'{preface}send "{channel}" {message}' - - def Serialize(self): - return { - 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), - 'channel' : self.chatCommandGlobalChannel.GetValue(), - 'message' : self.chatCommandGlobalMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) - if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) - if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) - -#######Costume Change -class CostumeChangeCmd(PowerBindCmd): - def BuildUI(self, dialog): - costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeCostume = wx.Choice(dialog, -1, - choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) - self.costumeChangeCostume.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeEmote = wx.Choice(dialog, -1, - choices = GameData.Emotes['costumechange']) - self.costumeChangeEmote.Insert("- None -", 0) - self.costumeChangeEmote.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return costumeChangeSizer - - def MakeBindString(self): - costumeNumber = self.costumeChangeCostume.GetSelection() - costumeEmote = self.costumeChangeEmote.GetSelection() - - if costumeEmote: # None, or 0 == "- None -" - ccCmd = 'cce' - emoteName = self.costumeChangeEmote.GetString(costumeEmote) - emoteName = " CC" + emoteName.replace(" ","") - else: - ccCmd = 'cc' - emoteName = '' - - return f"{ccCmd} {costumeNumber}{emoteName}" - - def Serialize(self): - return{ - 'costumeNumber': self.costumeChangeCostume.GetSelection(), - 'costumeEmote' : self.costumeChangeEmote.GetSelection(), - } - - def Deserialize(self, init): - if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) - if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) +from UI.PowerBinderCommand import PowerBinderCommand ####### Movement Command -class MovementCmd(PowerBindCmd): +class MovementCmd(PowerBinderCommand): + Name = "Movement Commands" + Menu = "Misc" + def BuildUI(self, dialog): sizer = wx.BoxSizer(wx.HORIZONTAL) @@ -843,958 +69,3 @@ def Deserialize(self, init): elif mod == 'one' : self.onebutton.SetValue(True) self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) - -####### Graphics Command -class GraphicsCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.FlexGridSizer(2) - - self.visscalecb = wx.CheckBox(dialog, label = "visscale") - sizer.Add(self.visscalecb) - self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) - sizer.Add(self.visscalesc) - - self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") - sizer.Add(self.dofweightcb) - self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) - sizer.Add(self.dofweightsc) - - self.fsaacb = wx.CheckBox(dialog, label = "fsaa") - sizer.Add(self.fsaacb) - self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) - self.fsaach.SetSelection(0) - sizer.Add(self.fsaach) - - self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") - sizer.Add(self.bloomscalecb) - self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) - self.bloomscalech.SetSelection(0) - sizer.Add(self.bloomscalech) - - self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") - sizer.Add(self.bloomweightcb) - self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) - sizer.Add(self.bloomweightsc) - - self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") - sizer.Add(self.lodbiascb) - self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) - sizer.Add(self.lodbiassc) - - self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") - sizer.Add(self.renderscalecb) - self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) - sizer.Add(self.renderscalesc) - - return sizer - - def MakeBindString(self): - # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. - bindstrings = [] - if self.visscalecb.IsChecked(): - bindstrings.append("visscale " + str(self.visscalesc.GetValue())) - if self.dofweightcb.IsChecked(): - bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) - if self.fsaacb.IsChecked(): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bindstrings.append("fsaa " + fsaavalue) - if self.bloomscalecb.IsChecked(): - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - bindstrings.append("bloomscale " + bloomscalevalue) - if self.bloomweightcb.IsChecked(): - bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) - if self.lodbiascb.IsChecked(): - bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) - if self.renderscalecb.IsChecked(): - bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) - - return '$$'.join(bindstrings) - - def Serialize(self): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - return { - 'visscalecb' : self.visscalecb.IsChecked(), - 'visscalesc' : self.visscalesc.GetValue(), - 'dofweightcb' : self.dofweightcb.IsChecked(), - 'dofweightsc' : self.dofweightsc.GetValue(), - 'fsaacb' : self.fsaacb.IsChecked(), - 'fsaach' : fsaavalue, - 'bloomscalecb' : self.bloomscalecb.IsChecked(), - 'bloomscalech' : bloomscalevalue, - 'bloomweightcb' : self.bloomweightcb.IsChecked(), - 'bloomweightsc' : self.bloomweightsc.GetValue(), - 'lodbiascb' : self.lodbiascb.IsChecked(), - 'lodbiassc' : self.lodbiassc.GetValue(), - 'renderscalecb' : self.renderscalecb.IsChecked(), - 'renderscalesc' : self.renderscalesc.GetValue(), - } - - def Deserialize(self, init): - self.visscalecb.SetValue(init.get('visscalecb', False)) - self.visscalesc.SetValue(init.get('visscalesc', 1.0)) - self.dofweightcb.SetValue(init.get('dofweightcb', False)) - self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) - self.fsaacb.SetValue(init.get('fsaacb', False)) - self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) - self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) - self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) - self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) - self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) - self.lodbiascb.SetValue(init.get('lodbiascb', False)) - self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) - self.renderscalecb.SetValue(init.get('renderscalecb', False)) - self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) - -####### Custom Bind -class CustomBindCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.customBindName = wx.TextCtrl(dialog, -1) - self.customBindName.SetHint('Custom Bind Text') - sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - return self.customBindName.GetValue() - - def Serialize(self): - return { 'customBindName': self.customBindName.GetValue() } - - def Deserialize(self,init): - if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) - -####### Emote -class EmoteCmd(PowerBindCmd): - def BuildUI(self, dialog): - emoteSizer = wx.BoxSizer(wx.HORIZONTAL) - self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") - emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - self.emoteName = wx.Button(dialog, -1, "...") - self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) - emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) - - return emoteSizer - - def MakeBindString(self): - displayedEmoteName = self.emoteName.GetLabel() - actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] - - return actualEmotePayload - - def Serialize(self): - return {'emoteName': self.emoteName.GetLabel()} - - def Deserialize(self, init): - if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) - -####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): - def BuildUI(self, dialog): - mainSizer = wx.BoxSizer(wx.VERTICAL) - - lbSizer = wx.BoxSizer(wx.HORIZONTAL) - lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") - lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - profiles = Profile.GetAllProfileBindsDirs() - - self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) - lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) - - mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") - self.lbResetCB.SetValue(True) - - mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - return mainSizer - - def MakeBindString(self): - - # If the specified binds directory disappeared between runs, we'd crash, so handle that. - if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' - - config = wx.ConfigBase.Get() - if config.Exists('GameBindPath'): - bindpath = config.Read('GameBindPath') - else: - bindpath = config.Read('BindPath') - - reset = "" - if self.lbResetCB.GetValue(): - reset = "keybind_reset$$" - - resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' - return reset + 'bindloadfile ' + str(resetfilepath) - - def Serialize(self): - return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), - 'ResetKeybinds' : self.lbResetCB.GetValue(), - } - - def Deserialize(self, init): - if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) - self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) - -####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' - -####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' - -####### SG Mode -class SGModeCmd(PowerBindCmd): - def BuildUI(self, dialog): - sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) - sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") - self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") - - sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) - - return sgmodeSizer - - def MakeBindString(self): - if self.sgmodeOnRB.GetValue(): - return 'sgmodeset 1' - elif self.sgmodeOffRB.GetValue(): - return 'sgmodeset 0' - else: - return 'sgmode' - - def Serialize(self): - if self.sgmodeOnRB.GetValue(): - val = "On" - elif self.sgmodeOffRB.GetValue(): - val = "Off" - else: - val = "Toggle" - - return {"value" : val} - - def Deserialize(self, init): - val = init.get('value', '') - if val == "On": - self.sgmodeOnRB.SetValue(True) - elif val == "Off": - self.sgmodeOffRB.SetValue(True) - else: - self.sgmodeToggleRB.SetValue(True) - -####### Target Custom -class TargetCustomCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetCustomSizer = wx.GridBagSizer(5,5) - targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), - flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) - self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetCustomModeChoice.SetSelection(0) - targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) - self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) - self.targetCustomOptionalName.SetHint("Optional name to match") - targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) - self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") - targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) - self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") - targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) - self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") - targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) - self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") - targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) - self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") - targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) - self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") - targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) - self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") - targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) - self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") - targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) - - targetCustomSizer.AddGrowableCol(2) - - return targetCustomSizer - - def MakeBindString(self): - choice = self.targetCustomModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - targetCommand = "targetcustom" + mode.lower() - - enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" - friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" - defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" - alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" - mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" - notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" - base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" - notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" - - name = self.targetCustomOptionalName.GetValue() - - return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" - - def Serialize(self): - return { - 'mode' : self.targetCustomModeChoice.GetSelection(), - 'enemy' : self.targetCustomCBEnemies. IsChecked(), - 'friend' : self.targetCustomCBFriends. IsChecked(), - 'defeated' : self.targetCustomCBDefeated. IsChecked(), - 'alive' : self.targetCustomCBAlive. IsChecked(), - 'mypet' : self.targetCustomCBMyPets. IsChecked(), - 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), - 'base' : self.targetCustomCBBaseItems. IsChecked(), - 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), - 'name' : self.targetCustomOptionalName.GetValue(), - } - - def Deserialize(self, init): - if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) - if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) - if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) - if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) - if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) - if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) - if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) - if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) - if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) - if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - - -####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) - targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetEnemyModeChoice.SetSelection(0) - targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetEnemySizer - - def MakeBindString(self): - choice = self.targetEnemyModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetenemy" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetEnemyModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) - -####### Target Friend -class TargetFriendCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) - targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetFriendModeChoice.SetSelection(0) - targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetFriendSizer - - def MakeBindString(self): - choice = self.targetFriendModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetfriend" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetFriendModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) - -####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): - def BuildUI(self, dialog): - teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], - style=wx.ALIGN_CENTER_VERTICAL) - self.teamPetSelectNumber.SetSelection(0) - teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) - - return teamPetSelectSizer - - def MakeBindString(self): - teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' - targetNumber = self.teamPetSelectNumber.GetSelection()+1 - - return f"{teamOrPet}select {targetNumber}" - - def Serialize(self): - return { - 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', - 'targetNum': self.teamPetSelectNumber.GetSelection(), - } - - def Deserialize(self, init): - ToP = init.get('teamOrPet', '') - if ToP == 'pet': - self.teamPetSelectPetRB.SetValue(True) - else: - self.teamPetSelectTeamRB.SetValue(True) - if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) - -####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' - -####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) - for _, types in GameData.Inspirations.items(): - for _, info in types.items(): - for insp in info['tiers']: - name = re.sub(' ', '', str(insp)) - icon = GetIcon(f'Inspirations/{name}') - self.useInspByNameModeChoice.Append(insp, icon) - self.useInspByNameModeChoice.SetSelection(0) - useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) - - return useInspByNameSizer - - def MakeBindString(self): - choice = self.useInspByNameModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "inspexecname " + mode.lower() - - def GetAllInsps(self): - Insplist = [] - for _, info in GameData.Inspirations.items(): - for insp in info['tiers']: - Insplist.append(insp) - Insplist.append("---") - Insplist.pop(-1) # snip the terminal "---" - - return Insplist - - def Serialize(self): - return { 'insp' : self.useInspByNameModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) - -####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnRow.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) - self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnCol.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) - - return useInspRowColumnSizer - - def MakeBindString(self): - row = self.useInspRowColumnRow.GetSelection()+1 - col = self.useInspRowColumnCol.GetSelection()+1 - - return f"inspexectray {col} {row}" - - def Serialize(self): - return { - 'col' : self.useInspRowColumnCol.GetSelection(), - 'row' : self.useInspRowColumnRow.GetSelection(), - } - - def Deserialize(self, init): - if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) - if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) - -####### Use Power -class UsePowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - outerSizer = wx.BoxSizer(wx.HORIZONTAL) - - usePowerSizer = wx.GridBagSizer(5,5) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBToggle, (0,1)) - self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOn, (0,2)) - self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOff, (0,3)) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerName = PowerPicker(dialog) - usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) - usePowerSizer.AddGrowableCol(3) - - outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) - - return outerSizer - - def MakeBindString(self): - if self.usePowerRBToggle.GetValue(): - method = "powexecname" - elif self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') - return '' - - return f"{method} {self.usePowerName.GetLabel()}" - - def Serialize(self): - if self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - method = "powexecname" - return { - 'method': method, - 'pname' : self.usePowerName.GetLabel(), - 'picon' : self.usePowerName.IconFilename - } - - def Deserialize(self, init): - method = init.get('method', '') - if method == 'powexectoggleon': - self.usePowerRBOn.SetValue(True) - elif method == 'powexectoggleoff': - self.usePowerRBOff.SetValue(True) - else: - self.usePowerRBToggle.SetValue(True) - if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) - -####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): - def BuildUI(self, dialog): - usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTrayTray = wx.Choice(dialog, -1, - choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', - 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) - self.usePowerFromTrayTray.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) - self.usePowerFromTraySlot.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return usePowerFromTraySizer - - def MakeBindString(self): - choice = self.usePowerFromTrayTray - tray = choice.GetSelection() - - choice = self.usePowerFromTraySlot - slot = choice.GetSelection()+1 - - mode = "slot" - mode2 = '' - if tray > 3: - mode = "tray" - mode2 = f" {tray - 3}" - elif tray == 3: - mode = "alt2slot" - elif tray == 2: - mode = "altslot" - - return f"powexec{mode} {slot}{mode2}" - - def Serialize(self): - return { - 'tray' : self.usePowerFromTrayTray.GetSelection(), - 'slot' : self.usePowerFromTraySlot.GetSelection(), - } - - def Deserialize(self, init): - if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) - if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) - -####### Window Color -class WindowColorCmd(PowerBindCmd): - def BuildUI(self, dialog): - windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) - borderSizer = wx.BoxSizer(wx.VERTICAL) - self.ColorBorder.SetSizer(borderSizer) - self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) - borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) - - windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) - - RGBASizer = wx.FlexGridSizer(3, 4, 5) - - RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) - self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) - self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - windowColorSizer.Add(RGBASizer) - - self.UpdateFromSlider() - - return windowColorSizer - - def MakeBindString(self): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - return f"windowcolor {Rval} {Gval} {Bval} {Aval}" - - def Serialize(self): - return { - 'Rval' : self.RSlider.GetValue(), - 'Gval' : self.GSlider.GetValue(), - 'Bval' : self.BSlider.GetValue(), - 'Aval' : self.ASlider.GetValue(), - } - - def Deserialize(self, init): - self.RSlider.SetValue(init['Rval']) - self.GSlider.SetValue(init['Gval']) - self.BSlider.SetValue(init['Bval']) - self.ASlider.SetValue(init['Aval']) - self.UpdateFromSlider() - - def UpdateFromSlider(self, _ = None): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RReadout.SetValue(Rval) - self.GReadout.SetValue(Gval) - self.BReadout.SetValue(Bval) - self.AReadout.SetValue(Aval) - self.ColorBorder.Refresh() - - def UpdateFromText(self, _ = None): - Rval = self.RReadout.GetValue() - Gval = self.GReadout.GetValue() - Bval = self.BReadout.GetValue() - Aval = self.AReadout.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RSlider.SetValue(Rval) - self.GSlider.SetValue(Gval) - self.BSlider.SetValue(Bval) - self.ASlider.SetValue(Aval) - self.ColorBorder.Refresh() - -####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) - self.CommandChoice.SetSelection(0) - sizer.Add(self.CommandChoice, 0, wx.ALL, 5) - - self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), - value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) - sizer.Add(self.FilePath, 0, wx.ALL, 5) - - return sizer - - def MakeBindString(self): - command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] - return f'{command} "{self.FilePath.GetValue()}"' - - def Serialize(self): - return { - 'command' : self.CommandChoice.GetSelection(), - 'filename' : self.FilePath.GetValue(), - } - - def Deserialize(self, init): - self.CommandChoice.SetSelection(init.get('command', 0)) - self.FilePath.SetValue(init.get('filename', '')) - -####### Window Toggle -class WindowToggleCmd(PowerBindCmd): - def BuildUI(self, dialog): - self.WindowNames = { - 'Actions' : 'actions', - 'Auction House' : 'ah', - 'Badge' : 'badge', - 'Channel Search' : 'chansearch', - 'Chat' : 'chat', - 'Custom Chat 1' : 'chat1', - 'Custom Chat 2' : 'chat2', - 'Custom Chat 3' : 'chat3', - 'Custom Chat 4' : 'chat4', - 'Clues' : 'clue', - 'Combat Numbers' : 'combatnumbers', - 'Contacts' : 'contact', - 'Contact Finder' : 'contactfinder', - 'Costumes' : 'costume', - 'Email' : 'email', - 'Enhancements' : 'enhancements', - 'Friends' : 'friend', - 'Group' : 'group', - 'Help' : 'helpwindow', - 'Incarnate' : 'incarnate', - 'Inspirations' : 'insp', - 'League' : 'league', - 'LFG' : 'lfg', - 'Map' : 'map', - 'Mission' : 'mission', - 'Nav / Compass' : 'nav', - 'Options' : 'options', - 'Pets' : 'pet', - 'Petition' : 'petition', - 'Power Tray' : 'powers', - 'Power List' : 'powerlist', - 'Quit' : 'quit', - 'Recipes' : 'recipe', - 'Salvage' : 'salvage', - 'Search' : 'search', - 'Supergroup' : 'sg', - 'Target' : 'target', - 'Team' : 'team', - 'Tray' : 'tray', - 'Tray1' : 'tray1', - 'Tray2' : 'tray2', - 'Tray3' : 'tray3', - 'Tray4' : 'tray4', - 'Tray5' : 'tray5', - 'Tray6' : 'tray6', - 'Tray7' : 'tray7', - 'Tray8' : 'tray8', - 'Vault' : 'vault', - } - - self.ShortToggleCommands = { - 'Auction House' : 'ah', - 'Chat' : 'chat', - 'Help' : 'helpwindow', - 'Map' : 'map', - 'Nav / Compass' : 'nav', - 'Power Tray' : 'powers', - 'Target' : 'target', - 'Tray' : 'tray', - } - - windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) - windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) - self.windowToggleTray.SetSelection(0) - windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.windowShowRB = wx.RadioButton(dialog, -1, "Show") - self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") - - windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) - - return windowToggleSizer - - def MakeBindString(self): - choice = self.windowToggleTray - index = choice.GetSelection() - windowdesc = choice.GetString(index) - windowname = self.WindowNames[windowdesc] - - if self.windowShowRB.GetValue(): - return 'show ' + windowname - elif self.windowHideRB.GetValue(): - return 'windowhide ' + windowname - else: - if shortcmd := self.ShortToggleCommands.get(windowdesc, None): - return shortcmd - else: - return 'toggle ' + windowname - - - def Serialize(self): - choice = self.windowToggleTray - if self.windowShowRB.GetValue(): - action = "Show" - elif self.windowHideRB.GetValue(): - action = "Hide" - else: - action = "Toggle" - return { - 'window': choice.GetString(choice.GetSelection()), - 'action': action, - } - - def Deserialize(self, init): - choice = self.windowToggleTray - if window := init.get('window', ''): - if isinstance(window, int): - choice.SetSelection(window) - else: - choice.SetSelection(choice.FindString(window)) - - if choice.GetSelection() == wx.NOT_FOUND: - choice.SetSelection(0) - - action = init.get('action', '') - if action == "Show": - self.windowShowRB.SetValue(True) - elif action == "Hide": - self.windowHideRB.SetValue(True) - else: - self.windowToggleRB.SetValue(True) - - -# Must always add to this list when adding a new command class above -menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], - # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, - # but I'm leaving it here to remind myself that we do that. - } - -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/PowerAbortCmd.py b/UI/PowerBinderCommand/PowerAbortCmd.py index 4c02ab7..d667dc8 100644 --- a/UI/PowerBinderCommand/PowerAbortCmd.py +++ b/UI/PowerBinderCommand/PowerAbortCmd.py @@ -1,1800 +1,9 @@ -import wx -import re -import UI -import UI.EmotePicker -from UI.ControlGroup import ControlGroup -from UI.PowerPicker import PowerPicker -from Help import HelpButton -import wx.adv -from wx.adv import BitmapComboBox, EditableListBox -from pathlib import PureWindowsPath -import GameData -import Profile -from Icon import GetIcon - -class PowerBinderDialog(wx.Dialog): - def __init__(self, parent, button, init = {}): - wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) - - self.Page = parent.Page - self.EditDialog = PowerBinderEditDialog(self) - self.Button = button - self.AddStepMenu = self.makeAddStepMenu() - - sizer = wx.BoxSizer(wx.VERTICAL); - self.mainSizer = sizer - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) - AddStepButton = wx.Button(self, -1, 'Add Step') - AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) - AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) - choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) - choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) - sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) - - rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) - - self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) - self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) - self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) - rearrangeCtrl.Add(self.RearrangeList, 1) - - rearrangeButtons = wx.BoxSizer(wx.VERTICAL) - self.DelButton = wx.Button(self, -1, "Delete") - self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) - self.EditButton = wx.Button(self, -1, "Edit") - self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) - self.EditButton.Disable() - upButton = wx.Button(self, -1, "\u25B2") - upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) - downButton = wx.Button(self, -1, "\u25BC") - downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) - rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) - rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) - - sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.BindStringDisplay = wx.TextCtrl(self, -1) - self.BindStringDisplay.Disable() - choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, - wx.ALIGN_CENTER_VERTICAL) - choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) - - sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) - - sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) - - # need to dig around and get the OK button since we show this dialog modelessly now. - okButton = self.FindWindow(self.GetAffirmativeId()) - okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) - - # Wrap everything in a vbox to add some padding - vbox = wx.BoxSizer(wx.VERTICAL); - vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); - - self.SetSizerAndFit(vbox); - self.Layout() - self.Fit() - self.SetFocus() - - # if we are loading from profile, ie, have "init", build the list from it - if init: self.LoadFromData(init) - - def LoadFromData(self, init): - for item in init: - for type, data in item.items(): - commandClass = commandClasses.get(type, None) - if not commandClass: - commandClass = deprecatedCommandClasses.get(type, None) - if not commandClass: - wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") - continue - newCommand = commandClass(self.EditDialog, data) - index = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.SetClientData(index, newCommand) - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) - self.EditDialog.mainSizer.Hide(newCommand.UI) - self.UpdateBindStringDisplay() - - def SaveToData(self): - data = [] - index = 0 - for _ in self.RearrangeList.GetItems(): - # check whether we have an object already attached to this choice - cmdObject = self.RearrangeList.GetClientData(index) - commandClassName = commandRevClasses[type(cmdObject)] - data.append({commandClassName: cmdObject.Serialize()}) - index = index + 1 - return data - - def OnAddStepButton(self, evt): - button = evt.EventObject - if not self.AddStepMenu: - self.AddStepMenu = self.makeAddStepMenu() - button.PopupMenu(self.AddStepMenu) - - - def OnOKButton(self, _): - if self.Button.tgtTxtCtrl: - bindString = self.MakeBindString() - if bindString != self.Button.tgtTxtCtrl.GetValue(): - self.Button.tgtTxtCtrl.SetValue(bindString) - wx.App.Get().Main.Profile.SetModified() - self.Close() - - def OnRearrangeDelete(self, _): - current = self.RearrangeList.GetSelection() - if current == wx.NOT_FOUND: return - - self.RearrangeList.Delete(current) - self.UpdateBindStringDisplay() - - def OnRearrangeUp(self, _): - self.RearrangeList.MoveCurrentUp() - self.UpdateBindStringDisplay() - - def OnRearrangeDown(self, _): - self.RearrangeList.MoveCurrentDown() - self.UpdateBindStringDisplay() - - def OnRearrangeEdit(self, _): - index = self.RearrangeList.GetSelection() - - # check whether we have an object already attached to this choice - cmdObject = None - try: - cmdObject = self.RearrangeList.GetClientData(index) - except Exception: - pass - - if cmdObject: - self.ShowEditDialogFor(cmdObject) - self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) - else: - print("cmdObject was None") - self.UpdateBindStringDisplay() - - # OnAddStepMenu creates a new step and adds it to the rearrangelist - def OnAddStepMenu(self, evt): - menuitem = self.AddStepMenu.FindItemById(evt.GetId()) - chosenName = menuitem.GetItemLabel() - - # make a new command object, attached to the parent dialog - newCommandClass = commandClasses[chosenName] - newCommand = newCommandClass(self.EditDialog) - - # show the edit dialog if this command needs it - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) - if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): - self.EditDialog.mainSizer.Remove(newCommand.UI) - return - - newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.Select(newBindIndex) - self.RearrangeList.SetClientData(newBindIndex, newCommand) - - self.OnListSelect() - self.UpdateBindStringDisplay() - - def OnListSelect(self, _ = None): - selected = self.RearrangeList.GetSelection() - - if selected != wx.NOT_FOUND: - selCommand = self.RearrangeList.GetClientData(selected) - if selCommand.UI: - self.EditButton.Enable() - else: - self.EditButton.Disable() - - def UpdateBindStringDisplay(self): - self.BindStringDisplay.SetValue(self.MakeBindString()) - self.BindStringDisplay.SetToolTip(self.MakeBindString()) - - def MakeBindString(self): - cmdBindStrings = [] - for index in range(self.RearrangeList.GetCount()): - c = self.RearrangeList.GetClientData(index) - if c: cmdBindStrings.append(c.MakeBindString()) - - bindstring = ('$$'.join(cmdBindStrings)) - return bindstring - - def ShowEditDialogFor(self, command): - if not command.UI: return - - self.EditDialog.mainSizer.Show(command.UI) - - self.EditDialog.Layout() - self.EditDialog.Fit() - - self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') - returnval = self.EditDialog.ShowModal() - - self.EditDialog.mainSizer.Hide(command.UI) - - return returnval - - def makeAddStepMenu(self): - - stepMenu = wx.Menu() - - for subname in menuStructure: - submenu = wx.Menu() - stepMenu.AppendSubMenu(submenu, subname) - for classname in menuStructure[subname]: - submenu.Append(wx.ID_ANY, classname) - - stepMenu.Append(wx.ID_ANY, 'Custom Bind') - - return stepMenu - -class PowerBinderButton(wx.BitmapButton): - - def __init__(self, parent, tgtTxtCtrl, init = {}): - wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) - self.Init = init - self.Dialog = None - self.DialogParent = parent - - self.tgtTxtCtrl = tgtTxtCtrl - self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) - self.SetToolTip("Launch PowerBinder") - - def PowerBinderEventHandler(self, _): - self.PowerBinderDialog().Show() - - def LoadFromData(self, data): - self.PowerBinderDialog().LoadFromData(data) - - def SaveToData(self): - return self.PowerBinderDialog().SaveToData() - - def PowerBinderDialog(self): - if not self.Dialog: - self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) - return self.Dialog - - -class PowerBinderEditDialog(wx.Dialog): - def __init__(self, parent): - wx.Dialog.__init__(self, parent, -1, "Edit Step", - style = wx.DEFAULT_DIALOG_STYLE) - - outerSizer = wx.BoxSizer(wx.VERTICAL) - - self.mainSizer = wx.BoxSizer(wx.VERTICAL) - self.mainSizer.SetMinSize([500, 150]) - - self.Page = parent.Page - - self.mainSizer.Add( - self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), - 0, wx.EXPAND|wx.ALL, 10) - - outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) - - self.SetSizerAndFit(outerSizer) - self.Layout() - self.Fit() - -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" - - -####### Away From Keyboard -class AFKCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.Groups = {} - self.AttributeTable = { - 'Base' : { - 'Current Hit Points' : 'NT H', - 'Max Hit Points' : 'X H', - 'Current Endurance' : 'T E', - 'Max Endurance' : 'X EN', - 'Regeneration Rate' : 'N RAT', - 'Recovery Rate' : 'Y RA', - 'Endurance Consumption' : 'SU', - 'ToHit Bonus' : 'T B', - 'Accuracy Bonus' : 'CC', - 'Last Hit Chance' : 'T C', - 'Damage Bonus' : 'DA', - 'Healing Bonus' : 'NG B', - 'Recharge Time Bonus' : 'ME B', - 'Endurance Discount' : 'CE DIS', - 'Stealth Radius (PvP)' : 'PVP', - 'Stealth Radius (PvE)' : 'PVE', - 'Perception Radius' : 'RC', - 'Range Bonus' : 'GE B', - 'Threat Level' : 'AT L', - 'Experience to Next Level' : 'XT', - 'Experience Debt' : 'XP', - 'Influence / Infamy' : 'INF', - 'Inherent' : 'NH', - }, - 'Movement Speed' : { - 'Flying Speed' : 'FL', - 'Jumping Speed' : 'PI', - 'Max Jump Height' : 'X J', - 'Run Speed' : 'RU', - }, - 'Damage Resistance' : { - 'Smashing Resistance' : 'G R', - 'Lethal Resistance' : 'L R', - 'Fire Resistance' : 'RE R', - 'Cold Resistance' : 'COLD R', - 'Energy Resistance' : 'DamageType[4]', - 'Negative Energy Resistance' : 'GY R', - 'Psyonic Resistance' : 'NIC R', - 'Toxic Resistance' : 'XIC R', - }, - 'Defense' : { - 'Base Defense' : 'BAS', - 'Ranged Defense' : 'ED', - 'Melee Defense' : 'MEL', - 'AoE Defense' : '2', - 'Smashing Defense' : '3', - 'Lethal Defense' : '4', - 'Fire Defense' : '5', - 'Cold Defense' : '6', - 'Energy Defense' : '7', - 'Negative Energy Defense' : '8', - 'Psionic Defense' : '9', - 'Toxic Defense' : '1', - }, - 'Debuff Resistance' : { - 'Regeneration Resistance' : 'ON R', - 'Recovery Resistance' : 'RY R', - 'To Hit Resistance' : 'IT R', - 'Defense Resistance' : 'NSE RES', - }, - 'Status Effect Protection' : { - 'Hold Protection' : 'D P', - 'Immobilize Protection' : 'LIZE P', - 'Stun Protection' : 'N P', - 'Sleep Protection' : 'P P', - 'Knockback Protection' : 'K P', - 'Confuse Protection' : 'SE P', - 'Terrorize Protection' : 'ZE P', - 'Repel Protection' : 'EL P', - 'Teleport Protection' : 'T P', - }, - 'Status Effect Resistance' : { - 'Hold Resistance' : 'D R', - 'Immobilize Resistance' : 'LIZE R', - 'Stun Resistance' : 'N R', - 'Sleep Resistance' : 'P R', - 'Knockback Resistance' : 'K R', - 'Confuse Resistance' : 'SE R', - 'Terrorize Resistance' : 'ZE R', - 'Placate Resistance' : 'TE R', - 'Taunt Resistance' : 'NT R', - }, - 'Miscellaneous' : { - 'Level Shift' : 'L S', - }, - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.AttributeMenu = wx.Menu() - for group, controls in self.AttributeTable.items(): - submenu = wx.Menu() - self.AttributeMenu.AppendSubMenu(submenu, group) - for cb in controls: - submenu.Append(wx.ID_ANY, cb) - - self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) - - self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) - groupSizer.Add(self.editbox) - - newButton = self.editbox.GetNewButton() - newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) - - return groupSizer - - def MakeBindString(self): - map = {} - bindstrings = [] - for _, controls in self.AttributeTable.items(): - for cb, data in controls.items(): - map[cb] = data - - for string in self.editbox.GetStrings(): - if string: - bindstrings.append(f'monitorattribute {map[string]}') - - return '$$'.join(bindstrings) - - def Serialize(self): - return { - 'attributes' : self.editbox.GetStrings() - } - - def Deserialize(self, init): - self.editbox.SetStrings(init.get('attributes', [])) - - def OnNewButton(self, evt): - evt.GetEventObject().PopupMenu(self.AttributeMenu) - - def OnMenuItem(self, evt): - menuitem = evt.EventObject.FindItemById(evt.GetId()) - existingstrings = self.editbox.GetStrings() - existingstrings.append(menuitem.GetItemLabel()) - self.editbox.SetStrings(existingstrings) - -####### Auto Power -class AutoPowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) - autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.autoPowerName = PowerPicker(dialog) - autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) - - return autoPowerSizer - - def MakeBindString(self): - return f"powexecauto {self.autoPowerName.GetLabel()}" - - def Serialize(self): - return { - 'pname' : self.autoPowerName.GetLabel(), - 'picon' : self.autoPowerName.IconFilename - } - - def Deserialize(self, init): - if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.buffDisplayMap = { - 'Status Window' : { - 'Hide Auto' : 1, - 'Hide Toggles' : 2, - 'No Blinking' : 4, - 'No Stacking' : 8, - 'Numeric Stacking' : 16, - 'Hide Buff Numbers' : 32, - 'Stop Sending Buffs' : 64, - }, - 'Group Window' : { - 'Hide Auto' : 256, - 'Hide Toggles' : 512, - 'No Blinking' : 1024, - 'No Stacking' : 2048, - 'Numeric Stacking' : 4096, - 'Hide Buff Numbers' : 8192, - 'Stop Sending Buffs' : 16384, - }, - 'Pet Window' : { - 'Hide Auto' : 65536, - 'Hide Toggles' : 131072, - 'No Blinking' : 262144, - 'No Stacking' : 524288, - 'Numeric Stacking' : 1048576, - 'Hide Buff Numbers' : 2097152, - 'Stop Sending Buffs' : 4194304, - }, - } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - for group, controls in self.buffDisplayMap.items(): - self.Groups[group] = ControlGroup(dialog, self.Page, label = group) - groupid = self.Groups[group].GetStaticBox().GetId() - for cb, data in controls.items(): - self.Groups[group].AddControl( - ctlType = 'checkbox', - ctlName = f"{groupid}_{group}_{cb}", - label = cb, - data = data, - ) - - groupSizer.Add(self.Groups[group]) - - return groupSizer - - def CalculateValue(self): - page = wx.App.Get().Main.Profile.CustomBinds - - total = 0 - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] - if checkbox.IsChecked(): - total = total + checkbox.Data - return total - - def MakeBindString(self): - return f"optionset buffsettings {self.CalculateValue()}" - - def Serialize(self): - return { 'value' : self.CalculateValue() } - - def Deserialize(self, init): - value = init.get('value', 0) - - value = value or 0 # in case we had for some reason 'None' stashed in the init values - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] - checkbox.SetValue( checkbox.Data & value ) - -####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - chatCommandSizer = wx.GridBagSizer(5, 5) - self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") - chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) - # row 1 - self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) - self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) - self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) - # row 2 - self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) - self.chatCommandDuration.SetRange(1, 20) - self.chatCommandDuration.SetValue(7) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandDuration, (2,1)) - self.chatCommandChatSize = wx.Choice(dialog, -1, - choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) - self.chatCommandChatSize.SetSelection(5) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) - self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) - self.chatCommandChannel.SetSelection(0) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChannel, (2,5)) - # row 3 - self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") - chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) - self.chatCommandMessage = wx.TextCtrl(dialog, -1) - self.chatCommandMessage.SetHint('Chat Command Text') - chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) - - return chatCommandSizer - - def MakeBindString(self): - duration = self.chatCommandDuration.GetValue() - - choice = self.chatCommandChatSize - index = choice.GetSelection() - size = choice.GetString(index) - - duration = f"" if duration != 7 else "" - size = f"" if size != "1" else "" - - bdcolor = fgcolor = bgcolor = '' - if self.chatCommandUseColorsCB.IsChecked(): - bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - - bdcolor = f"" - fgcolor = f"" - bgcolor = f"" - - beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' - text = self.chatCommandMessage.GetValue() - - choice = self.chatCommandChannel - index = choice.GetSelection() - channel = choice.GetString(index) - - return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" - - def Serialize(self): - return { - 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), - 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), - 'channel' : self.chatCommandChannel .GetSelection(), - 'size' : self.chatCommandChatSize.GetSelection(), - 'duration' : self.chatCommandDuration.GetValue(), - 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'text' : self.chatCommandMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) - if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) - if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) - if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) - if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) - if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) - if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) - if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) - if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - - -####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): - def BuildUI(self, dialog): - chatCommandGlobalSizer = wx.GridBagSizer(5,5) - - self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") - chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) - - self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalChannel.SetHint("Channel") - chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) - - self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') - chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) - - chatCommandGlobalSizer.AddGrowableCol(1) - - return chatCommandGlobalSizer - - def MakeBindString(self): - useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() - channel = self.chatCommandGlobalChannel.GetValue() - message = self.chatCommandGlobalMessage.GetValue() - - preface = "beginchat /" if useBeginchat else "" - - return f'{preface}send "{channel}" {message}' - - def Serialize(self): - return { - 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), - 'channel' : self.chatCommandGlobalChannel.GetValue(), - 'message' : self.chatCommandGlobalMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) - if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) - if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) - -#######Costume Change -class CostumeChangeCmd(PowerBindCmd): - def BuildUI(self, dialog): - costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeCostume = wx.Choice(dialog, -1, - choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) - self.costumeChangeCostume.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeEmote = wx.Choice(dialog, -1, - choices = GameData.Emotes['costumechange']) - self.costumeChangeEmote.Insert("- None -", 0) - self.costumeChangeEmote.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return costumeChangeSizer - - def MakeBindString(self): - costumeNumber = self.costumeChangeCostume.GetSelection() - costumeEmote = self.costumeChangeEmote.GetSelection() - - if costumeEmote: # None, or 0 == "- None -" - ccCmd = 'cce' - emoteName = self.costumeChangeEmote.GetString(costumeEmote) - emoteName = " CC" + emoteName.replace(" ","") - else: - ccCmd = 'cc' - emoteName = '' - - return f"{ccCmd} {costumeNumber}{emoteName}" - - def Serialize(self): - return{ - 'costumeNumber': self.costumeChangeCostume.GetSelection(), - 'costumeEmote' : self.costumeChangeEmote.GetSelection(), - } - - def Deserialize(self, init): - if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) - if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) - -####### Movement Command -class MovementCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - self.plusbutton.SetValue(True) - - self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.commandchoice = wx.Choice(dialog, choices = [ - "forward", "left", "right", "backward", "up", "down", - "turnleft", "turnright", "first", "autorun", "clicktomove", - ],) - sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) - self.commandchoice.SetSelection(0) - - self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - pre = post = '' - if self.plusbutton.GetValue() : pre = "+" - elif self.plusplusbutton.GetValue() : pre = "++" - elif self.minusbutton.GetValue() : pre = "-" - elif self.zerobutton.GetValue() : post = " 0" - elif self.onebutton.GetValue() : post = " 1" - - command = self.commandchoice.GetString(self.commandchoice.GetSelection()) - - return f"{pre}{command}{post}" - - def Serialize(self): - mod = '' - if self.plusbutton.GetValue() : mod = "plus" - elif self.plusplusbutton.GetValue() : mod = "plusplus" - elif self.minusbutton.GetValue() : mod = "minus" - elif self.zerobutton.GetValue() : mod = "zero" - elif self.onebutton.GetValue() : mod = "one" - - return { - 'mod' : mod, - 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), - } - - def Deserialize(self, init): - mod = init.get('mod', 'plus') - - if mod == 'plus' : self.plusbutton.SetValue(True) - elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) - elif mod == 'minus' : self.minusbutton.SetValue(True) - elif mod == 'zero' : self.zerobutton.SetValue(True) - elif mod == 'one' : self.onebutton.SetValue(True) - - self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) - -####### Graphics Command -class GraphicsCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.FlexGridSizer(2) - - self.visscalecb = wx.CheckBox(dialog, label = "visscale") - sizer.Add(self.visscalecb) - self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) - sizer.Add(self.visscalesc) - - self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") - sizer.Add(self.dofweightcb) - self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) - sizer.Add(self.dofweightsc) - - self.fsaacb = wx.CheckBox(dialog, label = "fsaa") - sizer.Add(self.fsaacb) - self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) - self.fsaach.SetSelection(0) - sizer.Add(self.fsaach) - - self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") - sizer.Add(self.bloomscalecb) - self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) - self.bloomscalech.SetSelection(0) - sizer.Add(self.bloomscalech) - - self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") - sizer.Add(self.bloomweightcb) - self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) - sizer.Add(self.bloomweightsc) - - self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") - sizer.Add(self.lodbiascb) - self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) - sizer.Add(self.lodbiassc) - - self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") - sizer.Add(self.renderscalecb) - self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) - sizer.Add(self.renderscalesc) - - return sizer - - def MakeBindString(self): - # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. - bindstrings = [] - if self.visscalecb.IsChecked(): - bindstrings.append("visscale " + str(self.visscalesc.GetValue())) - if self.dofweightcb.IsChecked(): - bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) - if self.fsaacb.IsChecked(): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bindstrings.append("fsaa " + fsaavalue) - if self.bloomscalecb.IsChecked(): - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - bindstrings.append("bloomscale " + bloomscalevalue) - if self.bloomweightcb.IsChecked(): - bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) - if self.lodbiascb.IsChecked(): - bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) - if self.renderscalecb.IsChecked(): - bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) - - return '$$'.join(bindstrings) - - def Serialize(self): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - return { - 'visscalecb' : self.visscalecb.IsChecked(), - 'visscalesc' : self.visscalesc.GetValue(), - 'dofweightcb' : self.dofweightcb.IsChecked(), - 'dofweightsc' : self.dofweightsc.GetValue(), - 'fsaacb' : self.fsaacb.IsChecked(), - 'fsaach' : fsaavalue, - 'bloomscalecb' : self.bloomscalecb.IsChecked(), - 'bloomscalech' : bloomscalevalue, - 'bloomweightcb' : self.bloomweightcb.IsChecked(), - 'bloomweightsc' : self.bloomweightsc.GetValue(), - 'lodbiascb' : self.lodbiascb.IsChecked(), - 'lodbiassc' : self.lodbiassc.GetValue(), - 'renderscalecb' : self.renderscalecb.IsChecked(), - 'renderscalesc' : self.renderscalesc.GetValue(), - } - - def Deserialize(self, init): - self.visscalecb.SetValue(init.get('visscalecb', False)) - self.visscalesc.SetValue(init.get('visscalesc', 1.0)) - self.dofweightcb.SetValue(init.get('dofweightcb', False)) - self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) - self.fsaacb.SetValue(init.get('fsaacb', False)) - self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) - self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) - self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) - self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) - self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) - self.lodbiascb.SetValue(init.get('lodbiascb', False)) - self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) - self.renderscalecb.SetValue(init.get('renderscalecb', False)) - self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) - -####### Custom Bind -class CustomBindCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.customBindName = wx.TextCtrl(dialog, -1) - self.customBindName.SetHint('Custom Bind Text') - sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - return self.customBindName.GetValue() - - def Serialize(self): - return { 'customBindName': self.customBindName.GetValue() } - - def Deserialize(self,init): - if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) - -####### Emote -class EmoteCmd(PowerBindCmd): - def BuildUI(self, dialog): - emoteSizer = wx.BoxSizer(wx.HORIZONTAL) - self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") - emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - self.emoteName = wx.Button(dialog, -1, "...") - self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) - emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) - - return emoteSizer - - def MakeBindString(self): - displayedEmoteName = self.emoteName.GetLabel() - actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] - - return actualEmotePayload - - def Serialize(self): - return {'emoteName': self.emoteName.GetLabel()} - - def Deserialize(self, init): - if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) - -####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): - def BuildUI(self, dialog): - mainSizer = wx.BoxSizer(wx.VERTICAL) - - lbSizer = wx.BoxSizer(wx.HORIZONTAL) - lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") - lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - profiles = Profile.GetAllProfileBindsDirs() - - self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) - lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) - - mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") - self.lbResetCB.SetValue(True) - - mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - return mainSizer - - def MakeBindString(self): - - # If the specified binds directory disappeared between runs, we'd crash, so handle that. - if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' - - config = wx.ConfigBase.Get() - if config.Exists('GameBindPath'): - bindpath = config.Read('GameBindPath') - else: - bindpath = config.Read('BindPath') - - reset = "" - if self.lbResetCB.GetValue(): - reset = "keybind_reset$$" - - resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' - return reset + 'bindloadfile ' + str(resetfilepath) - - def Serialize(self): - return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), - 'ResetKeybinds' : self.lbResetCB.GetValue(), - } - - def Deserialize(self, init): - if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) - self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) +from UI.PowerBinderCommand import PowerBinderCommand ####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' - -####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' - -####### SG Mode -class SGModeCmd(PowerBindCmd): - def BuildUI(self, dialog): - sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) - sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") - self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") - - sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) - - return sgmodeSizer - - def MakeBindString(self): - if self.sgmodeOnRB.GetValue(): - return 'sgmodeset 1' - elif self.sgmodeOffRB.GetValue(): - return 'sgmodeset 0' - else: - return 'sgmode' - - def Serialize(self): - if self.sgmodeOnRB.GetValue(): - val = "On" - elif self.sgmodeOffRB.GetValue(): - val = "Off" - else: - val = "Toggle" - - return {"value" : val} - - def Deserialize(self, init): - val = init.get('value', '') - if val == "On": - self.sgmodeOnRB.SetValue(True) - elif val == "Off": - self.sgmodeOffRB.SetValue(True) - else: - self.sgmodeToggleRB.SetValue(True) - -####### Target Custom -class TargetCustomCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetCustomSizer = wx.GridBagSizer(5,5) - targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), - flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) - self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetCustomModeChoice.SetSelection(0) - targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) - self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) - self.targetCustomOptionalName.SetHint("Optional name to match") - targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) - self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") - targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) - self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") - targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) - self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") - targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) - self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") - targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) - self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") - targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) - self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") - targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) - self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") - targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) - self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") - targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) - - targetCustomSizer.AddGrowableCol(2) - - return targetCustomSizer - - def MakeBindString(self): - choice = self.targetCustomModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - targetCommand = "targetcustom" + mode.lower() - - enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" - friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" - defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" - alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" - mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" - notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" - base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" - notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" - - name = self.targetCustomOptionalName.GetValue() - - return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" - - def Serialize(self): - return { - 'mode' : self.targetCustomModeChoice.GetSelection(), - 'enemy' : self.targetCustomCBEnemies. IsChecked(), - 'friend' : self.targetCustomCBFriends. IsChecked(), - 'defeated' : self.targetCustomCBDefeated. IsChecked(), - 'alive' : self.targetCustomCBAlive. IsChecked(), - 'mypet' : self.targetCustomCBMyPets. IsChecked(), - 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), - 'base' : self.targetCustomCBBaseItems. IsChecked(), - 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), - 'name' : self.targetCustomOptionalName.GetValue(), - } - - def Deserialize(self, init): - if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) - if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) - if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) - if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) - if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) - if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) - if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) - if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) - if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) - if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - - -####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) - targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetEnemyModeChoice.SetSelection(0) - targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetEnemySizer - - def MakeBindString(self): - choice = self.targetEnemyModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetenemy" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetEnemyModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) - -####### Target Friend -class TargetFriendCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) - targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetFriendModeChoice.SetSelection(0) - targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetFriendSizer - - def MakeBindString(self): - choice = self.targetFriendModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetfriend" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetFriendModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) - -####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): - def BuildUI(self, dialog): - teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], - style=wx.ALIGN_CENTER_VERTICAL) - self.teamPetSelectNumber.SetSelection(0) - teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) - - return teamPetSelectSizer +class PowerAbortCmd(PowerBinderCommand): + Name = "Power Abort" + Menu = "Powers" def MakeBindString(self): - teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' - targetNumber = self.teamPetSelectNumber.GetSelection()+1 - - return f"{teamOrPet}select {targetNumber}" - - def Serialize(self): - return { - 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', - 'targetNum': self.teamPetSelectNumber.GetSelection(), - } - - def Deserialize(self, init): - ToP = init.get('teamOrPet', '') - if ToP == 'pet': - self.teamPetSelectPetRB.SetValue(True) - else: - self.teamPetSelectTeamRB.SetValue(True) - if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) - -####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' - -####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) - for _, types in GameData.Inspirations.items(): - for _, info in types.items(): - for insp in info['tiers']: - name = re.sub(' ', '', str(insp)) - icon = GetIcon(f'Inspirations/{name}') - self.useInspByNameModeChoice.Append(insp, icon) - self.useInspByNameModeChoice.SetSelection(0) - useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) - - return useInspByNameSizer - - def MakeBindString(self): - choice = self.useInspByNameModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "inspexecname " + mode.lower() - - def GetAllInsps(self): - Insplist = [] - for _, info in GameData.Inspirations.items(): - for insp in info['tiers']: - Insplist.append(insp) - Insplist.append("---") - Insplist.pop(-1) # snip the terminal "---" - - return Insplist - - def Serialize(self): - return { 'insp' : self.useInspByNameModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) - -####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnRow.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) - self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnCol.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) - - return useInspRowColumnSizer - - def MakeBindString(self): - row = self.useInspRowColumnRow.GetSelection()+1 - col = self.useInspRowColumnCol.GetSelection()+1 - - return f"inspexectray {col} {row}" - - def Serialize(self): - return { - 'col' : self.useInspRowColumnCol.GetSelection(), - 'row' : self.useInspRowColumnRow.GetSelection(), - } - - def Deserialize(self, init): - if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) - if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) - -####### Use Power -class UsePowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - outerSizer = wx.BoxSizer(wx.HORIZONTAL) - - usePowerSizer = wx.GridBagSizer(5,5) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBToggle, (0,1)) - self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOn, (0,2)) - self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOff, (0,3)) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerName = PowerPicker(dialog) - usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) - usePowerSizer.AddGrowableCol(3) - - outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) - - return outerSizer - - def MakeBindString(self): - if self.usePowerRBToggle.GetValue(): - method = "powexecname" - elif self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') - return '' - - return f"{method} {self.usePowerName.GetLabel()}" - - def Serialize(self): - if self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - method = "powexecname" - return { - 'method': method, - 'pname' : self.usePowerName.GetLabel(), - 'picon' : self.usePowerName.IconFilename - } - - def Deserialize(self, init): - method = init.get('method', '') - if method == 'powexectoggleon': - self.usePowerRBOn.SetValue(True) - elif method == 'powexectoggleoff': - self.usePowerRBOff.SetValue(True) - else: - self.usePowerRBToggle.SetValue(True) - if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) - -####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): - def BuildUI(self, dialog): - usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTrayTray = wx.Choice(dialog, -1, - choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', - 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) - self.usePowerFromTrayTray.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) - self.usePowerFromTraySlot.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return usePowerFromTraySizer - - def MakeBindString(self): - choice = self.usePowerFromTrayTray - tray = choice.GetSelection() - - choice = self.usePowerFromTraySlot - slot = choice.GetSelection()+1 - - mode = "slot" - mode2 = '' - if tray > 3: - mode = "tray" - mode2 = f" {tray - 3}" - elif tray == 3: - mode = "alt2slot" - elif tray == 2: - mode = "altslot" - - return f"powexec{mode} {slot}{mode2}" - - def Serialize(self): - return { - 'tray' : self.usePowerFromTrayTray.GetSelection(), - 'slot' : self.usePowerFromTraySlot.GetSelection(), - } - - def Deserialize(self, init): - if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) - if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) - -####### Window Color -class WindowColorCmd(PowerBindCmd): - def BuildUI(self, dialog): - windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) - borderSizer = wx.BoxSizer(wx.VERTICAL) - self.ColorBorder.SetSizer(borderSizer) - self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) - borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) - - windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) - - RGBASizer = wx.FlexGridSizer(3, 4, 5) - - RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) - self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) - self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - windowColorSizer.Add(RGBASizer) - - self.UpdateFromSlider() - - return windowColorSizer - - def MakeBindString(self): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - return f"windowcolor {Rval} {Gval} {Bval} {Aval}" - - def Serialize(self): - return { - 'Rval' : self.RSlider.GetValue(), - 'Gval' : self.GSlider.GetValue(), - 'Bval' : self.BSlider.GetValue(), - 'Aval' : self.ASlider.GetValue(), - } - - def Deserialize(self, init): - self.RSlider.SetValue(init['Rval']) - self.GSlider.SetValue(init['Gval']) - self.BSlider.SetValue(init['Bval']) - self.ASlider.SetValue(init['Aval']) - self.UpdateFromSlider() - - def UpdateFromSlider(self, _ = None): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RReadout.SetValue(Rval) - self.GReadout.SetValue(Gval) - self.BReadout.SetValue(Bval) - self.AReadout.SetValue(Aval) - self.ColorBorder.Refresh() - - def UpdateFromText(self, _ = None): - Rval = self.RReadout.GetValue() - Gval = self.GReadout.GetValue() - Bval = self.BReadout.GetValue() - Aval = self.AReadout.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RSlider.SetValue(Rval) - self.GSlider.SetValue(Gval) - self.BSlider.SetValue(Bval) - self.ASlider.SetValue(Aval) - self.ColorBorder.Refresh() - -####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) - self.CommandChoice.SetSelection(0) - sizer.Add(self.CommandChoice, 0, wx.ALL, 5) - - self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), - value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) - sizer.Add(self.FilePath, 0, wx.ALL, 5) - - return sizer - - def MakeBindString(self): - command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] - return f'{command} "{self.FilePath.GetValue()}"' - - def Serialize(self): - return { - 'command' : self.CommandChoice.GetSelection(), - 'filename' : self.FilePath.GetValue(), - } - - def Deserialize(self, init): - self.CommandChoice.SetSelection(init.get('command', 0)) - self.FilePath.SetValue(init.get('filename', '')) - -####### Window Toggle -class WindowToggleCmd(PowerBindCmd): - def BuildUI(self, dialog): - self.WindowNames = { - 'Actions' : 'actions', - 'Auction House' : 'ah', - 'Badge' : 'badge', - 'Channel Search' : 'chansearch', - 'Chat' : 'chat', - 'Custom Chat 1' : 'chat1', - 'Custom Chat 2' : 'chat2', - 'Custom Chat 3' : 'chat3', - 'Custom Chat 4' : 'chat4', - 'Clues' : 'clue', - 'Combat Numbers' : 'combatnumbers', - 'Contacts' : 'contact', - 'Contact Finder' : 'contactfinder', - 'Costumes' : 'costume', - 'Email' : 'email', - 'Enhancements' : 'enhancements', - 'Friends' : 'friend', - 'Group' : 'group', - 'Help' : 'helpwindow', - 'Incarnate' : 'incarnate', - 'Inspirations' : 'insp', - 'League' : 'league', - 'LFG' : 'lfg', - 'Map' : 'map', - 'Mission' : 'mission', - 'Nav / Compass' : 'nav', - 'Options' : 'options', - 'Pets' : 'pet', - 'Petition' : 'petition', - 'Power Tray' : 'powers', - 'Power List' : 'powerlist', - 'Quit' : 'quit', - 'Recipes' : 'recipe', - 'Salvage' : 'salvage', - 'Search' : 'search', - 'Supergroup' : 'sg', - 'Target' : 'target', - 'Team' : 'team', - 'Tray' : 'tray', - 'Tray1' : 'tray1', - 'Tray2' : 'tray2', - 'Tray3' : 'tray3', - 'Tray4' : 'tray4', - 'Tray5' : 'tray5', - 'Tray6' : 'tray6', - 'Tray7' : 'tray7', - 'Tray8' : 'tray8', - 'Vault' : 'vault', - } - - self.ShortToggleCommands = { - 'Auction House' : 'ah', - 'Chat' : 'chat', - 'Help' : 'helpwindow', - 'Map' : 'map', - 'Nav / Compass' : 'nav', - 'Power Tray' : 'powers', - 'Target' : 'target', - 'Tray' : 'tray', - } - - windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) - windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) - self.windowToggleTray.SetSelection(0) - windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.windowShowRB = wx.RadioButton(dialog, -1, "Show") - self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") - - windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) - - return windowToggleSizer - - def MakeBindString(self): - choice = self.windowToggleTray - index = choice.GetSelection() - windowdesc = choice.GetString(index) - windowname = self.WindowNames[windowdesc] - - if self.windowShowRB.GetValue(): - return 'show ' + windowname - elif self.windowHideRB.GetValue(): - return 'windowhide ' + windowname - else: - if shortcmd := self.ShortToggleCommands.get(windowdesc, None): - return shortcmd - else: - return 'toggle ' + windowname - - - def Serialize(self): - choice = self.windowToggleTray - if self.windowShowRB.GetValue(): - action = "Show" - elif self.windowHideRB.GetValue(): - action = "Hide" - else: - action = "Toggle" - return { - 'window': choice.GetString(choice.GetSelection()), - 'action': action, - } - - def Deserialize(self, init): - choice = self.windowToggleTray - if window := init.get('window', ''): - if isinstance(window, int): - choice.SetSelection(window) - else: - choice.SetSelection(choice.FindString(window)) - - if choice.GetSelection() == wx.NOT_FOUND: - choice.SetSelection(0) - - action = init.get('action', '') - if action == "Show": - self.windowShowRB.SetValue(True) - elif action == "Hide": - self.windowHideRB.SetValue(True) - else: - self.windowToggleRB.SetValue(True) - - -# Must always add to this list when adding a new command class above -menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], - # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, - # but I'm leaving it here to remind myself that we do that. - } - -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} + return 'powexecabort' diff --git a/UI/PowerBinderCommand/PowerUnqueueCmd.py b/UI/PowerBinderCommand/PowerUnqueueCmd.py index 4c02ab7..2c84bd6 100644 --- a/UI/PowerBinderCommand/PowerUnqueueCmd.py +++ b/UI/PowerBinderCommand/PowerUnqueueCmd.py @@ -1,1800 +1,9 @@ -import wx -import re -import UI -import UI.EmotePicker -from UI.ControlGroup import ControlGroup -from UI.PowerPicker import PowerPicker -from Help import HelpButton -import wx.adv -from wx.adv import BitmapComboBox, EditableListBox -from pathlib import PureWindowsPath -import GameData -import Profile -from Icon import GetIcon - -class PowerBinderDialog(wx.Dialog): - def __init__(self, parent, button, init = {}): - wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) - - self.Page = parent.Page - self.EditDialog = PowerBinderEditDialog(self) - self.Button = button - self.AddStepMenu = self.makeAddStepMenu() - - sizer = wx.BoxSizer(wx.VERTICAL); - self.mainSizer = sizer - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) - AddStepButton = wx.Button(self, -1, 'Add Step') - AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) - AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) - choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) - choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) - sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) - - rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) - - self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) - self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) - self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) - rearrangeCtrl.Add(self.RearrangeList, 1) - - rearrangeButtons = wx.BoxSizer(wx.VERTICAL) - self.DelButton = wx.Button(self, -1, "Delete") - self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) - self.EditButton = wx.Button(self, -1, "Edit") - self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) - self.EditButton.Disable() - upButton = wx.Button(self, -1, "\u25B2") - upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) - downButton = wx.Button(self, -1, "\u25BC") - downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) - rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) - rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) - - sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.BindStringDisplay = wx.TextCtrl(self, -1) - self.BindStringDisplay.Disable() - choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, - wx.ALIGN_CENTER_VERTICAL) - choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) - - sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) - - sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) - - # need to dig around and get the OK button since we show this dialog modelessly now. - okButton = self.FindWindow(self.GetAffirmativeId()) - okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) - - # Wrap everything in a vbox to add some padding - vbox = wx.BoxSizer(wx.VERTICAL); - vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); - - self.SetSizerAndFit(vbox); - self.Layout() - self.Fit() - self.SetFocus() - - # if we are loading from profile, ie, have "init", build the list from it - if init: self.LoadFromData(init) - - def LoadFromData(self, init): - for item in init: - for type, data in item.items(): - commandClass = commandClasses.get(type, None) - if not commandClass: - commandClass = deprecatedCommandClasses.get(type, None) - if not commandClass: - wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") - continue - newCommand = commandClass(self.EditDialog, data) - index = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.SetClientData(index, newCommand) - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) - self.EditDialog.mainSizer.Hide(newCommand.UI) - self.UpdateBindStringDisplay() - - def SaveToData(self): - data = [] - index = 0 - for _ in self.RearrangeList.GetItems(): - # check whether we have an object already attached to this choice - cmdObject = self.RearrangeList.GetClientData(index) - commandClassName = commandRevClasses[type(cmdObject)] - data.append({commandClassName: cmdObject.Serialize()}) - index = index + 1 - return data - - def OnAddStepButton(self, evt): - button = evt.EventObject - if not self.AddStepMenu: - self.AddStepMenu = self.makeAddStepMenu() - button.PopupMenu(self.AddStepMenu) - - - def OnOKButton(self, _): - if self.Button.tgtTxtCtrl: - bindString = self.MakeBindString() - if bindString != self.Button.tgtTxtCtrl.GetValue(): - self.Button.tgtTxtCtrl.SetValue(bindString) - wx.App.Get().Main.Profile.SetModified() - self.Close() - - def OnRearrangeDelete(self, _): - current = self.RearrangeList.GetSelection() - if current == wx.NOT_FOUND: return - - self.RearrangeList.Delete(current) - self.UpdateBindStringDisplay() - - def OnRearrangeUp(self, _): - self.RearrangeList.MoveCurrentUp() - self.UpdateBindStringDisplay() - - def OnRearrangeDown(self, _): - self.RearrangeList.MoveCurrentDown() - self.UpdateBindStringDisplay() - - def OnRearrangeEdit(self, _): - index = self.RearrangeList.GetSelection() - - # check whether we have an object already attached to this choice - cmdObject = None - try: - cmdObject = self.RearrangeList.GetClientData(index) - except Exception: - pass - - if cmdObject: - self.ShowEditDialogFor(cmdObject) - self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) - else: - print("cmdObject was None") - self.UpdateBindStringDisplay() - - # OnAddStepMenu creates a new step and adds it to the rearrangelist - def OnAddStepMenu(self, evt): - menuitem = self.AddStepMenu.FindItemById(evt.GetId()) - chosenName = menuitem.GetItemLabel() - - # make a new command object, attached to the parent dialog - newCommandClass = commandClasses[chosenName] - newCommand = newCommandClass(self.EditDialog) - - # show the edit dialog if this command needs it - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) - if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): - self.EditDialog.mainSizer.Remove(newCommand.UI) - return - - newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.Select(newBindIndex) - self.RearrangeList.SetClientData(newBindIndex, newCommand) - - self.OnListSelect() - self.UpdateBindStringDisplay() - - def OnListSelect(self, _ = None): - selected = self.RearrangeList.GetSelection() - - if selected != wx.NOT_FOUND: - selCommand = self.RearrangeList.GetClientData(selected) - if selCommand.UI: - self.EditButton.Enable() - else: - self.EditButton.Disable() - - def UpdateBindStringDisplay(self): - self.BindStringDisplay.SetValue(self.MakeBindString()) - self.BindStringDisplay.SetToolTip(self.MakeBindString()) - - def MakeBindString(self): - cmdBindStrings = [] - for index in range(self.RearrangeList.GetCount()): - c = self.RearrangeList.GetClientData(index) - if c: cmdBindStrings.append(c.MakeBindString()) - - bindstring = ('$$'.join(cmdBindStrings)) - return bindstring - - def ShowEditDialogFor(self, command): - if not command.UI: return - - self.EditDialog.mainSizer.Show(command.UI) - - self.EditDialog.Layout() - self.EditDialog.Fit() - - self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') - returnval = self.EditDialog.ShowModal() - - self.EditDialog.mainSizer.Hide(command.UI) - - return returnval - - def makeAddStepMenu(self): - - stepMenu = wx.Menu() - - for subname in menuStructure: - submenu = wx.Menu() - stepMenu.AppendSubMenu(submenu, subname) - for classname in menuStructure[subname]: - submenu.Append(wx.ID_ANY, classname) - - stepMenu.Append(wx.ID_ANY, 'Custom Bind') - - return stepMenu - -class PowerBinderButton(wx.BitmapButton): - - def __init__(self, parent, tgtTxtCtrl, init = {}): - wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) - self.Init = init - self.Dialog = None - self.DialogParent = parent - - self.tgtTxtCtrl = tgtTxtCtrl - self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) - self.SetToolTip("Launch PowerBinder") - - def PowerBinderEventHandler(self, _): - self.PowerBinderDialog().Show() - - def LoadFromData(self, data): - self.PowerBinderDialog().LoadFromData(data) - - def SaveToData(self): - return self.PowerBinderDialog().SaveToData() - - def PowerBinderDialog(self): - if not self.Dialog: - self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) - return self.Dialog - - -class PowerBinderEditDialog(wx.Dialog): - def __init__(self, parent): - wx.Dialog.__init__(self, parent, -1, "Edit Step", - style = wx.DEFAULT_DIALOG_STYLE) - - outerSizer = wx.BoxSizer(wx.VERTICAL) - - self.mainSizer = wx.BoxSizer(wx.VERTICAL) - self.mainSizer.SetMinSize([500, 150]) - - self.Page = parent.Page - - self.mainSizer.Add( - self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), - 0, wx.EXPAND|wx.ALL, 10) - - outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) - - self.SetSizerAndFit(outerSizer) - self.Layout() - self.Fit() - -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" - - -####### Away From Keyboard -class AFKCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.Groups = {} - self.AttributeTable = { - 'Base' : { - 'Current Hit Points' : 'NT H', - 'Max Hit Points' : 'X H', - 'Current Endurance' : 'T E', - 'Max Endurance' : 'X EN', - 'Regeneration Rate' : 'N RAT', - 'Recovery Rate' : 'Y RA', - 'Endurance Consumption' : 'SU', - 'ToHit Bonus' : 'T B', - 'Accuracy Bonus' : 'CC', - 'Last Hit Chance' : 'T C', - 'Damage Bonus' : 'DA', - 'Healing Bonus' : 'NG B', - 'Recharge Time Bonus' : 'ME B', - 'Endurance Discount' : 'CE DIS', - 'Stealth Radius (PvP)' : 'PVP', - 'Stealth Radius (PvE)' : 'PVE', - 'Perception Radius' : 'RC', - 'Range Bonus' : 'GE B', - 'Threat Level' : 'AT L', - 'Experience to Next Level' : 'XT', - 'Experience Debt' : 'XP', - 'Influence / Infamy' : 'INF', - 'Inherent' : 'NH', - }, - 'Movement Speed' : { - 'Flying Speed' : 'FL', - 'Jumping Speed' : 'PI', - 'Max Jump Height' : 'X J', - 'Run Speed' : 'RU', - }, - 'Damage Resistance' : { - 'Smashing Resistance' : 'G R', - 'Lethal Resistance' : 'L R', - 'Fire Resistance' : 'RE R', - 'Cold Resistance' : 'COLD R', - 'Energy Resistance' : 'DamageType[4]', - 'Negative Energy Resistance' : 'GY R', - 'Psyonic Resistance' : 'NIC R', - 'Toxic Resistance' : 'XIC R', - }, - 'Defense' : { - 'Base Defense' : 'BAS', - 'Ranged Defense' : 'ED', - 'Melee Defense' : 'MEL', - 'AoE Defense' : '2', - 'Smashing Defense' : '3', - 'Lethal Defense' : '4', - 'Fire Defense' : '5', - 'Cold Defense' : '6', - 'Energy Defense' : '7', - 'Negative Energy Defense' : '8', - 'Psionic Defense' : '9', - 'Toxic Defense' : '1', - }, - 'Debuff Resistance' : { - 'Regeneration Resistance' : 'ON R', - 'Recovery Resistance' : 'RY R', - 'To Hit Resistance' : 'IT R', - 'Defense Resistance' : 'NSE RES', - }, - 'Status Effect Protection' : { - 'Hold Protection' : 'D P', - 'Immobilize Protection' : 'LIZE P', - 'Stun Protection' : 'N P', - 'Sleep Protection' : 'P P', - 'Knockback Protection' : 'K P', - 'Confuse Protection' : 'SE P', - 'Terrorize Protection' : 'ZE P', - 'Repel Protection' : 'EL P', - 'Teleport Protection' : 'T P', - }, - 'Status Effect Resistance' : { - 'Hold Resistance' : 'D R', - 'Immobilize Resistance' : 'LIZE R', - 'Stun Resistance' : 'N R', - 'Sleep Resistance' : 'P R', - 'Knockback Resistance' : 'K R', - 'Confuse Resistance' : 'SE R', - 'Terrorize Resistance' : 'ZE R', - 'Placate Resistance' : 'TE R', - 'Taunt Resistance' : 'NT R', - }, - 'Miscellaneous' : { - 'Level Shift' : 'L S', - }, - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.AttributeMenu = wx.Menu() - for group, controls in self.AttributeTable.items(): - submenu = wx.Menu() - self.AttributeMenu.AppendSubMenu(submenu, group) - for cb in controls: - submenu.Append(wx.ID_ANY, cb) - - self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) - - self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) - groupSizer.Add(self.editbox) - - newButton = self.editbox.GetNewButton() - newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) - - return groupSizer - - def MakeBindString(self): - map = {} - bindstrings = [] - for _, controls in self.AttributeTable.items(): - for cb, data in controls.items(): - map[cb] = data - - for string in self.editbox.GetStrings(): - if string: - bindstrings.append(f'monitorattribute {map[string]}') - - return '$$'.join(bindstrings) - - def Serialize(self): - return { - 'attributes' : self.editbox.GetStrings() - } - - def Deserialize(self, init): - self.editbox.SetStrings(init.get('attributes', [])) - - def OnNewButton(self, evt): - evt.GetEventObject().PopupMenu(self.AttributeMenu) - - def OnMenuItem(self, evt): - menuitem = evt.EventObject.FindItemById(evt.GetId()) - existingstrings = self.editbox.GetStrings() - existingstrings.append(menuitem.GetItemLabel()) - self.editbox.SetStrings(existingstrings) - -####### Auto Power -class AutoPowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) - autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.autoPowerName = PowerPicker(dialog) - autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) - - return autoPowerSizer - - def MakeBindString(self): - return f"powexecauto {self.autoPowerName.GetLabel()}" - - def Serialize(self): - return { - 'pname' : self.autoPowerName.GetLabel(), - 'picon' : self.autoPowerName.IconFilename - } - - def Deserialize(self, init): - if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.buffDisplayMap = { - 'Status Window' : { - 'Hide Auto' : 1, - 'Hide Toggles' : 2, - 'No Blinking' : 4, - 'No Stacking' : 8, - 'Numeric Stacking' : 16, - 'Hide Buff Numbers' : 32, - 'Stop Sending Buffs' : 64, - }, - 'Group Window' : { - 'Hide Auto' : 256, - 'Hide Toggles' : 512, - 'No Blinking' : 1024, - 'No Stacking' : 2048, - 'Numeric Stacking' : 4096, - 'Hide Buff Numbers' : 8192, - 'Stop Sending Buffs' : 16384, - }, - 'Pet Window' : { - 'Hide Auto' : 65536, - 'Hide Toggles' : 131072, - 'No Blinking' : 262144, - 'No Stacking' : 524288, - 'Numeric Stacking' : 1048576, - 'Hide Buff Numbers' : 2097152, - 'Stop Sending Buffs' : 4194304, - }, - } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - for group, controls in self.buffDisplayMap.items(): - self.Groups[group] = ControlGroup(dialog, self.Page, label = group) - groupid = self.Groups[group].GetStaticBox().GetId() - for cb, data in controls.items(): - self.Groups[group].AddControl( - ctlType = 'checkbox', - ctlName = f"{groupid}_{group}_{cb}", - label = cb, - data = data, - ) - - groupSizer.Add(self.Groups[group]) - - return groupSizer - - def CalculateValue(self): - page = wx.App.Get().Main.Profile.CustomBinds - - total = 0 - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] - if checkbox.IsChecked(): - total = total + checkbox.Data - return total - - def MakeBindString(self): - return f"optionset buffsettings {self.CalculateValue()}" - - def Serialize(self): - return { 'value' : self.CalculateValue() } - - def Deserialize(self, init): - value = init.get('value', 0) - - value = value or 0 # in case we had for some reason 'None' stashed in the init values - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] - checkbox.SetValue( checkbox.Data & value ) - -####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - chatCommandSizer = wx.GridBagSizer(5, 5) - self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") - chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) - # row 1 - self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) - self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) - self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) - # row 2 - self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) - self.chatCommandDuration.SetRange(1, 20) - self.chatCommandDuration.SetValue(7) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandDuration, (2,1)) - self.chatCommandChatSize = wx.Choice(dialog, -1, - choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) - self.chatCommandChatSize.SetSelection(5) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) - self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) - self.chatCommandChannel.SetSelection(0) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChannel, (2,5)) - # row 3 - self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") - chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) - self.chatCommandMessage = wx.TextCtrl(dialog, -1) - self.chatCommandMessage.SetHint('Chat Command Text') - chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) - - return chatCommandSizer - - def MakeBindString(self): - duration = self.chatCommandDuration.GetValue() - - choice = self.chatCommandChatSize - index = choice.GetSelection() - size = choice.GetString(index) - - duration = f"" if duration != 7 else "" - size = f"" if size != "1" else "" - - bdcolor = fgcolor = bgcolor = '' - if self.chatCommandUseColorsCB.IsChecked(): - bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - - bdcolor = f"" - fgcolor = f"" - bgcolor = f"" - - beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' - text = self.chatCommandMessage.GetValue() - - choice = self.chatCommandChannel - index = choice.GetSelection() - channel = choice.GetString(index) - - return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" - - def Serialize(self): - return { - 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), - 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), - 'channel' : self.chatCommandChannel .GetSelection(), - 'size' : self.chatCommandChatSize.GetSelection(), - 'duration' : self.chatCommandDuration.GetValue(), - 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'text' : self.chatCommandMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) - if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) - if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) - if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) - if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) - if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) - if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) - if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) - if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - - -####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): - def BuildUI(self, dialog): - chatCommandGlobalSizer = wx.GridBagSizer(5,5) - - self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") - chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) - - self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalChannel.SetHint("Channel") - chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) - - self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') - chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) - - chatCommandGlobalSizer.AddGrowableCol(1) - - return chatCommandGlobalSizer - - def MakeBindString(self): - useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() - channel = self.chatCommandGlobalChannel.GetValue() - message = self.chatCommandGlobalMessage.GetValue() - - preface = "beginchat /" if useBeginchat else "" - - return f'{preface}send "{channel}" {message}' - - def Serialize(self): - return { - 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), - 'channel' : self.chatCommandGlobalChannel.GetValue(), - 'message' : self.chatCommandGlobalMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) - if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) - if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) - -#######Costume Change -class CostumeChangeCmd(PowerBindCmd): - def BuildUI(self, dialog): - costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeCostume = wx.Choice(dialog, -1, - choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) - self.costumeChangeCostume.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeEmote = wx.Choice(dialog, -1, - choices = GameData.Emotes['costumechange']) - self.costumeChangeEmote.Insert("- None -", 0) - self.costumeChangeEmote.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return costumeChangeSizer - - def MakeBindString(self): - costumeNumber = self.costumeChangeCostume.GetSelection() - costumeEmote = self.costumeChangeEmote.GetSelection() - - if costumeEmote: # None, or 0 == "- None -" - ccCmd = 'cce' - emoteName = self.costumeChangeEmote.GetString(costumeEmote) - emoteName = " CC" + emoteName.replace(" ","") - else: - ccCmd = 'cc' - emoteName = '' - - return f"{ccCmd} {costumeNumber}{emoteName}" - - def Serialize(self): - return{ - 'costumeNumber': self.costumeChangeCostume.GetSelection(), - 'costumeEmote' : self.costumeChangeEmote.GetSelection(), - } - - def Deserialize(self, init): - if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) - if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) - -####### Movement Command -class MovementCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - self.plusbutton.SetValue(True) - - self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.commandchoice = wx.Choice(dialog, choices = [ - "forward", "left", "right", "backward", "up", "down", - "turnleft", "turnright", "first", "autorun", "clicktomove", - ],) - sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) - self.commandchoice.SetSelection(0) - - self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - pre = post = '' - if self.plusbutton.GetValue() : pre = "+" - elif self.plusplusbutton.GetValue() : pre = "++" - elif self.minusbutton.GetValue() : pre = "-" - elif self.zerobutton.GetValue() : post = " 0" - elif self.onebutton.GetValue() : post = " 1" - - command = self.commandchoice.GetString(self.commandchoice.GetSelection()) - - return f"{pre}{command}{post}" - - def Serialize(self): - mod = '' - if self.plusbutton.GetValue() : mod = "plus" - elif self.plusplusbutton.GetValue() : mod = "plusplus" - elif self.minusbutton.GetValue() : mod = "minus" - elif self.zerobutton.GetValue() : mod = "zero" - elif self.onebutton.GetValue() : mod = "one" - - return { - 'mod' : mod, - 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), - } - - def Deserialize(self, init): - mod = init.get('mod', 'plus') - - if mod == 'plus' : self.plusbutton.SetValue(True) - elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) - elif mod == 'minus' : self.minusbutton.SetValue(True) - elif mod == 'zero' : self.zerobutton.SetValue(True) - elif mod == 'one' : self.onebutton.SetValue(True) - - self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) - -####### Graphics Command -class GraphicsCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.FlexGridSizer(2) - - self.visscalecb = wx.CheckBox(dialog, label = "visscale") - sizer.Add(self.visscalecb) - self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) - sizer.Add(self.visscalesc) - - self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") - sizer.Add(self.dofweightcb) - self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) - sizer.Add(self.dofweightsc) - - self.fsaacb = wx.CheckBox(dialog, label = "fsaa") - sizer.Add(self.fsaacb) - self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) - self.fsaach.SetSelection(0) - sizer.Add(self.fsaach) - - self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") - sizer.Add(self.bloomscalecb) - self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) - self.bloomscalech.SetSelection(0) - sizer.Add(self.bloomscalech) - - self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") - sizer.Add(self.bloomweightcb) - self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) - sizer.Add(self.bloomweightsc) - - self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") - sizer.Add(self.lodbiascb) - self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) - sizer.Add(self.lodbiassc) - - self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") - sizer.Add(self.renderscalecb) - self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) - sizer.Add(self.renderscalesc) - - return sizer - - def MakeBindString(self): - # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. - bindstrings = [] - if self.visscalecb.IsChecked(): - bindstrings.append("visscale " + str(self.visscalesc.GetValue())) - if self.dofweightcb.IsChecked(): - bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) - if self.fsaacb.IsChecked(): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bindstrings.append("fsaa " + fsaavalue) - if self.bloomscalecb.IsChecked(): - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - bindstrings.append("bloomscale " + bloomscalevalue) - if self.bloomweightcb.IsChecked(): - bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) - if self.lodbiascb.IsChecked(): - bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) - if self.renderscalecb.IsChecked(): - bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) - - return '$$'.join(bindstrings) - - def Serialize(self): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - return { - 'visscalecb' : self.visscalecb.IsChecked(), - 'visscalesc' : self.visscalesc.GetValue(), - 'dofweightcb' : self.dofweightcb.IsChecked(), - 'dofweightsc' : self.dofweightsc.GetValue(), - 'fsaacb' : self.fsaacb.IsChecked(), - 'fsaach' : fsaavalue, - 'bloomscalecb' : self.bloomscalecb.IsChecked(), - 'bloomscalech' : bloomscalevalue, - 'bloomweightcb' : self.bloomweightcb.IsChecked(), - 'bloomweightsc' : self.bloomweightsc.GetValue(), - 'lodbiascb' : self.lodbiascb.IsChecked(), - 'lodbiassc' : self.lodbiassc.GetValue(), - 'renderscalecb' : self.renderscalecb.IsChecked(), - 'renderscalesc' : self.renderscalesc.GetValue(), - } - - def Deserialize(self, init): - self.visscalecb.SetValue(init.get('visscalecb', False)) - self.visscalesc.SetValue(init.get('visscalesc', 1.0)) - self.dofweightcb.SetValue(init.get('dofweightcb', False)) - self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) - self.fsaacb.SetValue(init.get('fsaacb', False)) - self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) - self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) - self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) - self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) - self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) - self.lodbiascb.SetValue(init.get('lodbiascb', False)) - self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) - self.renderscalecb.SetValue(init.get('renderscalecb', False)) - self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) - -####### Custom Bind -class CustomBindCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.customBindName = wx.TextCtrl(dialog, -1) - self.customBindName.SetHint('Custom Bind Text') - sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - return self.customBindName.GetValue() - - def Serialize(self): - return { 'customBindName': self.customBindName.GetValue() } - - def Deserialize(self,init): - if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) - -####### Emote -class EmoteCmd(PowerBindCmd): - def BuildUI(self, dialog): - emoteSizer = wx.BoxSizer(wx.HORIZONTAL) - self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") - emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - self.emoteName = wx.Button(dialog, -1, "...") - self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) - emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) - - return emoteSizer - - def MakeBindString(self): - displayedEmoteName = self.emoteName.GetLabel() - actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] - - return actualEmotePayload - - def Serialize(self): - return {'emoteName': self.emoteName.GetLabel()} - - def Deserialize(self, init): - if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) - -####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): - def BuildUI(self, dialog): - mainSizer = wx.BoxSizer(wx.VERTICAL) - - lbSizer = wx.BoxSizer(wx.HORIZONTAL) - lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") - lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - profiles = Profile.GetAllProfileBindsDirs() - - self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) - lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) - - mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") - self.lbResetCB.SetValue(True) - - mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - return mainSizer - - def MakeBindString(self): - - # If the specified binds directory disappeared between runs, we'd crash, so handle that. - if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' - - config = wx.ConfigBase.Get() - if config.Exists('GameBindPath'): - bindpath = config.Read('GameBindPath') - else: - bindpath = config.Read('BindPath') - - reset = "" - if self.lbResetCB.GetValue(): - reset = "keybind_reset$$" - - resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' - return reset + 'bindloadfile ' + str(resetfilepath) - - def Serialize(self): - return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), - 'ResetKeybinds' : self.lbResetCB.GetValue(), - } - - def Deserialize(self, init): - if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) - self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) - -####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' +from UI.PowerBinderCommand import PowerBinderCommand ####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' - -####### SG Mode -class SGModeCmd(PowerBindCmd): - def BuildUI(self, dialog): - sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) - sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") - self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") - - sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) - - return sgmodeSizer - - def MakeBindString(self): - if self.sgmodeOnRB.GetValue(): - return 'sgmodeset 1' - elif self.sgmodeOffRB.GetValue(): - return 'sgmodeset 0' - else: - return 'sgmode' - - def Serialize(self): - if self.sgmodeOnRB.GetValue(): - val = "On" - elif self.sgmodeOffRB.GetValue(): - val = "Off" - else: - val = "Toggle" - - return {"value" : val} - - def Deserialize(self, init): - val = init.get('value', '') - if val == "On": - self.sgmodeOnRB.SetValue(True) - elif val == "Off": - self.sgmodeOffRB.SetValue(True) - else: - self.sgmodeToggleRB.SetValue(True) - -####### Target Custom -class TargetCustomCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetCustomSizer = wx.GridBagSizer(5,5) - targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), - flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) - self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetCustomModeChoice.SetSelection(0) - targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) - self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) - self.targetCustomOptionalName.SetHint("Optional name to match") - targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) - self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") - targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) - self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") - targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) - self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") - targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) - self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") - targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) - self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") - targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) - self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") - targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) - self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") - targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) - self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") - targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) - - targetCustomSizer.AddGrowableCol(2) - - return targetCustomSizer - - def MakeBindString(self): - choice = self.targetCustomModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - targetCommand = "targetcustom" + mode.lower() - - enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" - friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" - defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" - alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" - mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" - notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" - base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" - notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" - - name = self.targetCustomOptionalName.GetValue() - - return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" - - def Serialize(self): - return { - 'mode' : self.targetCustomModeChoice.GetSelection(), - 'enemy' : self.targetCustomCBEnemies. IsChecked(), - 'friend' : self.targetCustomCBFriends. IsChecked(), - 'defeated' : self.targetCustomCBDefeated. IsChecked(), - 'alive' : self.targetCustomCBAlive. IsChecked(), - 'mypet' : self.targetCustomCBMyPets. IsChecked(), - 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), - 'base' : self.targetCustomCBBaseItems. IsChecked(), - 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), - 'name' : self.targetCustomOptionalName.GetValue(), - } - - def Deserialize(self, init): - if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) - if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) - if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) - if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) - if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) - if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) - if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) - if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) - if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) - if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - - -####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) - targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetEnemyModeChoice.SetSelection(0) - targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetEnemySizer - - def MakeBindString(self): - choice = self.targetEnemyModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetenemy" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetEnemyModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) - -####### Target Friend -class TargetFriendCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) - targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetFriendModeChoice.SetSelection(0) - targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetFriendSizer - - def MakeBindString(self): - choice = self.targetFriendModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetfriend" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetFriendModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) - -####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): - def BuildUI(self, dialog): - teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], - style=wx.ALIGN_CENTER_VERTICAL) - self.teamPetSelectNumber.SetSelection(0) - teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) - - return teamPetSelectSizer +class PowerUnqueueCmd(PowerBinderCommand): + Name = "Power Unqueue" + Menu = "Powers" def MakeBindString(self): - teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' - targetNumber = self.teamPetSelectNumber.GetSelection()+1 - - return f"{teamOrPet}select {targetNumber}" - - def Serialize(self): - return { - 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', - 'targetNum': self.teamPetSelectNumber.GetSelection(), - } - - def Deserialize(self, init): - ToP = init.get('teamOrPet', '') - if ToP == 'pet': - self.teamPetSelectPetRB.SetValue(True) - else: - self.teamPetSelectTeamRB.SetValue(True) - if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) - -####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' - -####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) - for _, types in GameData.Inspirations.items(): - for _, info in types.items(): - for insp in info['tiers']: - name = re.sub(' ', '', str(insp)) - icon = GetIcon(f'Inspirations/{name}') - self.useInspByNameModeChoice.Append(insp, icon) - self.useInspByNameModeChoice.SetSelection(0) - useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) - - return useInspByNameSizer - - def MakeBindString(self): - choice = self.useInspByNameModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "inspexecname " + mode.lower() - - def GetAllInsps(self): - Insplist = [] - for _, info in GameData.Inspirations.items(): - for insp in info['tiers']: - Insplist.append(insp) - Insplist.append("---") - Insplist.pop(-1) # snip the terminal "---" - - return Insplist - - def Serialize(self): - return { 'insp' : self.useInspByNameModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) - -####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnRow.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) - self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnCol.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) - - return useInspRowColumnSizer - - def MakeBindString(self): - row = self.useInspRowColumnRow.GetSelection()+1 - col = self.useInspRowColumnCol.GetSelection()+1 - - return f"inspexectray {col} {row}" - - def Serialize(self): - return { - 'col' : self.useInspRowColumnCol.GetSelection(), - 'row' : self.useInspRowColumnRow.GetSelection(), - } - - def Deserialize(self, init): - if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) - if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) - -####### Use Power -class UsePowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - outerSizer = wx.BoxSizer(wx.HORIZONTAL) - - usePowerSizer = wx.GridBagSizer(5,5) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBToggle, (0,1)) - self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOn, (0,2)) - self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOff, (0,3)) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerName = PowerPicker(dialog) - usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) - usePowerSizer.AddGrowableCol(3) - - outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) - - return outerSizer - - def MakeBindString(self): - if self.usePowerRBToggle.GetValue(): - method = "powexecname" - elif self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') - return '' - - return f"{method} {self.usePowerName.GetLabel()}" - - def Serialize(self): - if self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - method = "powexecname" - return { - 'method': method, - 'pname' : self.usePowerName.GetLabel(), - 'picon' : self.usePowerName.IconFilename - } - - def Deserialize(self, init): - method = init.get('method', '') - if method == 'powexectoggleon': - self.usePowerRBOn.SetValue(True) - elif method == 'powexectoggleoff': - self.usePowerRBOff.SetValue(True) - else: - self.usePowerRBToggle.SetValue(True) - if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) - -####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): - def BuildUI(self, dialog): - usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTrayTray = wx.Choice(dialog, -1, - choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', - 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) - self.usePowerFromTrayTray.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) - self.usePowerFromTraySlot.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return usePowerFromTraySizer - - def MakeBindString(self): - choice = self.usePowerFromTrayTray - tray = choice.GetSelection() - - choice = self.usePowerFromTraySlot - slot = choice.GetSelection()+1 - - mode = "slot" - mode2 = '' - if tray > 3: - mode = "tray" - mode2 = f" {tray - 3}" - elif tray == 3: - mode = "alt2slot" - elif tray == 2: - mode = "altslot" - - return f"powexec{mode} {slot}{mode2}" - - def Serialize(self): - return { - 'tray' : self.usePowerFromTrayTray.GetSelection(), - 'slot' : self.usePowerFromTraySlot.GetSelection(), - } - - def Deserialize(self, init): - if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) - if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) - -####### Window Color -class WindowColorCmd(PowerBindCmd): - def BuildUI(self, dialog): - windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) - borderSizer = wx.BoxSizer(wx.VERTICAL) - self.ColorBorder.SetSizer(borderSizer) - self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) - borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) - - windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) - - RGBASizer = wx.FlexGridSizer(3, 4, 5) - - RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) - self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) - self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - windowColorSizer.Add(RGBASizer) - - self.UpdateFromSlider() - - return windowColorSizer - - def MakeBindString(self): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - return f"windowcolor {Rval} {Gval} {Bval} {Aval}" - - def Serialize(self): - return { - 'Rval' : self.RSlider.GetValue(), - 'Gval' : self.GSlider.GetValue(), - 'Bval' : self.BSlider.GetValue(), - 'Aval' : self.ASlider.GetValue(), - } - - def Deserialize(self, init): - self.RSlider.SetValue(init['Rval']) - self.GSlider.SetValue(init['Gval']) - self.BSlider.SetValue(init['Bval']) - self.ASlider.SetValue(init['Aval']) - self.UpdateFromSlider() - - def UpdateFromSlider(self, _ = None): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RReadout.SetValue(Rval) - self.GReadout.SetValue(Gval) - self.BReadout.SetValue(Bval) - self.AReadout.SetValue(Aval) - self.ColorBorder.Refresh() - - def UpdateFromText(self, _ = None): - Rval = self.RReadout.GetValue() - Gval = self.GReadout.GetValue() - Bval = self.BReadout.GetValue() - Aval = self.AReadout.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RSlider.SetValue(Rval) - self.GSlider.SetValue(Gval) - self.BSlider.SetValue(Bval) - self.ASlider.SetValue(Aval) - self.ColorBorder.Refresh() - -####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) - self.CommandChoice.SetSelection(0) - sizer.Add(self.CommandChoice, 0, wx.ALL, 5) - - self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), - value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) - sizer.Add(self.FilePath, 0, wx.ALL, 5) - - return sizer - - def MakeBindString(self): - command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] - return f'{command} "{self.FilePath.GetValue()}"' - - def Serialize(self): - return { - 'command' : self.CommandChoice.GetSelection(), - 'filename' : self.FilePath.GetValue(), - } - - def Deserialize(self, init): - self.CommandChoice.SetSelection(init.get('command', 0)) - self.FilePath.SetValue(init.get('filename', '')) - -####### Window Toggle -class WindowToggleCmd(PowerBindCmd): - def BuildUI(self, dialog): - self.WindowNames = { - 'Actions' : 'actions', - 'Auction House' : 'ah', - 'Badge' : 'badge', - 'Channel Search' : 'chansearch', - 'Chat' : 'chat', - 'Custom Chat 1' : 'chat1', - 'Custom Chat 2' : 'chat2', - 'Custom Chat 3' : 'chat3', - 'Custom Chat 4' : 'chat4', - 'Clues' : 'clue', - 'Combat Numbers' : 'combatnumbers', - 'Contacts' : 'contact', - 'Contact Finder' : 'contactfinder', - 'Costumes' : 'costume', - 'Email' : 'email', - 'Enhancements' : 'enhancements', - 'Friends' : 'friend', - 'Group' : 'group', - 'Help' : 'helpwindow', - 'Incarnate' : 'incarnate', - 'Inspirations' : 'insp', - 'League' : 'league', - 'LFG' : 'lfg', - 'Map' : 'map', - 'Mission' : 'mission', - 'Nav / Compass' : 'nav', - 'Options' : 'options', - 'Pets' : 'pet', - 'Petition' : 'petition', - 'Power Tray' : 'powers', - 'Power List' : 'powerlist', - 'Quit' : 'quit', - 'Recipes' : 'recipe', - 'Salvage' : 'salvage', - 'Search' : 'search', - 'Supergroup' : 'sg', - 'Target' : 'target', - 'Team' : 'team', - 'Tray' : 'tray', - 'Tray1' : 'tray1', - 'Tray2' : 'tray2', - 'Tray3' : 'tray3', - 'Tray4' : 'tray4', - 'Tray5' : 'tray5', - 'Tray6' : 'tray6', - 'Tray7' : 'tray7', - 'Tray8' : 'tray8', - 'Vault' : 'vault', - } - - self.ShortToggleCommands = { - 'Auction House' : 'ah', - 'Chat' : 'chat', - 'Help' : 'helpwindow', - 'Map' : 'map', - 'Nav / Compass' : 'nav', - 'Power Tray' : 'powers', - 'Target' : 'target', - 'Tray' : 'tray', - } - - windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) - windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) - self.windowToggleTray.SetSelection(0) - windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.windowShowRB = wx.RadioButton(dialog, -1, "Show") - self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") - - windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) - - return windowToggleSizer - - def MakeBindString(self): - choice = self.windowToggleTray - index = choice.GetSelection() - windowdesc = choice.GetString(index) - windowname = self.WindowNames[windowdesc] - - if self.windowShowRB.GetValue(): - return 'show ' + windowname - elif self.windowHideRB.GetValue(): - return 'windowhide ' + windowname - else: - if shortcmd := self.ShortToggleCommands.get(windowdesc, None): - return shortcmd - else: - return 'toggle ' + windowname - - - def Serialize(self): - choice = self.windowToggleTray - if self.windowShowRB.GetValue(): - action = "Show" - elif self.windowHideRB.GetValue(): - action = "Hide" - else: - action = "Toggle" - return { - 'window': choice.GetString(choice.GetSelection()), - 'action': action, - } - - def Deserialize(self, init): - choice = self.windowToggleTray - if window := init.get('window', ''): - if isinstance(window, int): - choice.SetSelection(window) - else: - choice.SetSelection(choice.FindString(window)) - - if choice.GetSelection() == wx.NOT_FOUND: - choice.SetSelection(0) - - action = init.get('action', '') - if action == "Show": - self.windowShowRB.SetValue(True) - elif action == "Hide": - self.windowHideRB.SetValue(True) - else: - self.windowToggleRB.SetValue(True) - - -# Must always add to this list when adding a new command class above -menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], - # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, - # but I'm leaving it here to remind myself that we do that. - } - -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} + return 'powexecunqueue' diff --git a/UI/PowerBinderCommand/SGModeCmd.py b/UI/PowerBinderCommand/SGModeCmd.py index 4c02ab7..6d41cce 100644 --- a/UI/PowerBinderCommand/SGModeCmd.py +++ b/UI/PowerBinderCommand/SGModeCmd.py @@ -1,1069 +1,11 @@ import wx -import re -import UI -import UI.EmotePicker -from UI.ControlGroup import ControlGroup -from UI.PowerPicker import PowerPicker -from Help import HelpButton -import wx.adv -from wx.adv import BitmapComboBox, EditableListBox -from pathlib import PureWindowsPath -import GameData -import Profile -from Icon import GetIcon - -class PowerBinderDialog(wx.Dialog): - def __init__(self, parent, button, init = {}): - wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) - - self.Page = parent.Page - self.EditDialog = PowerBinderEditDialog(self) - self.Button = button - self.AddStepMenu = self.makeAddStepMenu() - - sizer = wx.BoxSizer(wx.VERTICAL); - self.mainSizer = sizer - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) - AddStepButton = wx.Button(self, -1, 'Add Step') - AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) - AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) - choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) - choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) - sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) - - rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) - - self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) - self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) - self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) - rearrangeCtrl.Add(self.RearrangeList, 1) - - rearrangeButtons = wx.BoxSizer(wx.VERTICAL) - self.DelButton = wx.Button(self, -1, "Delete") - self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) - self.EditButton = wx.Button(self, -1, "Edit") - self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) - self.EditButton.Disable() - upButton = wx.Button(self, -1, "\u25B2") - upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) - downButton = wx.Button(self, -1, "\u25BC") - downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) - rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) - rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) - - sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.BindStringDisplay = wx.TextCtrl(self, -1) - self.BindStringDisplay.Disable() - choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, - wx.ALIGN_CENTER_VERTICAL) - choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) - - sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) - - sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) - - # need to dig around and get the OK button since we show this dialog modelessly now. - okButton = self.FindWindow(self.GetAffirmativeId()) - okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) - - # Wrap everything in a vbox to add some padding - vbox = wx.BoxSizer(wx.VERTICAL); - vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); - - self.SetSizerAndFit(vbox); - self.Layout() - self.Fit() - self.SetFocus() - - # if we are loading from profile, ie, have "init", build the list from it - if init: self.LoadFromData(init) - - def LoadFromData(self, init): - for item in init: - for type, data in item.items(): - commandClass = commandClasses.get(type, None) - if not commandClass: - commandClass = deprecatedCommandClasses.get(type, None) - if not commandClass: - wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") - continue - newCommand = commandClass(self.EditDialog, data) - index = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.SetClientData(index, newCommand) - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) - self.EditDialog.mainSizer.Hide(newCommand.UI) - self.UpdateBindStringDisplay() - - def SaveToData(self): - data = [] - index = 0 - for _ in self.RearrangeList.GetItems(): - # check whether we have an object already attached to this choice - cmdObject = self.RearrangeList.GetClientData(index) - commandClassName = commandRevClasses[type(cmdObject)] - data.append({commandClassName: cmdObject.Serialize()}) - index = index + 1 - return data - - def OnAddStepButton(self, evt): - button = evt.EventObject - if not self.AddStepMenu: - self.AddStepMenu = self.makeAddStepMenu() - button.PopupMenu(self.AddStepMenu) - - - def OnOKButton(self, _): - if self.Button.tgtTxtCtrl: - bindString = self.MakeBindString() - if bindString != self.Button.tgtTxtCtrl.GetValue(): - self.Button.tgtTxtCtrl.SetValue(bindString) - wx.App.Get().Main.Profile.SetModified() - self.Close() - - def OnRearrangeDelete(self, _): - current = self.RearrangeList.GetSelection() - if current == wx.NOT_FOUND: return - - self.RearrangeList.Delete(current) - self.UpdateBindStringDisplay() - - def OnRearrangeUp(self, _): - self.RearrangeList.MoveCurrentUp() - self.UpdateBindStringDisplay() - - def OnRearrangeDown(self, _): - self.RearrangeList.MoveCurrentDown() - self.UpdateBindStringDisplay() - - def OnRearrangeEdit(self, _): - index = self.RearrangeList.GetSelection() - - # check whether we have an object already attached to this choice - cmdObject = None - try: - cmdObject = self.RearrangeList.GetClientData(index) - except Exception: - pass - - if cmdObject: - self.ShowEditDialogFor(cmdObject) - self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) - else: - print("cmdObject was None") - self.UpdateBindStringDisplay() - - # OnAddStepMenu creates a new step and adds it to the rearrangelist - def OnAddStepMenu(self, evt): - menuitem = self.AddStepMenu.FindItemById(evt.GetId()) - chosenName = menuitem.GetItemLabel() - - # make a new command object, attached to the parent dialog - newCommandClass = commandClasses[chosenName] - newCommand = newCommandClass(self.EditDialog) - - # show the edit dialog if this command needs it - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) - if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): - self.EditDialog.mainSizer.Remove(newCommand.UI) - return - - newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.Select(newBindIndex) - self.RearrangeList.SetClientData(newBindIndex, newCommand) - - self.OnListSelect() - self.UpdateBindStringDisplay() - - def OnListSelect(self, _ = None): - selected = self.RearrangeList.GetSelection() - - if selected != wx.NOT_FOUND: - selCommand = self.RearrangeList.GetClientData(selected) - if selCommand.UI: - self.EditButton.Enable() - else: - self.EditButton.Disable() - - def UpdateBindStringDisplay(self): - self.BindStringDisplay.SetValue(self.MakeBindString()) - self.BindStringDisplay.SetToolTip(self.MakeBindString()) - - def MakeBindString(self): - cmdBindStrings = [] - for index in range(self.RearrangeList.GetCount()): - c = self.RearrangeList.GetClientData(index) - if c: cmdBindStrings.append(c.MakeBindString()) - - bindstring = ('$$'.join(cmdBindStrings)) - return bindstring - - def ShowEditDialogFor(self, command): - if not command.UI: return - - self.EditDialog.mainSizer.Show(command.UI) - - self.EditDialog.Layout() - self.EditDialog.Fit() - - self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') - returnval = self.EditDialog.ShowModal() - - self.EditDialog.mainSizer.Hide(command.UI) - - return returnval - - def makeAddStepMenu(self): - - stepMenu = wx.Menu() - - for subname in menuStructure: - submenu = wx.Menu() - stepMenu.AppendSubMenu(submenu, subname) - for classname in menuStructure[subname]: - submenu.Append(wx.ID_ANY, classname) - - stepMenu.Append(wx.ID_ANY, 'Custom Bind') - - return stepMenu - -class PowerBinderButton(wx.BitmapButton): - - def __init__(self, parent, tgtTxtCtrl, init = {}): - wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) - self.Init = init - self.Dialog = None - self.DialogParent = parent - - self.tgtTxtCtrl = tgtTxtCtrl - self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) - self.SetToolTip("Launch PowerBinder") - - def PowerBinderEventHandler(self, _): - self.PowerBinderDialog().Show() - - def LoadFromData(self, data): - self.PowerBinderDialog().LoadFromData(data) - - def SaveToData(self): - return self.PowerBinderDialog().SaveToData() - - def PowerBinderDialog(self): - if not self.Dialog: - self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) - return self.Dialog - - -class PowerBinderEditDialog(wx.Dialog): - def __init__(self, parent): - wx.Dialog.__init__(self, parent, -1, "Edit Step", - style = wx.DEFAULT_DIALOG_STYLE) - - outerSizer = wx.BoxSizer(wx.VERTICAL) - - self.mainSizer = wx.BoxSizer(wx.VERTICAL) - self.mainSizer.SetMinSize([500, 150]) - - self.Page = parent.Page - - self.mainSizer.Add( - self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), - 0, wx.EXPAND|wx.ALL, 10) - - outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) - - self.SetSizerAndFit(outerSizer) - self.Layout() - self.Fit() - -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" - - -####### Away From Keyboard -class AFKCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.Groups = {} - self.AttributeTable = { - 'Base' : { - 'Current Hit Points' : 'NT H', - 'Max Hit Points' : 'X H', - 'Current Endurance' : 'T E', - 'Max Endurance' : 'X EN', - 'Regeneration Rate' : 'N RAT', - 'Recovery Rate' : 'Y RA', - 'Endurance Consumption' : 'SU', - 'ToHit Bonus' : 'T B', - 'Accuracy Bonus' : 'CC', - 'Last Hit Chance' : 'T C', - 'Damage Bonus' : 'DA', - 'Healing Bonus' : 'NG B', - 'Recharge Time Bonus' : 'ME B', - 'Endurance Discount' : 'CE DIS', - 'Stealth Radius (PvP)' : 'PVP', - 'Stealth Radius (PvE)' : 'PVE', - 'Perception Radius' : 'RC', - 'Range Bonus' : 'GE B', - 'Threat Level' : 'AT L', - 'Experience to Next Level' : 'XT', - 'Experience Debt' : 'XP', - 'Influence / Infamy' : 'INF', - 'Inherent' : 'NH', - }, - 'Movement Speed' : { - 'Flying Speed' : 'FL', - 'Jumping Speed' : 'PI', - 'Max Jump Height' : 'X J', - 'Run Speed' : 'RU', - }, - 'Damage Resistance' : { - 'Smashing Resistance' : 'G R', - 'Lethal Resistance' : 'L R', - 'Fire Resistance' : 'RE R', - 'Cold Resistance' : 'COLD R', - 'Energy Resistance' : 'DamageType[4]', - 'Negative Energy Resistance' : 'GY R', - 'Psyonic Resistance' : 'NIC R', - 'Toxic Resistance' : 'XIC R', - }, - 'Defense' : { - 'Base Defense' : 'BAS', - 'Ranged Defense' : 'ED', - 'Melee Defense' : 'MEL', - 'AoE Defense' : '2', - 'Smashing Defense' : '3', - 'Lethal Defense' : '4', - 'Fire Defense' : '5', - 'Cold Defense' : '6', - 'Energy Defense' : '7', - 'Negative Energy Defense' : '8', - 'Psionic Defense' : '9', - 'Toxic Defense' : '1', - }, - 'Debuff Resistance' : { - 'Regeneration Resistance' : 'ON R', - 'Recovery Resistance' : 'RY R', - 'To Hit Resistance' : 'IT R', - 'Defense Resistance' : 'NSE RES', - }, - 'Status Effect Protection' : { - 'Hold Protection' : 'D P', - 'Immobilize Protection' : 'LIZE P', - 'Stun Protection' : 'N P', - 'Sleep Protection' : 'P P', - 'Knockback Protection' : 'K P', - 'Confuse Protection' : 'SE P', - 'Terrorize Protection' : 'ZE P', - 'Repel Protection' : 'EL P', - 'Teleport Protection' : 'T P', - }, - 'Status Effect Resistance' : { - 'Hold Resistance' : 'D R', - 'Immobilize Resistance' : 'LIZE R', - 'Stun Resistance' : 'N R', - 'Sleep Resistance' : 'P R', - 'Knockback Resistance' : 'K R', - 'Confuse Resistance' : 'SE R', - 'Terrorize Resistance' : 'ZE R', - 'Placate Resistance' : 'TE R', - 'Taunt Resistance' : 'NT R', - }, - 'Miscellaneous' : { - 'Level Shift' : 'L S', - }, - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.AttributeMenu = wx.Menu() - for group, controls in self.AttributeTable.items(): - submenu = wx.Menu() - self.AttributeMenu.AppendSubMenu(submenu, group) - for cb in controls: - submenu.Append(wx.ID_ANY, cb) - - self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) - - self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) - groupSizer.Add(self.editbox) - - newButton = self.editbox.GetNewButton() - newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) - - return groupSizer - - def MakeBindString(self): - map = {} - bindstrings = [] - for _, controls in self.AttributeTable.items(): - for cb, data in controls.items(): - map[cb] = data - - for string in self.editbox.GetStrings(): - if string: - bindstrings.append(f'monitorattribute {map[string]}') - - return '$$'.join(bindstrings) - - def Serialize(self): - return { - 'attributes' : self.editbox.GetStrings() - } - - def Deserialize(self, init): - self.editbox.SetStrings(init.get('attributes', [])) - - def OnNewButton(self, evt): - evt.GetEventObject().PopupMenu(self.AttributeMenu) - - def OnMenuItem(self, evt): - menuitem = evt.EventObject.FindItemById(evt.GetId()) - existingstrings = self.editbox.GetStrings() - existingstrings.append(menuitem.GetItemLabel()) - self.editbox.SetStrings(existingstrings) - -####### Auto Power -class AutoPowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) - autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.autoPowerName = PowerPicker(dialog) - autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) - - return autoPowerSizer - - def MakeBindString(self): - return f"powexecauto {self.autoPowerName.GetLabel()}" - - def Serialize(self): - return { - 'pname' : self.autoPowerName.GetLabel(), - 'picon' : self.autoPowerName.IconFilename - } - - def Deserialize(self, init): - if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.buffDisplayMap = { - 'Status Window' : { - 'Hide Auto' : 1, - 'Hide Toggles' : 2, - 'No Blinking' : 4, - 'No Stacking' : 8, - 'Numeric Stacking' : 16, - 'Hide Buff Numbers' : 32, - 'Stop Sending Buffs' : 64, - }, - 'Group Window' : { - 'Hide Auto' : 256, - 'Hide Toggles' : 512, - 'No Blinking' : 1024, - 'No Stacking' : 2048, - 'Numeric Stacking' : 4096, - 'Hide Buff Numbers' : 8192, - 'Stop Sending Buffs' : 16384, - }, - 'Pet Window' : { - 'Hide Auto' : 65536, - 'Hide Toggles' : 131072, - 'No Blinking' : 262144, - 'No Stacking' : 524288, - 'Numeric Stacking' : 1048576, - 'Hide Buff Numbers' : 2097152, - 'Stop Sending Buffs' : 4194304, - }, - } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - for group, controls in self.buffDisplayMap.items(): - self.Groups[group] = ControlGroup(dialog, self.Page, label = group) - groupid = self.Groups[group].GetStaticBox().GetId() - for cb, data in controls.items(): - self.Groups[group].AddControl( - ctlType = 'checkbox', - ctlName = f"{groupid}_{group}_{cb}", - label = cb, - data = data, - ) - - groupSizer.Add(self.Groups[group]) - - return groupSizer - - def CalculateValue(self): - page = wx.App.Get().Main.Profile.CustomBinds - - total = 0 - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] - if checkbox.IsChecked(): - total = total + checkbox.Data - return total - - def MakeBindString(self): - return f"optionset buffsettings {self.CalculateValue()}" - - def Serialize(self): - return { 'value' : self.CalculateValue() } - - def Deserialize(self, init): - value = init.get('value', 0) - - value = value or 0 # in case we had for some reason 'None' stashed in the init values - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] - checkbox.SetValue( checkbox.Data & value ) - -####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - chatCommandSizer = wx.GridBagSizer(5, 5) - self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") - chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) - # row 1 - self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) - self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) - self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) - # row 2 - self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) - self.chatCommandDuration.SetRange(1, 20) - self.chatCommandDuration.SetValue(7) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandDuration, (2,1)) - self.chatCommandChatSize = wx.Choice(dialog, -1, - choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) - self.chatCommandChatSize.SetSelection(5) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) - self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) - self.chatCommandChannel.SetSelection(0) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChannel, (2,5)) - # row 3 - self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") - chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) - self.chatCommandMessage = wx.TextCtrl(dialog, -1) - self.chatCommandMessage.SetHint('Chat Command Text') - chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) - - return chatCommandSizer - - def MakeBindString(self): - duration = self.chatCommandDuration.GetValue() - - choice = self.chatCommandChatSize - index = choice.GetSelection() - size = choice.GetString(index) - - duration = f"" if duration != 7 else "" - size = f"" if size != "1" else "" - - bdcolor = fgcolor = bgcolor = '' - if self.chatCommandUseColorsCB.IsChecked(): - bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - - bdcolor = f"" - fgcolor = f"" - bgcolor = f"" - - beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' - text = self.chatCommandMessage.GetValue() - - choice = self.chatCommandChannel - index = choice.GetSelection() - channel = choice.GetString(index) - - return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" - - def Serialize(self): - return { - 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), - 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), - 'channel' : self.chatCommandChannel .GetSelection(), - 'size' : self.chatCommandChatSize.GetSelection(), - 'duration' : self.chatCommandDuration.GetValue(), - 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'text' : self.chatCommandMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) - if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) - if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) - if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) - if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) - if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) - if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) - if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) - if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - - -####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): - def BuildUI(self, dialog): - chatCommandGlobalSizer = wx.GridBagSizer(5,5) - - self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") - chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) - - self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalChannel.SetHint("Channel") - chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) - - self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') - chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) - - chatCommandGlobalSizer.AddGrowableCol(1) - - return chatCommandGlobalSizer - - def MakeBindString(self): - useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() - channel = self.chatCommandGlobalChannel.GetValue() - message = self.chatCommandGlobalMessage.GetValue() - - preface = "beginchat /" if useBeginchat else "" - - return f'{preface}send "{channel}" {message}' - - def Serialize(self): - return { - 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), - 'channel' : self.chatCommandGlobalChannel.GetValue(), - 'message' : self.chatCommandGlobalMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) - if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) - if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) - -#######Costume Change -class CostumeChangeCmd(PowerBindCmd): - def BuildUI(self, dialog): - costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeCostume = wx.Choice(dialog, -1, - choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) - self.costumeChangeCostume.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeEmote = wx.Choice(dialog, -1, - choices = GameData.Emotes['costumechange']) - self.costumeChangeEmote.Insert("- None -", 0) - self.costumeChangeEmote.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return costumeChangeSizer - - def MakeBindString(self): - costumeNumber = self.costumeChangeCostume.GetSelection() - costumeEmote = self.costumeChangeEmote.GetSelection() - - if costumeEmote: # None, or 0 == "- None -" - ccCmd = 'cce' - emoteName = self.costumeChangeEmote.GetString(costumeEmote) - emoteName = " CC" + emoteName.replace(" ","") - else: - ccCmd = 'cc' - emoteName = '' - - return f"{ccCmd} {costumeNumber}{emoteName}" - - def Serialize(self): - return{ - 'costumeNumber': self.costumeChangeCostume.GetSelection(), - 'costumeEmote' : self.costumeChangeEmote.GetSelection(), - } - - def Deserialize(self, init): - if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) - if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) - -####### Movement Command -class MovementCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - self.plusbutton.SetValue(True) - - self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.commandchoice = wx.Choice(dialog, choices = [ - "forward", "left", "right", "backward", "up", "down", - "turnleft", "turnright", "first", "autorun", "clicktomove", - ],) - sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) - self.commandchoice.SetSelection(0) - - self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - pre = post = '' - if self.plusbutton.GetValue() : pre = "+" - elif self.plusplusbutton.GetValue() : pre = "++" - elif self.minusbutton.GetValue() : pre = "-" - elif self.zerobutton.GetValue() : post = " 0" - elif self.onebutton.GetValue() : post = " 1" - - command = self.commandchoice.GetString(self.commandchoice.GetSelection()) - - return f"{pre}{command}{post}" - - def Serialize(self): - mod = '' - if self.plusbutton.GetValue() : mod = "plus" - elif self.plusplusbutton.GetValue() : mod = "plusplus" - elif self.minusbutton.GetValue() : mod = "minus" - elif self.zerobutton.GetValue() : mod = "zero" - elif self.onebutton.GetValue() : mod = "one" - - return { - 'mod' : mod, - 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), - } - - def Deserialize(self, init): - mod = init.get('mod', 'plus') - - if mod == 'plus' : self.plusbutton.SetValue(True) - elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) - elif mod == 'minus' : self.minusbutton.SetValue(True) - elif mod == 'zero' : self.zerobutton.SetValue(True) - elif mod == 'one' : self.onebutton.SetValue(True) - - self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) - -####### Graphics Command -class GraphicsCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.FlexGridSizer(2) - - self.visscalecb = wx.CheckBox(dialog, label = "visscale") - sizer.Add(self.visscalecb) - self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) - sizer.Add(self.visscalesc) - - self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") - sizer.Add(self.dofweightcb) - self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) - sizer.Add(self.dofweightsc) - - self.fsaacb = wx.CheckBox(dialog, label = "fsaa") - sizer.Add(self.fsaacb) - self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) - self.fsaach.SetSelection(0) - sizer.Add(self.fsaach) - - self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") - sizer.Add(self.bloomscalecb) - self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) - self.bloomscalech.SetSelection(0) - sizer.Add(self.bloomscalech) - - self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") - sizer.Add(self.bloomweightcb) - self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) - sizer.Add(self.bloomweightsc) - - self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") - sizer.Add(self.lodbiascb) - self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) - sizer.Add(self.lodbiassc) - - self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") - sizer.Add(self.renderscalecb) - self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) - sizer.Add(self.renderscalesc) - - return sizer - - def MakeBindString(self): - # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. - bindstrings = [] - if self.visscalecb.IsChecked(): - bindstrings.append("visscale " + str(self.visscalesc.GetValue())) - if self.dofweightcb.IsChecked(): - bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) - if self.fsaacb.IsChecked(): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bindstrings.append("fsaa " + fsaavalue) - if self.bloomscalecb.IsChecked(): - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - bindstrings.append("bloomscale " + bloomscalevalue) - if self.bloomweightcb.IsChecked(): - bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) - if self.lodbiascb.IsChecked(): - bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) - if self.renderscalecb.IsChecked(): - bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) - - return '$$'.join(bindstrings) - - def Serialize(self): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - return { - 'visscalecb' : self.visscalecb.IsChecked(), - 'visscalesc' : self.visscalesc.GetValue(), - 'dofweightcb' : self.dofweightcb.IsChecked(), - 'dofweightsc' : self.dofweightsc.GetValue(), - 'fsaacb' : self.fsaacb.IsChecked(), - 'fsaach' : fsaavalue, - 'bloomscalecb' : self.bloomscalecb.IsChecked(), - 'bloomscalech' : bloomscalevalue, - 'bloomweightcb' : self.bloomweightcb.IsChecked(), - 'bloomweightsc' : self.bloomweightsc.GetValue(), - 'lodbiascb' : self.lodbiascb.IsChecked(), - 'lodbiassc' : self.lodbiassc.GetValue(), - 'renderscalecb' : self.renderscalecb.IsChecked(), - 'renderscalesc' : self.renderscalesc.GetValue(), - } - - def Deserialize(self, init): - self.visscalecb.SetValue(init.get('visscalecb', False)) - self.visscalesc.SetValue(init.get('visscalesc', 1.0)) - self.dofweightcb.SetValue(init.get('dofweightcb', False)) - self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) - self.fsaacb.SetValue(init.get('fsaacb', False)) - self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) - self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) - self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) - self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) - self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) - self.lodbiascb.SetValue(init.get('lodbiascb', False)) - self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) - self.renderscalecb.SetValue(init.get('renderscalecb', False)) - self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) - -####### Custom Bind -class CustomBindCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.customBindName = wx.TextCtrl(dialog, -1) - self.customBindName.SetHint('Custom Bind Text') - sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - return self.customBindName.GetValue() - - def Serialize(self): - return { 'customBindName': self.customBindName.GetValue() } - - def Deserialize(self,init): - if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) - -####### Emote -class EmoteCmd(PowerBindCmd): - def BuildUI(self, dialog): - emoteSizer = wx.BoxSizer(wx.HORIZONTAL) - self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") - emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - self.emoteName = wx.Button(dialog, -1, "...") - self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) - emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) - - return emoteSizer - - def MakeBindString(self): - displayedEmoteName = self.emoteName.GetLabel() - actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] - - return actualEmotePayload - - def Serialize(self): - return {'emoteName': self.emoteName.GetLabel()} - - def Deserialize(self, init): - if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) - -####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): - def BuildUI(self, dialog): - mainSizer = wx.BoxSizer(wx.VERTICAL) - - lbSizer = wx.BoxSizer(wx.HORIZONTAL) - lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") - lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - profiles = Profile.GetAllProfileBindsDirs() - - self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) - lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) - - mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") - self.lbResetCB.SetValue(True) - - mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - return mainSizer - - def MakeBindString(self): - - # If the specified binds directory disappeared between runs, we'd crash, so handle that. - if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' - - config = wx.ConfigBase.Get() - if config.Exists('GameBindPath'): - bindpath = config.Read('GameBindPath') - else: - bindpath = config.Read('BindPath') - - reset = "" - if self.lbResetCB.GetValue(): - reset = "keybind_reset$$" - - resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' - return reset + 'bindloadfile ' + str(resetfilepath) - - def Serialize(self): - return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), - 'ResetKeybinds' : self.lbResetCB.GetValue(), - } - - def Deserialize(self, init): - if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) - self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) - -####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' - -####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' +from UI.PowerBinderCommand import PowerBinderCommand ####### SG Mode -class SGModeCmd(PowerBindCmd): +class SGModeCmd(PowerBinderCommand): + Name = "Supergroup Mode" + Menu = "Social" + def BuildUI(self, dialog): sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) @@ -1104,697 +46,3 @@ def Deserialize(self, init): self.sgmodeOffRB.SetValue(True) else: self.sgmodeToggleRB.SetValue(True) - -####### Target Custom -class TargetCustomCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetCustomSizer = wx.GridBagSizer(5,5) - targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), - flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) - self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetCustomModeChoice.SetSelection(0) - targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) - self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) - self.targetCustomOptionalName.SetHint("Optional name to match") - targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) - self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") - targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) - self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") - targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) - self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") - targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) - self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") - targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) - self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") - targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) - self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") - targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) - self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") - targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) - self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") - targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) - - targetCustomSizer.AddGrowableCol(2) - - return targetCustomSizer - - def MakeBindString(self): - choice = self.targetCustomModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - targetCommand = "targetcustom" + mode.lower() - - enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" - friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" - defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" - alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" - mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" - notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" - base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" - notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" - - name = self.targetCustomOptionalName.GetValue() - - return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" - - def Serialize(self): - return { - 'mode' : self.targetCustomModeChoice.GetSelection(), - 'enemy' : self.targetCustomCBEnemies. IsChecked(), - 'friend' : self.targetCustomCBFriends. IsChecked(), - 'defeated' : self.targetCustomCBDefeated. IsChecked(), - 'alive' : self.targetCustomCBAlive. IsChecked(), - 'mypet' : self.targetCustomCBMyPets. IsChecked(), - 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), - 'base' : self.targetCustomCBBaseItems. IsChecked(), - 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), - 'name' : self.targetCustomOptionalName.GetValue(), - } - - def Deserialize(self, init): - if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) - if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) - if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) - if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) - if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) - if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) - if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) - if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) - if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) - if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - - -####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) - targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetEnemyModeChoice.SetSelection(0) - targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetEnemySizer - - def MakeBindString(self): - choice = self.targetEnemyModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetenemy" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetEnemyModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) - -####### Target Friend -class TargetFriendCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) - targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetFriendModeChoice.SetSelection(0) - targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetFriendSizer - - def MakeBindString(self): - choice = self.targetFriendModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetfriend" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetFriendModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) - -####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): - def BuildUI(self, dialog): - teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], - style=wx.ALIGN_CENTER_VERTICAL) - self.teamPetSelectNumber.SetSelection(0) - teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) - - return teamPetSelectSizer - - def MakeBindString(self): - teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' - targetNumber = self.teamPetSelectNumber.GetSelection()+1 - - return f"{teamOrPet}select {targetNumber}" - - def Serialize(self): - return { - 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', - 'targetNum': self.teamPetSelectNumber.GetSelection(), - } - - def Deserialize(self, init): - ToP = init.get('teamOrPet', '') - if ToP == 'pet': - self.teamPetSelectPetRB.SetValue(True) - else: - self.teamPetSelectTeamRB.SetValue(True) - if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) - -####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' - -####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) - for _, types in GameData.Inspirations.items(): - for _, info in types.items(): - for insp in info['tiers']: - name = re.sub(' ', '', str(insp)) - icon = GetIcon(f'Inspirations/{name}') - self.useInspByNameModeChoice.Append(insp, icon) - self.useInspByNameModeChoice.SetSelection(0) - useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) - - return useInspByNameSizer - - def MakeBindString(self): - choice = self.useInspByNameModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "inspexecname " + mode.lower() - - def GetAllInsps(self): - Insplist = [] - for _, info in GameData.Inspirations.items(): - for insp in info['tiers']: - Insplist.append(insp) - Insplist.append("---") - Insplist.pop(-1) # snip the terminal "---" - - return Insplist - - def Serialize(self): - return { 'insp' : self.useInspByNameModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) - -####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnRow.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) - self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnCol.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) - - return useInspRowColumnSizer - - def MakeBindString(self): - row = self.useInspRowColumnRow.GetSelection()+1 - col = self.useInspRowColumnCol.GetSelection()+1 - - return f"inspexectray {col} {row}" - - def Serialize(self): - return { - 'col' : self.useInspRowColumnCol.GetSelection(), - 'row' : self.useInspRowColumnRow.GetSelection(), - } - - def Deserialize(self, init): - if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) - if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) - -####### Use Power -class UsePowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - outerSizer = wx.BoxSizer(wx.HORIZONTAL) - - usePowerSizer = wx.GridBagSizer(5,5) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBToggle, (0,1)) - self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOn, (0,2)) - self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOff, (0,3)) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerName = PowerPicker(dialog) - usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) - usePowerSizer.AddGrowableCol(3) - - outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) - - return outerSizer - - def MakeBindString(self): - if self.usePowerRBToggle.GetValue(): - method = "powexecname" - elif self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') - return '' - - return f"{method} {self.usePowerName.GetLabel()}" - - def Serialize(self): - if self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - method = "powexecname" - return { - 'method': method, - 'pname' : self.usePowerName.GetLabel(), - 'picon' : self.usePowerName.IconFilename - } - - def Deserialize(self, init): - method = init.get('method', '') - if method == 'powexectoggleon': - self.usePowerRBOn.SetValue(True) - elif method == 'powexectoggleoff': - self.usePowerRBOff.SetValue(True) - else: - self.usePowerRBToggle.SetValue(True) - if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) - -####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): - def BuildUI(self, dialog): - usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTrayTray = wx.Choice(dialog, -1, - choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', - 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) - self.usePowerFromTrayTray.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) - self.usePowerFromTraySlot.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return usePowerFromTraySizer - - def MakeBindString(self): - choice = self.usePowerFromTrayTray - tray = choice.GetSelection() - - choice = self.usePowerFromTraySlot - slot = choice.GetSelection()+1 - - mode = "slot" - mode2 = '' - if tray > 3: - mode = "tray" - mode2 = f" {tray - 3}" - elif tray == 3: - mode = "alt2slot" - elif tray == 2: - mode = "altslot" - - return f"powexec{mode} {slot}{mode2}" - - def Serialize(self): - return { - 'tray' : self.usePowerFromTrayTray.GetSelection(), - 'slot' : self.usePowerFromTraySlot.GetSelection(), - } - - def Deserialize(self, init): - if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) - if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) - -####### Window Color -class WindowColorCmd(PowerBindCmd): - def BuildUI(self, dialog): - windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) - borderSizer = wx.BoxSizer(wx.VERTICAL) - self.ColorBorder.SetSizer(borderSizer) - self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) - borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) - - windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) - - RGBASizer = wx.FlexGridSizer(3, 4, 5) - - RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) - self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) - self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - windowColorSizer.Add(RGBASizer) - - self.UpdateFromSlider() - - return windowColorSizer - - def MakeBindString(self): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - return f"windowcolor {Rval} {Gval} {Bval} {Aval}" - - def Serialize(self): - return { - 'Rval' : self.RSlider.GetValue(), - 'Gval' : self.GSlider.GetValue(), - 'Bval' : self.BSlider.GetValue(), - 'Aval' : self.ASlider.GetValue(), - } - - def Deserialize(self, init): - self.RSlider.SetValue(init['Rval']) - self.GSlider.SetValue(init['Gval']) - self.BSlider.SetValue(init['Bval']) - self.ASlider.SetValue(init['Aval']) - self.UpdateFromSlider() - - def UpdateFromSlider(self, _ = None): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RReadout.SetValue(Rval) - self.GReadout.SetValue(Gval) - self.BReadout.SetValue(Bval) - self.AReadout.SetValue(Aval) - self.ColorBorder.Refresh() - - def UpdateFromText(self, _ = None): - Rval = self.RReadout.GetValue() - Gval = self.GReadout.GetValue() - Bval = self.BReadout.GetValue() - Aval = self.AReadout.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RSlider.SetValue(Rval) - self.GSlider.SetValue(Gval) - self.BSlider.SetValue(Bval) - self.ASlider.SetValue(Aval) - self.ColorBorder.Refresh() - -####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) - self.CommandChoice.SetSelection(0) - sizer.Add(self.CommandChoice, 0, wx.ALL, 5) - - self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), - value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) - sizer.Add(self.FilePath, 0, wx.ALL, 5) - - return sizer - - def MakeBindString(self): - command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] - return f'{command} "{self.FilePath.GetValue()}"' - - def Serialize(self): - return { - 'command' : self.CommandChoice.GetSelection(), - 'filename' : self.FilePath.GetValue(), - } - - def Deserialize(self, init): - self.CommandChoice.SetSelection(init.get('command', 0)) - self.FilePath.SetValue(init.get('filename', '')) - -####### Window Toggle -class WindowToggleCmd(PowerBindCmd): - def BuildUI(self, dialog): - self.WindowNames = { - 'Actions' : 'actions', - 'Auction House' : 'ah', - 'Badge' : 'badge', - 'Channel Search' : 'chansearch', - 'Chat' : 'chat', - 'Custom Chat 1' : 'chat1', - 'Custom Chat 2' : 'chat2', - 'Custom Chat 3' : 'chat3', - 'Custom Chat 4' : 'chat4', - 'Clues' : 'clue', - 'Combat Numbers' : 'combatnumbers', - 'Contacts' : 'contact', - 'Contact Finder' : 'contactfinder', - 'Costumes' : 'costume', - 'Email' : 'email', - 'Enhancements' : 'enhancements', - 'Friends' : 'friend', - 'Group' : 'group', - 'Help' : 'helpwindow', - 'Incarnate' : 'incarnate', - 'Inspirations' : 'insp', - 'League' : 'league', - 'LFG' : 'lfg', - 'Map' : 'map', - 'Mission' : 'mission', - 'Nav / Compass' : 'nav', - 'Options' : 'options', - 'Pets' : 'pet', - 'Petition' : 'petition', - 'Power Tray' : 'powers', - 'Power List' : 'powerlist', - 'Quit' : 'quit', - 'Recipes' : 'recipe', - 'Salvage' : 'salvage', - 'Search' : 'search', - 'Supergroup' : 'sg', - 'Target' : 'target', - 'Team' : 'team', - 'Tray' : 'tray', - 'Tray1' : 'tray1', - 'Tray2' : 'tray2', - 'Tray3' : 'tray3', - 'Tray4' : 'tray4', - 'Tray5' : 'tray5', - 'Tray6' : 'tray6', - 'Tray7' : 'tray7', - 'Tray8' : 'tray8', - 'Vault' : 'vault', - } - - self.ShortToggleCommands = { - 'Auction House' : 'ah', - 'Chat' : 'chat', - 'Help' : 'helpwindow', - 'Map' : 'map', - 'Nav / Compass' : 'nav', - 'Power Tray' : 'powers', - 'Target' : 'target', - 'Tray' : 'tray', - } - - windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) - windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) - self.windowToggleTray.SetSelection(0) - windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.windowShowRB = wx.RadioButton(dialog, -1, "Show") - self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") - - windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) - - return windowToggleSizer - - def MakeBindString(self): - choice = self.windowToggleTray - index = choice.GetSelection() - windowdesc = choice.GetString(index) - windowname = self.WindowNames[windowdesc] - - if self.windowShowRB.GetValue(): - return 'show ' + windowname - elif self.windowHideRB.GetValue(): - return 'windowhide ' + windowname - else: - if shortcmd := self.ShortToggleCommands.get(windowdesc, None): - return shortcmd - else: - return 'toggle ' + windowname - - - def Serialize(self): - choice = self.windowToggleTray - if self.windowShowRB.GetValue(): - action = "Show" - elif self.windowHideRB.GetValue(): - action = "Hide" - else: - action = "Toggle" - return { - 'window': choice.GetString(choice.GetSelection()), - 'action': action, - } - - def Deserialize(self, init): - choice = self.windowToggleTray - if window := init.get('window', ''): - if isinstance(window, int): - choice.SetSelection(window) - else: - choice.SetSelection(choice.FindString(window)) - - if choice.GetSelection() == wx.NOT_FOUND: - choice.SetSelection(0) - - action = init.get('action', '') - if action == "Show": - self.windowShowRB.SetValue(True) - elif action == "Hide": - self.windowHideRB.SetValue(True) - else: - self.windowToggleRB.SetValue(True) - - -# Must always add to this list when adding a new command class above -menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], - # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, - # but I'm leaving it here to remind myself that we do that. - } - -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/TargetCustomCmd.py b/UI/PowerBinderCommand/TargetCustomCmd.py index 4c02ab7..96261b7 100644 --- a/UI/PowerBinderCommand/TargetCustomCmd.py +++ b/UI/PowerBinderCommand/TargetCustomCmd.py @@ -1,1112 +1,11 @@ import wx -import re -import UI -import UI.EmotePicker -from UI.ControlGroup import ControlGroup -from UI.PowerPicker import PowerPicker -from Help import HelpButton -import wx.adv -from wx.adv import BitmapComboBox, EditableListBox -from pathlib import PureWindowsPath -import GameData -import Profile -from Icon import GetIcon - -class PowerBinderDialog(wx.Dialog): - def __init__(self, parent, button, init = {}): - wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) - - self.Page = parent.Page - self.EditDialog = PowerBinderEditDialog(self) - self.Button = button - self.AddStepMenu = self.makeAddStepMenu() - - sizer = wx.BoxSizer(wx.VERTICAL); - self.mainSizer = sizer - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) - AddStepButton = wx.Button(self, -1, 'Add Step') - AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) - AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) - choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) - choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) - sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) - - rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) - - self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) - self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) - self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) - rearrangeCtrl.Add(self.RearrangeList, 1) - - rearrangeButtons = wx.BoxSizer(wx.VERTICAL) - self.DelButton = wx.Button(self, -1, "Delete") - self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) - self.EditButton = wx.Button(self, -1, "Edit") - self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) - self.EditButton.Disable() - upButton = wx.Button(self, -1, "\u25B2") - upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) - downButton = wx.Button(self, -1, "\u25BC") - downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) - rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) - rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) - - sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.BindStringDisplay = wx.TextCtrl(self, -1) - self.BindStringDisplay.Disable() - choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, - wx.ALIGN_CENTER_VERTICAL) - choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) - - sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) - - sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) - - # need to dig around and get the OK button since we show this dialog modelessly now. - okButton = self.FindWindow(self.GetAffirmativeId()) - okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) - - # Wrap everything in a vbox to add some padding - vbox = wx.BoxSizer(wx.VERTICAL); - vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); - - self.SetSizerAndFit(vbox); - self.Layout() - self.Fit() - self.SetFocus() - - # if we are loading from profile, ie, have "init", build the list from it - if init: self.LoadFromData(init) - - def LoadFromData(self, init): - for item in init: - for type, data in item.items(): - commandClass = commandClasses.get(type, None) - if not commandClass: - commandClass = deprecatedCommandClasses.get(type, None) - if not commandClass: - wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") - continue - newCommand = commandClass(self.EditDialog, data) - index = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.SetClientData(index, newCommand) - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) - self.EditDialog.mainSizer.Hide(newCommand.UI) - self.UpdateBindStringDisplay() - - def SaveToData(self): - data = [] - index = 0 - for _ in self.RearrangeList.GetItems(): - # check whether we have an object already attached to this choice - cmdObject = self.RearrangeList.GetClientData(index) - commandClassName = commandRevClasses[type(cmdObject)] - data.append({commandClassName: cmdObject.Serialize()}) - index = index + 1 - return data - - def OnAddStepButton(self, evt): - button = evt.EventObject - if not self.AddStepMenu: - self.AddStepMenu = self.makeAddStepMenu() - button.PopupMenu(self.AddStepMenu) - - - def OnOKButton(self, _): - if self.Button.tgtTxtCtrl: - bindString = self.MakeBindString() - if bindString != self.Button.tgtTxtCtrl.GetValue(): - self.Button.tgtTxtCtrl.SetValue(bindString) - wx.App.Get().Main.Profile.SetModified() - self.Close() - - def OnRearrangeDelete(self, _): - current = self.RearrangeList.GetSelection() - if current == wx.NOT_FOUND: return - - self.RearrangeList.Delete(current) - self.UpdateBindStringDisplay() - - def OnRearrangeUp(self, _): - self.RearrangeList.MoveCurrentUp() - self.UpdateBindStringDisplay() - - def OnRearrangeDown(self, _): - self.RearrangeList.MoveCurrentDown() - self.UpdateBindStringDisplay() - - def OnRearrangeEdit(self, _): - index = self.RearrangeList.GetSelection() - - # check whether we have an object already attached to this choice - cmdObject = None - try: - cmdObject = self.RearrangeList.GetClientData(index) - except Exception: - pass - - if cmdObject: - self.ShowEditDialogFor(cmdObject) - self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) - else: - print("cmdObject was None") - self.UpdateBindStringDisplay() - - # OnAddStepMenu creates a new step and adds it to the rearrangelist - def OnAddStepMenu(self, evt): - menuitem = self.AddStepMenu.FindItemById(evt.GetId()) - chosenName = menuitem.GetItemLabel() - - # make a new command object, attached to the parent dialog - newCommandClass = commandClasses[chosenName] - newCommand = newCommandClass(self.EditDialog) - - # show the edit dialog if this command needs it - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) - if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): - self.EditDialog.mainSizer.Remove(newCommand.UI) - return - - newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.Select(newBindIndex) - self.RearrangeList.SetClientData(newBindIndex, newCommand) - - self.OnListSelect() - self.UpdateBindStringDisplay() - - def OnListSelect(self, _ = None): - selected = self.RearrangeList.GetSelection() - - if selected != wx.NOT_FOUND: - selCommand = self.RearrangeList.GetClientData(selected) - if selCommand.UI: - self.EditButton.Enable() - else: - self.EditButton.Disable() - - def UpdateBindStringDisplay(self): - self.BindStringDisplay.SetValue(self.MakeBindString()) - self.BindStringDisplay.SetToolTip(self.MakeBindString()) - - def MakeBindString(self): - cmdBindStrings = [] - for index in range(self.RearrangeList.GetCount()): - c = self.RearrangeList.GetClientData(index) - if c: cmdBindStrings.append(c.MakeBindString()) - - bindstring = ('$$'.join(cmdBindStrings)) - return bindstring - - def ShowEditDialogFor(self, command): - if not command.UI: return - - self.EditDialog.mainSizer.Show(command.UI) - - self.EditDialog.Layout() - self.EditDialog.Fit() - - self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') - returnval = self.EditDialog.ShowModal() - - self.EditDialog.mainSizer.Hide(command.UI) - - return returnval - - def makeAddStepMenu(self): - - stepMenu = wx.Menu() - - for subname in menuStructure: - submenu = wx.Menu() - stepMenu.AppendSubMenu(submenu, subname) - for classname in menuStructure[subname]: - submenu.Append(wx.ID_ANY, classname) - - stepMenu.Append(wx.ID_ANY, 'Custom Bind') - - return stepMenu - -class PowerBinderButton(wx.BitmapButton): - - def __init__(self, parent, tgtTxtCtrl, init = {}): - wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) - self.Init = init - self.Dialog = None - self.DialogParent = parent - - self.tgtTxtCtrl = tgtTxtCtrl - self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) - self.SetToolTip("Launch PowerBinder") - - def PowerBinderEventHandler(self, _): - self.PowerBinderDialog().Show() - - def LoadFromData(self, data): - self.PowerBinderDialog().LoadFromData(data) - - def SaveToData(self): - return self.PowerBinderDialog().SaveToData() - - def PowerBinderDialog(self): - if not self.Dialog: - self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) - return self.Dialog - - -class PowerBinderEditDialog(wx.Dialog): - def __init__(self, parent): - wx.Dialog.__init__(self, parent, -1, "Edit Step", - style = wx.DEFAULT_DIALOG_STYLE) - - outerSizer = wx.BoxSizer(wx.VERTICAL) - - self.mainSizer = wx.BoxSizer(wx.VERTICAL) - self.mainSizer.SetMinSize([500, 150]) - - self.Page = parent.Page - - self.mainSizer.Add( - self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), - 0, wx.EXPAND|wx.ALL, 10) - - outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) - - self.SetSizerAndFit(outerSizer) - self.Layout() - self.Fit() - -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" - - -####### Away From Keyboard -class AFKCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.Groups = {} - self.AttributeTable = { - 'Base' : { - 'Current Hit Points' : 'NT H', - 'Max Hit Points' : 'X H', - 'Current Endurance' : 'T E', - 'Max Endurance' : 'X EN', - 'Regeneration Rate' : 'N RAT', - 'Recovery Rate' : 'Y RA', - 'Endurance Consumption' : 'SU', - 'ToHit Bonus' : 'T B', - 'Accuracy Bonus' : 'CC', - 'Last Hit Chance' : 'T C', - 'Damage Bonus' : 'DA', - 'Healing Bonus' : 'NG B', - 'Recharge Time Bonus' : 'ME B', - 'Endurance Discount' : 'CE DIS', - 'Stealth Radius (PvP)' : 'PVP', - 'Stealth Radius (PvE)' : 'PVE', - 'Perception Radius' : 'RC', - 'Range Bonus' : 'GE B', - 'Threat Level' : 'AT L', - 'Experience to Next Level' : 'XT', - 'Experience Debt' : 'XP', - 'Influence / Infamy' : 'INF', - 'Inherent' : 'NH', - }, - 'Movement Speed' : { - 'Flying Speed' : 'FL', - 'Jumping Speed' : 'PI', - 'Max Jump Height' : 'X J', - 'Run Speed' : 'RU', - }, - 'Damage Resistance' : { - 'Smashing Resistance' : 'G R', - 'Lethal Resistance' : 'L R', - 'Fire Resistance' : 'RE R', - 'Cold Resistance' : 'COLD R', - 'Energy Resistance' : 'DamageType[4]', - 'Negative Energy Resistance' : 'GY R', - 'Psyonic Resistance' : 'NIC R', - 'Toxic Resistance' : 'XIC R', - }, - 'Defense' : { - 'Base Defense' : 'BAS', - 'Ranged Defense' : 'ED', - 'Melee Defense' : 'MEL', - 'AoE Defense' : '2', - 'Smashing Defense' : '3', - 'Lethal Defense' : '4', - 'Fire Defense' : '5', - 'Cold Defense' : '6', - 'Energy Defense' : '7', - 'Negative Energy Defense' : '8', - 'Psionic Defense' : '9', - 'Toxic Defense' : '1', - }, - 'Debuff Resistance' : { - 'Regeneration Resistance' : 'ON R', - 'Recovery Resistance' : 'RY R', - 'To Hit Resistance' : 'IT R', - 'Defense Resistance' : 'NSE RES', - }, - 'Status Effect Protection' : { - 'Hold Protection' : 'D P', - 'Immobilize Protection' : 'LIZE P', - 'Stun Protection' : 'N P', - 'Sleep Protection' : 'P P', - 'Knockback Protection' : 'K P', - 'Confuse Protection' : 'SE P', - 'Terrorize Protection' : 'ZE P', - 'Repel Protection' : 'EL P', - 'Teleport Protection' : 'T P', - }, - 'Status Effect Resistance' : { - 'Hold Resistance' : 'D R', - 'Immobilize Resistance' : 'LIZE R', - 'Stun Resistance' : 'N R', - 'Sleep Resistance' : 'P R', - 'Knockback Resistance' : 'K R', - 'Confuse Resistance' : 'SE R', - 'Terrorize Resistance' : 'ZE R', - 'Placate Resistance' : 'TE R', - 'Taunt Resistance' : 'NT R', - }, - 'Miscellaneous' : { - 'Level Shift' : 'L S', - }, - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.AttributeMenu = wx.Menu() - for group, controls in self.AttributeTable.items(): - submenu = wx.Menu() - self.AttributeMenu.AppendSubMenu(submenu, group) - for cb in controls: - submenu.Append(wx.ID_ANY, cb) - - self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) - - self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) - groupSizer.Add(self.editbox) - - newButton = self.editbox.GetNewButton() - newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) - - return groupSizer - - def MakeBindString(self): - map = {} - bindstrings = [] - for _, controls in self.AttributeTable.items(): - for cb, data in controls.items(): - map[cb] = data - - for string in self.editbox.GetStrings(): - if string: - bindstrings.append(f'monitorattribute {map[string]}') - - return '$$'.join(bindstrings) - - def Serialize(self): - return { - 'attributes' : self.editbox.GetStrings() - } - - def Deserialize(self, init): - self.editbox.SetStrings(init.get('attributes', [])) - - def OnNewButton(self, evt): - evt.GetEventObject().PopupMenu(self.AttributeMenu) - - def OnMenuItem(self, evt): - menuitem = evt.EventObject.FindItemById(evt.GetId()) - existingstrings = self.editbox.GetStrings() - existingstrings.append(menuitem.GetItemLabel()) - self.editbox.SetStrings(existingstrings) - -####### Auto Power -class AutoPowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) - autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.autoPowerName = PowerPicker(dialog) - autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) - - return autoPowerSizer - - def MakeBindString(self): - return f"powexecauto {self.autoPowerName.GetLabel()}" - - def Serialize(self): - return { - 'pname' : self.autoPowerName.GetLabel(), - 'picon' : self.autoPowerName.IconFilename - } - - def Deserialize(self, init): - if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.buffDisplayMap = { - 'Status Window' : { - 'Hide Auto' : 1, - 'Hide Toggles' : 2, - 'No Blinking' : 4, - 'No Stacking' : 8, - 'Numeric Stacking' : 16, - 'Hide Buff Numbers' : 32, - 'Stop Sending Buffs' : 64, - }, - 'Group Window' : { - 'Hide Auto' : 256, - 'Hide Toggles' : 512, - 'No Blinking' : 1024, - 'No Stacking' : 2048, - 'Numeric Stacking' : 4096, - 'Hide Buff Numbers' : 8192, - 'Stop Sending Buffs' : 16384, - }, - 'Pet Window' : { - 'Hide Auto' : 65536, - 'Hide Toggles' : 131072, - 'No Blinking' : 262144, - 'No Stacking' : 524288, - 'Numeric Stacking' : 1048576, - 'Hide Buff Numbers' : 2097152, - 'Stop Sending Buffs' : 4194304, - }, - } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - for group, controls in self.buffDisplayMap.items(): - self.Groups[group] = ControlGroup(dialog, self.Page, label = group) - groupid = self.Groups[group].GetStaticBox().GetId() - for cb, data in controls.items(): - self.Groups[group].AddControl( - ctlType = 'checkbox', - ctlName = f"{groupid}_{group}_{cb}", - label = cb, - data = data, - ) - - groupSizer.Add(self.Groups[group]) - - return groupSizer - - def CalculateValue(self): - page = wx.App.Get().Main.Profile.CustomBinds - - total = 0 - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] - if checkbox.IsChecked(): - total = total + checkbox.Data - return total - - def MakeBindString(self): - return f"optionset buffsettings {self.CalculateValue()}" - - def Serialize(self): - return { 'value' : self.CalculateValue() } - - def Deserialize(self, init): - value = init.get('value', 0) - - value = value or 0 # in case we had for some reason 'None' stashed in the init values - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] - checkbox.SetValue( checkbox.Data & value ) - -####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - chatCommandSizer = wx.GridBagSizer(5, 5) - self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") - chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) - # row 1 - self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) - self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) - self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) - # row 2 - self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) - self.chatCommandDuration.SetRange(1, 20) - self.chatCommandDuration.SetValue(7) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandDuration, (2,1)) - self.chatCommandChatSize = wx.Choice(dialog, -1, - choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) - self.chatCommandChatSize.SetSelection(5) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) - self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) - self.chatCommandChannel.SetSelection(0) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChannel, (2,5)) - # row 3 - self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") - chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) - self.chatCommandMessage = wx.TextCtrl(dialog, -1) - self.chatCommandMessage.SetHint('Chat Command Text') - chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) - - return chatCommandSizer - - def MakeBindString(self): - duration = self.chatCommandDuration.GetValue() - - choice = self.chatCommandChatSize - index = choice.GetSelection() - size = choice.GetString(index) - - duration = f"" if duration != 7 else "" - size = f"" if size != "1" else "" - - bdcolor = fgcolor = bgcolor = '' - if self.chatCommandUseColorsCB.IsChecked(): - bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - - bdcolor = f"" - fgcolor = f"" - bgcolor = f"" - - beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' - text = self.chatCommandMessage.GetValue() - - choice = self.chatCommandChannel - index = choice.GetSelection() - channel = choice.GetString(index) - - return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" - - def Serialize(self): - return { - 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), - 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), - 'channel' : self.chatCommandChannel .GetSelection(), - 'size' : self.chatCommandChatSize.GetSelection(), - 'duration' : self.chatCommandDuration.GetValue(), - 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'text' : self.chatCommandMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) - if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) - if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) - if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) - if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) - if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) - if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) - if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) - if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - - -####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): - def BuildUI(self, dialog): - chatCommandGlobalSizer = wx.GridBagSizer(5,5) - - self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") - chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) - - self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalChannel.SetHint("Channel") - chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) - - self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') - chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) - - chatCommandGlobalSizer.AddGrowableCol(1) - - return chatCommandGlobalSizer - - def MakeBindString(self): - useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() - channel = self.chatCommandGlobalChannel.GetValue() - message = self.chatCommandGlobalMessage.GetValue() - - preface = "beginchat /" if useBeginchat else "" - - return f'{preface}send "{channel}" {message}' - - def Serialize(self): - return { - 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), - 'channel' : self.chatCommandGlobalChannel.GetValue(), - 'message' : self.chatCommandGlobalMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) - if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) - if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) - -#######Costume Change -class CostumeChangeCmd(PowerBindCmd): - def BuildUI(self, dialog): - costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeCostume = wx.Choice(dialog, -1, - choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) - self.costumeChangeCostume.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeEmote = wx.Choice(dialog, -1, - choices = GameData.Emotes['costumechange']) - self.costumeChangeEmote.Insert("- None -", 0) - self.costumeChangeEmote.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return costumeChangeSizer - - def MakeBindString(self): - costumeNumber = self.costumeChangeCostume.GetSelection() - costumeEmote = self.costumeChangeEmote.GetSelection() - - if costumeEmote: # None, or 0 == "- None -" - ccCmd = 'cce' - emoteName = self.costumeChangeEmote.GetString(costumeEmote) - emoteName = " CC" + emoteName.replace(" ","") - else: - ccCmd = 'cc' - emoteName = '' - - return f"{ccCmd} {costumeNumber}{emoteName}" - - def Serialize(self): - return{ - 'costumeNumber': self.costumeChangeCostume.GetSelection(), - 'costumeEmote' : self.costumeChangeEmote.GetSelection(), - } - - def Deserialize(self, init): - if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) - if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) - -####### Movement Command -class MovementCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - self.plusbutton.SetValue(True) - - self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.commandchoice = wx.Choice(dialog, choices = [ - "forward", "left", "right", "backward", "up", "down", - "turnleft", "turnright", "first", "autorun", "clicktomove", - ],) - sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) - self.commandchoice.SetSelection(0) - - self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - pre = post = '' - if self.plusbutton.GetValue() : pre = "+" - elif self.plusplusbutton.GetValue() : pre = "++" - elif self.minusbutton.GetValue() : pre = "-" - elif self.zerobutton.GetValue() : post = " 0" - elif self.onebutton.GetValue() : post = " 1" - - command = self.commandchoice.GetString(self.commandchoice.GetSelection()) - - return f"{pre}{command}{post}" - - def Serialize(self): - mod = '' - if self.plusbutton.GetValue() : mod = "plus" - elif self.plusplusbutton.GetValue() : mod = "plusplus" - elif self.minusbutton.GetValue() : mod = "minus" - elif self.zerobutton.GetValue() : mod = "zero" - elif self.onebutton.GetValue() : mod = "one" - - return { - 'mod' : mod, - 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), - } - - def Deserialize(self, init): - mod = init.get('mod', 'plus') - - if mod == 'plus' : self.plusbutton.SetValue(True) - elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) - elif mod == 'minus' : self.minusbutton.SetValue(True) - elif mod == 'zero' : self.zerobutton.SetValue(True) - elif mod == 'one' : self.onebutton.SetValue(True) - - self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) - -####### Graphics Command -class GraphicsCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.FlexGridSizer(2) - - self.visscalecb = wx.CheckBox(dialog, label = "visscale") - sizer.Add(self.visscalecb) - self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) - sizer.Add(self.visscalesc) - - self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") - sizer.Add(self.dofweightcb) - self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) - sizer.Add(self.dofweightsc) - - self.fsaacb = wx.CheckBox(dialog, label = "fsaa") - sizer.Add(self.fsaacb) - self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) - self.fsaach.SetSelection(0) - sizer.Add(self.fsaach) - - self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") - sizer.Add(self.bloomscalecb) - self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) - self.bloomscalech.SetSelection(0) - sizer.Add(self.bloomscalech) - - self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") - sizer.Add(self.bloomweightcb) - self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) - sizer.Add(self.bloomweightsc) - - self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") - sizer.Add(self.lodbiascb) - self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) - sizer.Add(self.lodbiassc) - - self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") - sizer.Add(self.renderscalecb) - self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) - sizer.Add(self.renderscalesc) - - return sizer - - def MakeBindString(self): - # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. - bindstrings = [] - if self.visscalecb.IsChecked(): - bindstrings.append("visscale " + str(self.visscalesc.GetValue())) - if self.dofweightcb.IsChecked(): - bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) - if self.fsaacb.IsChecked(): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bindstrings.append("fsaa " + fsaavalue) - if self.bloomscalecb.IsChecked(): - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - bindstrings.append("bloomscale " + bloomscalevalue) - if self.bloomweightcb.IsChecked(): - bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) - if self.lodbiascb.IsChecked(): - bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) - if self.renderscalecb.IsChecked(): - bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) - - return '$$'.join(bindstrings) - - def Serialize(self): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - return { - 'visscalecb' : self.visscalecb.IsChecked(), - 'visscalesc' : self.visscalesc.GetValue(), - 'dofweightcb' : self.dofweightcb.IsChecked(), - 'dofweightsc' : self.dofweightsc.GetValue(), - 'fsaacb' : self.fsaacb.IsChecked(), - 'fsaach' : fsaavalue, - 'bloomscalecb' : self.bloomscalecb.IsChecked(), - 'bloomscalech' : bloomscalevalue, - 'bloomweightcb' : self.bloomweightcb.IsChecked(), - 'bloomweightsc' : self.bloomweightsc.GetValue(), - 'lodbiascb' : self.lodbiascb.IsChecked(), - 'lodbiassc' : self.lodbiassc.GetValue(), - 'renderscalecb' : self.renderscalecb.IsChecked(), - 'renderscalesc' : self.renderscalesc.GetValue(), - } - - def Deserialize(self, init): - self.visscalecb.SetValue(init.get('visscalecb', False)) - self.visscalesc.SetValue(init.get('visscalesc', 1.0)) - self.dofweightcb.SetValue(init.get('dofweightcb', False)) - self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) - self.fsaacb.SetValue(init.get('fsaacb', False)) - self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) - self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) - self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) - self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) - self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) - self.lodbiascb.SetValue(init.get('lodbiascb', False)) - self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) - self.renderscalecb.SetValue(init.get('renderscalecb', False)) - self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) - -####### Custom Bind -class CustomBindCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.customBindName = wx.TextCtrl(dialog, -1) - self.customBindName.SetHint('Custom Bind Text') - sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - return self.customBindName.GetValue() - - def Serialize(self): - return { 'customBindName': self.customBindName.GetValue() } - - def Deserialize(self,init): - if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) - -####### Emote -class EmoteCmd(PowerBindCmd): - def BuildUI(self, dialog): - emoteSizer = wx.BoxSizer(wx.HORIZONTAL) - self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") - emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - self.emoteName = wx.Button(dialog, -1, "...") - self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) - emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) - - return emoteSizer - - def MakeBindString(self): - displayedEmoteName = self.emoteName.GetLabel() - actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] - - return actualEmotePayload - - def Serialize(self): - return {'emoteName': self.emoteName.GetLabel()} - - def Deserialize(self, init): - if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) - -####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): - def BuildUI(self, dialog): - mainSizer = wx.BoxSizer(wx.VERTICAL) - - lbSizer = wx.BoxSizer(wx.HORIZONTAL) - lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") - lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - profiles = Profile.GetAllProfileBindsDirs() - - self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) - lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) - - mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") - self.lbResetCB.SetValue(True) - - mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - return mainSizer - - def MakeBindString(self): - - # If the specified binds directory disappeared between runs, we'd crash, so handle that. - if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' - - config = wx.ConfigBase.Get() - if config.Exists('GameBindPath'): - bindpath = config.Read('GameBindPath') - else: - bindpath = config.Read('BindPath') - - reset = "" - if self.lbResetCB.GetValue(): - reset = "keybind_reset$$" - - resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' - return reset + 'bindloadfile ' + str(resetfilepath) - - def Serialize(self): - return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), - 'ResetKeybinds' : self.lbResetCB.GetValue(), - } - - def Deserialize(self, init): - if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) - self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) - -####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' - -####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' - -####### SG Mode -class SGModeCmd(PowerBindCmd): - def BuildUI(self, dialog): - sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) - sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") - self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") - - sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) - - return sgmodeSizer - - def MakeBindString(self): - if self.sgmodeOnRB.GetValue(): - return 'sgmodeset 1' - elif self.sgmodeOffRB.GetValue(): - return 'sgmodeset 0' - else: - return 'sgmode' - - def Serialize(self): - if self.sgmodeOnRB.GetValue(): - val = "On" - elif self.sgmodeOffRB.GetValue(): - val = "Off" - else: - val = "Toggle" - - return {"value" : val} - - def Deserialize(self, init): - val = init.get('value', '') - if val == "On": - self.sgmodeOnRB.SetValue(True) - elif val == "Off": - self.sgmodeOffRB.SetValue(True) - else: - self.sgmodeToggleRB.SetValue(True) +from UI.PowerBinderCommand import PowerBinderCommand ####### Target Custom -class TargetCustomCmd(PowerBindCmd): +class TargetCustomCmd(PowerBinderCommand): + Name = "Target Custom" + Menu = "Targeting" + def BuildUI(self, dialog): targetCustomSizer = wx.GridBagSizer(5,5) targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), @@ -1182,619 +81,3 @@ def Deserialize(self, init): if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - - -####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) - targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetEnemyModeChoice.SetSelection(0) - targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetEnemySizer - - def MakeBindString(self): - choice = self.targetEnemyModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetenemy" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetEnemyModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) - -####### Target Friend -class TargetFriendCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) - targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetFriendModeChoice.SetSelection(0) - targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetFriendSizer - - def MakeBindString(self): - choice = self.targetFriendModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetfriend" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetFriendModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) - -####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): - def BuildUI(self, dialog): - teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], - style=wx.ALIGN_CENTER_VERTICAL) - self.teamPetSelectNumber.SetSelection(0) - teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) - - return teamPetSelectSizer - - def MakeBindString(self): - teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' - targetNumber = self.teamPetSelectNumber.GetSelection()+1 - - return f"{teamOrPet}select {targetNumber}" - - def Serialize(self): - return { - 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', - 'targetNum': self.teamPetSelectNumber.GetSelection(), - } - - def Deserialize(self, init): - ToP = init.get('teamOrPet', '') - if ToP == 'pet': - self.teamPetSelectPetRB.SetValue(True) - else: - self.teamPetSelectTeamRB.SetValue(True) - if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) - -####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' - -####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) - for _, types in GameData.Inspirations.items(): - for _, info in types.items(): - for insp in info['tiers']: - name = re.sub(' ', '', str(insp)) - icon = GetIcon(f'Inspirations/{name}') - self.useInspByNameModeChoice.Append(insp, icon) - self.useInspByNameModeChoice.SetSelection(0) - useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) - - return useInspByNameSizer - - def MakeBindString(self): - choice = self.useInspByNameModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "inspexecname " + mode.lower() - - def GetAllInsps(self): - Insplist = [] - for _, info in GameData.Inspirations.items(): - for insp in info['tiers']: - Insplist.append(insp) - Insplist.append("---") - Insplist.pop(-1) # snip the terminal "---" - - return Insplist - - def Serialize(self): - return { 'insp' : self.useInspByNameModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) - -####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnRow.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) - self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnCol.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) - - return useInspRowColumnSizer - - def MakeBindString(self): - row = self.useInspRowColumnRow.GetSelection()+1 - col = self.useInspRowColumnCol.GetSelection()+1 - - return f"inspexectray {col} {row}" - - def Serialize(self): - return { - 'col' : self.useInspRowColumnCol.GetSelection(), - 'row' : self.useInspRowColumnRow.GetSelection(), - } - - def Deserialize(self, init): - if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) - if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) - -####### Use Power -class UsePowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - outerSizer = wx.BoxSizer(wx.HORIZONTAL) - - usePowerSizer = wx.GridBagSizer(5,5) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBToggle, (0,1)) - self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOn, (0,2)) - self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOff, (0,3)) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerName = PowerPicker(dialog) - usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) - usePowerSizer.AddGrowableCol(3) - - outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) - - return outerSizer - - def MakeBindString(self): - if self.usePowerRBToggle.GetValue(): - method = "powexecname" - elif self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') - return '' - - return f"{method} {self.usePowerName.GetLabel()}" - - def Serialize(self): - if self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - method = "powexecname" - return { - 'method': method, - 'pname' : self.usePowerName.GetLabel(), - 'picon' : self.usePowerName.IconFilename - } - - def Deserialize(self, init): - method = init.get('method', '') - if method == 'powexectoggleon': - self.usePowerRBOn.SetValue(True) - elif method == 'powexectoggleoff': - self.usePowerRBOff.SetValue(True) - else: - self.usePowerRBToggle.SetValue(True) - if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) - -####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): - def BuildUI(self, dialog): - usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTrayTray = wx.Choice(dialog, -1, - choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', - 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) - self.usePowerFromTrayTray.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) - self.usePowerFromTraySlot.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return usePowerFromTraySizer - - def MakeBindString(self): - choice = self.usePowerFromTrayTray - tray = choice.GetSelection() - - choice = self.usePowerFromTraySlot - slot = choice.GetSelection()+1 - - mode = "slot" - mode2 = '' - if tray > 3: - mode = "tray" - mode2 = f" {tray - 3}" - elif tray == 3: - mode = "alt2slot" - elif tray == 2: - mode = "altslot" - - return f"powexec{mode} {slot}{mode2}" - - def Serialize(self): - return { - 'tray' : self.usePowerFromTrayTray.GetSelection(), - 'slot' : self.usePowerFromTraySlot.GetSelection(), - } - - def Deserialize(self, init): - if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) - if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) - -####### Window Color -class WindowColorCmd(PowerBindCmd): - def BuildUI(self, dialog): - windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) - borderSizer = wx.BoxSizer(wx.VERTICAL) - self.ColorBorder.SetSizer(borderSizer) - self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) - borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) - - windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) - - RGBASizer = wx.FlexGridSizer(3, 4, 5) - - RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) - self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) - self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - windowColorSizer.Add(RGBASizer) - - self.UpdateFromSlider() - - return windowColorSizer - - def MakeBindString(self): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - return f"windowcolor {Rval} {Gval} {Bval} {Aval}" - - def Serialize(self): - return { - 'Rval' : self.RSlider.GetValue(), - 'Gval' : self.GSlider.GetValue(), - 'Bval' : self.BSlider.GetValue(), - 'Aval' : self.ASlider.GetValue(), - } - - def Deserialize(self, init): - self.RSlider.SetValue(init['Rval']) - self.GSlider.SetValue(init['Gval']) - self.BSlider.SetValue(init['Bval']) - self.ASlider.SetValue(init['Aval']) - self.UpdateFromSlider() - - def UpdateFromSlider(self, _ = None): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RReadout.SetValue(Rval) - self.GReadout.SetValue(Gval) - self.BReadout.SetValue(Bval) - self.AReadout.SetValue(Aval) - self.ColorBorder.Refresh() - - def UpdateFromText(self, _ = None): - Rval = self.RReadout.GetValue() - Gval = self.GReadout.GetValue() - Bval = self.BReadout.GetValue() - Aval = self.AReadout.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RSlider.SetValue(Rval) - self.GSlider.SetValue(Gval) - self.BSlider.SetValue(Bval) - self.ASlider.SetValue(Aval) - self.ColorBorder.Refresh() - -####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) - self.CommandChoice.SetSelection(0) - sizer.Add(self.CommandChoice, 0, wx.ALL, 5) - - self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), - value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) - sizer.Add(self.FilePath, 0, wx.ALL, 5) - - return sizer - - def MakeBindString(self): - command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] - return f'{command} "{self.FilePath.GetValue()}"' - - def Serialize(self): - return { - 'command' : self.CommandChoice.GetSelection(), - 'filename' : self.FilePath.GetValue(), - } - - def Deserialize(self, init): - self.CommandChoice.SetSelection(init.get('command', 0)) - self.FilePath.SetValue(init.get('filename', '')) - -####### Window Toggle -class WindowToggleCmd(PowerBindCmd): - def BuildUI(self, dialog): - self.WindowNames = { - 'Actions' : 'actions', - 'Auction House' : 'ah', - 'Badge' : 'badge', - 'Channel Search' : 'chansearch', - 'Chat' : 'chat', - 'Custom Chat 1' : 'chat1', - 'Custom Chat 2' : 'chat2', - 'Custom Chat 3' : 'chat3', - 'Custom Chat 4' : 'chat4', - 'Clues' : 'clue', - 'Combat Numbers' : 'combatnumbers', - 'Contacts' : 'contact', - 'Contact Finder' : 'contactfinder', - 'Costumes' : 'costume', - 'Email' : 'email', - 'Enhancements' : 'enhancements', - 'Friends' : 'friend', - 'Group' : 'group', - 'Help' : 'helpwindow', - 'Incarnate' : 'incarnate', - 'Inspirations' : 'insp', - 'League' : 'league', - 'LFG' : 'lfg', - 'Map' : 'map', - 'Mission' : 'mission', - 'Nav / Compass' : 'nav', - 'Options' : 'options', - 'Pets' : 'pet', - 'Petition' : 'petition', - 'Power Tray' : 'powers', - 'Power List' : 'powerlist', - 'Quit' : 'quit', - 'Recipes' : 'recipe', - 'Salvage' : 'salvage', - 'Search' : 'search', - 'Supergroup' : 'sg', - 'Target' : 'target', - 'Team' : 'team', - 'Tray' : 'tray', - 'Tray1' : 'tray1', - 'Tray2' : 'tray2', - 'Tray3' : 'tray3', - 'Tray4' : 'tray4', - 'Tray5' : 'tray5', - 'Tray6' : 'tray6', - 'Tray7' : 'tray7', - 'Tray8' : 'tray8', - 'Vault' : 'vault', - } - - self.ShortToggleCommands = { - 'Auction House' : 'ah', - 'Chat' : 'chat', - 'Help' : 'helpwindow', - 'Map' : 'map', - 'Nav / Compass' : 'nav', - 'Power Tray' : 'powers', - 'Target' : 'target', - 'Tray' : 'tray', - } - - windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) - windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) - self.windowToggleTray.SetSelection(0) - windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.windowShowRB = wx.RadioButton(dialog, -1, "Show") - self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") - - windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) - - return windowToggleSizer - - def MakeBindString(self): - choice = self.windowToggleTray - index = choice.GetSelection() - windowdesc = choice.GetString(index) - windowname = self.WindowNames[windowdesc] - - if self.windowShowRB.GetValue(): - return 'show ' + windowname - elif self.windowHideRB.GetValue(): - return 'windowhide ' + windowname - else: - if shortcmd := self.ShortToggleCommands.get(windowdesc, None): - return shortcmd - else: - return 'toggle ' + windowname - - - def Serialize(self): - choice = self.windowToggleTray - if self.windowShowRB.GetValue(): - action = "Show" - elif self.windowHideRB.GetValue(): - action = "Hide" - else: - action = "Toggle" - return { - 'window': choice.GetString(choice.GetSelection()), - 'action': action, - } - - def Deserialize(self, init): - choice = self.windowToggleTray - if window := init.get('window', ''): - if isinstance(window, int): - choice.SetSelection(window) - else: - choice.SetSelection(choice.FindString(window)) - - if choice.GetSelection() == wx.NOT_FOUND: - choice.SetSelection(0) - - action = init.get('action', '') - if action == "Show": - self.windowShowRB.SetValue(True) - elif action == "Hide": - self.windowHideRB.SetValue(True) - else: - self.windowToggleRB.SetValue(True) - - -# Must always add to this list when adding a new command class above -menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], - # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, - # but I'm leaving it here to remind myself that we do that. - } - -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/TargetEnemyCmd.py b/UI/PowerBinderCommand/TargetEnemyCmd.py index 4c02ab7..a7d1086 100644 --- a/UI/PowerBinderCommand/TargetEnemyCmd.py +++ b/UI/PowerBinderCommand/TargetEnemyCmd.py @@ -1,1191 +1,11 @@ import wx -import re -import UI -import UI.EmotePicker -from UI.ControlGroup import ControlGroup -from UI.PowerPicker import PowerPicker -from Help import HelpButton -import wx.adv -from wx.adv import BitmapComboBox, EditableListBox -from pathlib import PureWindowsPath -import GameData -import Profile -from Icon import GetIcon - -class PowerBinderDialog(wx.Dialog): - def __init__(self, parent, button, init = {}): - wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) - - self.Page = parent.Page - self.EditDialog = PowerBinderEditDialog(self) - self.Button = button - self.AddStepMenu = self.makeAddStepMenu() - - sizer = wx.BoxSizer(wx.VERTICAL); - self.mainSizer = sizer - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) - AddStepButton = wx.Button(self, -1, 'Add Step') - AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) - AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) - choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) - choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) - sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) - - rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) - - self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) - self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) - self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) - rearrangeCtrl.Add(self.RearrangeList, 1) - - rearrangeButtons = wx.BoxSizer(wx.VERTICAL) - self.DelButton = wx.Button(self, -1, "Delete") - self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) - self.EditButton = wx.Button(self, -1, "Edit") - self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) - self.EditButton.Disable() - upButton = wx.Button(self, -1, "\u25B2") - upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) - downButton = wx.Button(self, -1, "\u25BC") - downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) - rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) - rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) - - sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.BindStringDisplay = wx.TextCtrl(self, -1) - self.BindStringDisplay.Disable() - choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, - wx.ALIGN_CENTER_VERTICAL) - choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) - - sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) - - sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) - - # need to dig around and get the OK button since we show this dialog modelessly now. - okButton = self.FindWindow(self.GetAffirmativeId()) - okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) - - # Wrap everything in a vbox to add some padding - vbox = wx.BoxSizer(wx.VERTICAL); - vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); - - self.SetSizerAndFit(vbox); - self.Layout() - self.Fit() - self.SetFocus() - - # if we are loading from profile, ie, have "init", build the list from it - if init: self.LoadFromData(init) - - def LoadFromData(self, init): - for item in init: - for type, data in item.items(): - commandClass = commandClasses.get(type, None) - if not commandClass: - commandClass = deprecatedCommandClasses.get(type, None) - if not commandClass: - wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") - continue - newCommand = commandClass(self.EditDialog, data) - index = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.SetClientData(index, newCommand) - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) - self.EditDialog.mainSizer.Hide(newCommand.UI) - self.UpdateBindStringDisplay() - - def SaveToData(self): - data = [] - index = 0 - for _ in self.RearrangeList.GetItems(): - # check whether we have an object already attached to this choice - cmdObject = self.RearrangeList.GetClientData(index) - commandClassName = commandRevClasses[type(cmdObject)] - data.append({commandClassName: cmdObject.Serialize()}) - index = index + 1 - return data - - def OnAddStepButton(self, evt): - button = evt.EventObject - if not self.AddStepMenu: - self.AddStepMenu = self.makeAddStepMenu() - button.PopupMenu(self.AddStepMenu) - - - def OnOKButton(self, _): - if self.Button.tgtTxtCtrl: - bindString = self.MakeBindString() - if bindString != self.Button.tgtTxtCtrl.GetValue(): - self.Button.tgtTxtCtrl.SetValue(bindString) - wx.App.Get().Main.Profile.SetModified() - self.Close() - - def OnRearrangeDelete(self, _): - current = self.RearrangeList.GetSelection() - if current == wx.NOT_FOUND: return - - self.RearrangeList.Delete(current) - self.UpdateBindStringDisplay() - - def OnRearrangeUp(self, _): - self.RearrangeList.MoveCurrentUp() - self.UpdateBindStringDisplay() - - def OnRearrangeDown(self, _): - self.RearrangeList.MoveCurrentDown() - self.UpdateBindStringDisplay() - - def OnRearrangeEdit(self, _): - index = self.RearrangeList.GetSelection() - - # check whether we have an object already attached to this choice - cmdObject = None - try: - cmdObject = self.RearrangeList.GetClientData(index) - except Exception: - pass - - if cmdObject: - self.ShowEditDialogFor(cmdObject) - self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) - else: - print("cmdObject was None") - self.UpdateBindStringDisplay() - - # OnAddStepMenu creates a new step and adds it to the rearrangelist - def OnAddStepMenu(self, evt): - menuitem = self.AddStepMenu.FindItemById(evt.GetId()) - chosenName = menuitem.GetItemLabel() - - # make a new command object, attached to the parent dialog - newCommandClass = commandClasses[chosenName] - newCommand = newCommandClass(self.EditDialog) - - # show the edit dialog if this command needs it - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) - if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): - self.EditDialog.mainSizer.Remove(newCommand.UI) - return - - newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.Select(newBindIndex) - self.RearrangeList.SetClientData(newBindIndex, newCommand) - - self.OnListSelect() - self.UpdateBindStringDisplay() - - def OnListSelect(self, _ = None): - selected = self.RearrangeList.GetSelection() - - if selected != wx.NOT_FOUND: - selCommand = self.RearrangeList.GetClientData(selected) - if selCommand.UI: - self.EditButton.Enable() - else: - self.EditButton.Disable() - - def UpdateBindStringDisplay(self): - self.BindStringDisplay.SetValue(self.MakeBindString()) - self.BindStringDisplay.SetToolTip(self.MakeBindString()) - - def MakeBindString(self): - cmdBindStrings = [] - for index in range(self.RearrangeList.GetCount()): - c = self.RearrangeList.GetClientData(index) - if c: cmdBindStrings.append(c.MakeBindString()) - - bindstring = ('$$'.join(cmdBindStrings)) - return bindstring - - def ShowEditDialogFor(self, command): - if not command.UI: return - - self.EditDialog.mainSizer.Show(command.UI) - - self.EditDialog.Layout() - self.EditDialog.Fit() - - self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') - returnval = self.EditDialog.ShowModal() - - self.EditDialog.mainSizer.Hide(command.UI) - - return returnval - - def makeAddStepMenu(self): - - stepMenu = wx.Menu() - - for subname in menuStructure: - submenu = wx.Menu() - stepMenu.AppendSubMenu(submenu, subname) - for classname in menuStructure[subname]: - submenu.Append(wx.ID_ANY, classname) - - stepMenu.Append(wx.ID_ANY, 'Custom Bind') - - return stepMenu - -class PowerBinderButton(wx.BitmapButton): - - def __init__(self, parent, tgtTxtCtrl, init = {}): - wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) - self.Init = init - self.Dialog = None - self.DialogParent = parent - - self.tgtTxtCtrl = tgtTxtCtrl - self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) - self.SetToolTip("Launch PowerBinder") - - def PowerBinderEventHandler(self, _): - self.PowerBinderDialog().Show() - - def LoadFromData(self, data): - self.PowerBinderDialog().LoadFromData(data) - - def SaveToData(self): - return self.PowerBinderDialog().SaveToData() - - def PowerBinderDialog(self): - if not self.Dialog: - self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) - return self.Dialog - - -class PowerBinderEditDialog(wx.Dialog): - def __init__(self, parent): - wx.Dialog.__init__(self, parent, -1, "Edit Step", - style = wx.DEFAULT_DIALOG_STYLE) - - outerSizer = wx.BoxSizer(wx.VERTICAL) - - self.mainSizer = wx.BoxSizer(wx.VERTICAL) - self.mainSizer.SetMinSize([500, 150]) - - self.Page = parent.Page - - self.mainSizer.Add( - self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), - 0, wx.EXPAND|wx.ALL, 10) - - outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) - - self.SetSizerAndFit(outerSizer) - self.Layout() - self.Fit() - -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" - - -####### Away From Keyboard -class AFKCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.Groups = {} - self.AttributeTable = { - 'Base' : { - 'Current Hit Points' : 'NT H', - 'Max Hit Points' : 'X H', - 'Current Endurance' : 'T E', - 'Max Endurance' : 'X EN', - 'Regeneration Rate' : 'N RAT', - 'Recovery Rate' : 'Y RA', - 'Endurance Consumption' : 'SU', - 'ToHit Bonus' : 'T B', - 'Accuracy Bonus' : 'CC', - 'Last Hit Chance' : 'T C', - 'Damage Bonus' : 'DA', - 'Healing Bonus' : 'NG B', - 'Recharge Time Bonus' : 'ME B', - 'Endurance Discount' : 'CE DIS', - 'Stealth Radius (PvP)' : 'PVP', - 'Stealth Radius (PvE)' : 'PVE', - 'Perception Radius' : 'RC', - 'Range Bonus' : 'GE B', - 'Threat Level' : 'AT L', - 'Experience to Next Level' : 'XT', - 'Experience Debt' : 'XP', - 'Influence / Infamy' : 'INF', - 'Inherent' : 'NH', - }, - 'Movement Speed' : { - 'Flying Speed' : 'FL', - 'Jumping Speed' : 'PI', - 'Max Jump Height' : 'X J', - 'Run Speed' : 'RU', - }, - 'Damage Resistance' : { - 'Smashing Resistance' : 'G R', - 'Lethal Resistance' : 'L R', - 'Fire Resistance' : 'RE R', - 'Cold Resistance' : 'COLD R', - 'Energy Resistance' : 'DamageType[4]', - 'Negative Energy Resistance' : 'GY R', - 'Psyonic Resistance' : 'NIC R', - 'Toxic Resistance' : 'XIC R', - }, - 'Defense' : { - 'Base Defense' : 'BAS', - 'Ranged Defense' : 'ED', - 'Melee Defense' : 'MEL', - 'AoE Defense' : '2', - 'Smashing Defense' : '3', - 'Lethal Defense' : '4', - 'Fire Defense' : '5', - 'Cold Defense' : '6', - 'Energy Defense' : '7', - 'Negative Energy Defense' : '8', - 'Psionic Defense' : '9', - 'Toxic Defense' : '1', - }, - 'Debuff Resistance' : { - 'Regeneration Resistance' : 'ON R', - 'Recovery Resistance' : 'RY R', - 'To Hit Resistance' : 'IT R', - 'Defense Resistance' : 'NSE RES', - }, - 'Status Effect Protection' : { - 'Hold Protection' : 'D P', - 'Immobilize Protection' : 'LIZE P', - 'Stun Protection' : 'N P', - 'Sleep Protection' : 'P P', - 'Knockback Protection' : 'K P', - 'Confuse Protection' : 'SE P', - 'Terrorize Protection' : 'ZE P', - 'Repel Protection' : 'EL P', - 'Teleport Protection' : 'T P', - }, - 'Status Effect Resistance' : { - 'Hold Resistance' : 'D R', - 'Immobilize Resistance' : 'LIZE R', - 'Stun Resistance' : 'N R', - 'Sleep Resistance' : 'P R', - 'Knockback Resistance' : 'K R', - 'Confuse Resistance' : 'SE R', - 'Terrorize Resistance' : 'ZE R', - 'Placate Resistance' : 'TE R', - 'Taunt Resistance' : 'NT R', - }, - 'Miscellaneous' : { - 'Level Shift' : 'L S', - }, - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.AttributeMenu = wx.Menu() - for group, controls in self.AttributeTable.items(): - submenu = wx.Menu() - self.AttributeMenu.AppendSubMenu(submenu, group) - for cb in controls: - submenu.Append(wx.ID_ANY, cb) - - self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) - - self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) - groupSizer.Add(self.editbox) - - newButton = self.editbox.GetNewButton() - newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) - - return groupSizer - - def MakeBindString(self): - map = {} - bindstrings = [] - for _, controls in self.AttributeTable.items(): - for cb, data in controls.items(): - map[cb] = data - - for string in self.editbox.GetStrings(): - if string: - bindstrings.append(f'monitorattribute {map[string]}') - - return '$$'.join(bindstrings) - - def Serialize(self): - return { - 'attributes' : self.editbox.GetStrings() - } - - def Deserialize(self, init): - self.editbox.SetStrings(init.get('attributes', [])) - - def OnNewButton(self, evt): - evt.GetEventObject().PopupMenu(self.AttributeMenu) - - def OnMenuItem(self, evt): - menuitem = evt.EventObject.FindItemById(evt.GetId()) - existingstrings = self.editbox.GetStrings() - existingstrings.append(menuitem.GetItemLabel()) - self.editbox.SetStrings(existingstrings) - -####### Auto Power -class AutoPowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) - autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.autoPowerName = PowerPicker(dialog) - autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) - - return autoPowerSizer - - def MakeBindString(self): - return f"powexecauto {self.autoPowerName.GetLabel()}" - - def Serialize(self): - return { - 'pname' : self.autoPowerName.GetLabel(), - 'picon' : self.autoPowerName.IconFilename - } - - def Deserialize(self, init): - if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.buffDisplayMap = { - 'Status Window' : { - 'Hide Auto' : 1, - 'Hide Toggles' : 2, - 'No Blinking' : 4, - 'No Stacking' : 8, - 'Numeric Stacking' : 16, - 'Hide Buff Numbers' : 32, - 'Stop Sending Buffs' : 64, - }, - 'Group Window' : { - 'Hide Auto' : 256, - 'Hide Toggles' : 512, - 'No Blinking' : 1024, - 'No Stacking' : 2048, - 'Numeric Stacking' : 4096, - 'Hide Buff Numbers' : 8192, - 'Stop Sending Buffs' : 16384, - }, - 'Pet Window' : { - 'Hide Auto' : 65536, - 'Hide Toggles' : 131072, - 'No Blinking' : 262144, - 'No Stacking' : 524288, - 'Numeric Stacking' : 1048576, - 'Hide Buff Numbers' : 2097152, - 'Stop Sending Buffs' : 4194304, - }, - } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - for group, controls in self.buffDisplayMap.items(): - self.Groups[group] = ControlGroup(dialog, self.Page, label = group) - groupid = self.Groups[group].GetStaticBox().GetId() - for cb, data in controls.items(): - self.Groups[group].AddControl( - ctlType = 'checkbox', - ctlName = f"{groupid}_{group}_{cb}", - label = cb, - data = data, - ) - - groupSizer.Add(self.Groups[group]) - - return groupSizer - - def CalculateValue(self): - page = wx.App.Get().Main.Profile.CustomBinds - - total = 0 - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] - if checkbox.IsChecked(): - total = total + checkbox.Data - return total - - def MakeBindString(self): - return f"optionset buffsettings {self.CalculateValue()}" - - def Serialize(self): - return { 'value' : self.CalculateValue() } - - def Deserialize(self, init): - value = init.get('value', 0) - - value = value or 0 # in case we had for some reason 'None' stashed in the init values - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] - checkbox.SetValue( checkbox.Data & value ) - -####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - chatCommandSizer = wx.GridBagSizer(5, 5) - self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") - chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) - # row 1 - self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) - self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) - self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) - # row 2 - self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) - self.chatCommandDuration.SetRange(1, 20) - self.chatCommandDuration.SetValue(7) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandDuration, (2,1)) - self.chatCommandChatSize = wx.Choice(dialog, -1, - choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) - self.chatCommandChatSize.SetSelection(5) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) - self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) - self.chatCommandChannel.SetSelection(0) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChannel, (2,5)) - # row 3 - self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") - chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) - self.chatCommandMessage = wx.TextCtrl(dialog, -1) - self.chatCommandMessage.SetHint('Chat Command Text') - chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) - - return chatCommandSizer - - def MakeBindString(self): - duration = self.chatCommandDuration.GetValue() - - choice = self.chatCommandChatSize - index = choice.GetSelection() - size = choice.GetString(index) - - duration = f"" if duration != 7 else "" - size = f"" if size != "1" else "" - - bdcolor = fgcolor = bgcolor = '' - if self.chatCommandUseColorsCB.IsChecked(): - bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - - bdcolor = f"" - fgcolor = f"" - bgcolor = f"" - - beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' - text = self.chatCommandMessage.GetValue() - - choice = self.chatCommandChannel - index = choice.GetSelection() - channel = choice.GetString(index) - - return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" - - def Serialize(self): - return { - 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), - 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), - 'channel' : self.chatCommandChannel .GetSelection(), - 'size' : self.chatCommandChatSize.GetSelection(), - 'duration' : self.chatCommandDuration.GetValue(), - 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'text' : self.chatCommandMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) - if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) - if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) - if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) - if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) - if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) - if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) - if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) - if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - - -####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): - def BuildUI(self, dialog): - chatCommandGlobalSizer = wx.GridBagSizer(5,5) - - self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") - chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) - - self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalChannel.SetHint("Channel") - chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) - - self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') - chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) - - chatCommandGlobalSizer.AddGrowableCol(1) - - return chatCommandGlobalSizer - - def MakeBindString(self): - useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() - channel = self.chatCommandGlobalChannel.GetValue() - message = self.chatCommandGlobalMessage.GetValue() - - preface = "beginchat /" if useBeginchat else "" - - return f'{preface}send "{channel}" {message}' - - def Serialize(self): - return { - 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), - 'channel' : self.chatCommandGlobalChannel.GetValue(), - 'message' : self.chatCommandGlobalMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) - if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) - if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) - -#######Costume Change -class CostumeChangeCmd(PowerBindCmd): - def BuildUI(self, dialog): - costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeCostume = wx.Choice(dialog, -1, - choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) - self.costumeChangeCostume.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeEmote = wx.Choice(dialog, -1, - choices = GameData.Emotes['costumechange']) - self.costumeChangeEmote.Insert("- None -", 0) - self.costumeChangeEmote.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return costumeChangeSizer - - def MakeBindString(self): - costumeNumber = self.costumeChangeCostume.GetSelection() - costumeEmote = self.costumeChangeEmote.GetSelection() - - if costumeEmote: # None, or 0 == "- None -" - ccCmd = 'cce' - emoteName = self.costumeChangeEmote.GetString(costumeEmote) - emoteName = " CC" + emoteName.replace(" ","") - else: - ccCmd = 'cc' - emoteName = '' - - return f"{ccCmd} {costumeNumber}{emoteName}" - - def Serialize(self): - return{ - 'costumeNumber': self.costumeChangeCostume.GetSelection(), - 'costumeEmote' : self.costumeChangeEmote.GetSelection(), - } - - def Deserialize(self, init): - if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) - if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) - -####### Movement Command -class MovementCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - self.plusbutton.SetValue(True) - - self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.commandchoice = wx.Choice(dialog, choices = [ - "forward", "left", "right", "backward", "up", "down", - "turnleft", "turnright", "first", "autorun", "clicktomove", - ],) - sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) - self.commandchoice.SetSelection(0) - - self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - pre = post = '' - if self.plusbutton.GetValue() : pre = "+" - elif self.plusplusbutton.GetValue() : pre = "++" - elif self.minusbutton.GetValue() : pre = "-" - elif self.zerobutton.GetValue() : post = " 0" - elif self.onebutton.GetValue() : post = " 1" - - command = self.commandchoice.GetString(self.commandchoice.GetSelection()) - - return f"{pre}{command}{post}" - - def Serialize(self): - mod = '' - if self.plusbutton.GetValue() : mod = "plus" - elif self.plusplusbutton.GetValue() : mod = "plusplus" - elif self.minusbutton.GetValue() : mod = "minus" - elif self.zerobutton.GetValue() : mod = "zero" - elif self.onebutton.GetValue() : mod = "one" - - return { - 'mod' : mod, - 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), - } - - def Deserialize(self, init): - mod = init.get('mod', 'plus') - - if mod == 'plus' : self.plusbutton.SetValue(True) - elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) - elif mod == 'minus' : self.minusbutton.SetValue(True) - elif mod == 'zero' : self.zerobutton.SetValue(True) - elif mod == 'one' : self.onebutton.SetValue(True) - - self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) - -####### Graphics Command -class GraphicsCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.FlexGridSizer(2) - - self.visscalecb = wx.CheckBox(dialog, label = "visscale") - sizer.Add(self.visscalecb) - self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) - sizer.Add(self.visscalesc) - - self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") - sizer.Add(self.dofweightcb) - self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) - sizer.Add(self.dofweightsc) - - self.fsaacb = wx.CheckBox(dialog, label = "fsaa") - sizer.Add(self.fsaacb) - self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) - self.fsaach.SetSelection(0) - sizer.Add(self.fsaach) - - self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") - sizer.Add(self.bloomscalecb) - self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) - self.bloomscalech.SetSelection(0) - sizer.Add(self.bloomscalech) - - self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") - sizer.Add(self.bloomweightcb) - self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) - sizer.Add(self.bloomweightsc) - - self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") - sizer.Add(self.lodbiascb) - self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) - sizer.Add(self.lodbiassc) - - self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") - sizer.Add(self.renderscalecb) - self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) - sizer.Add(self.renderscalesc) - - return sizer - - def MakeBindString(self): - # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. - bindstrings = [] - if self.visscalecb.IsChecked(): - bindstrings.append("visscale " + str(self.visscalesc.GetValue())) - if self.dofweightcb.IsChecked(): - bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) - if self.fsaacb.IsChecked(): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bindstrings.append("fsaa " + fsaavalue) - if self.bloomscalecb.IsChecked(): - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - bindstrings.append("bloomscale " + bloomscalevalue) - if self.bloomweightcb.IsChecked(): - bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) - if self.lodbiascb.IsChecked(): - bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) - if self.renderscalecb.IsChecked(): - bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) - - return '$$'.join(bindstrings) - - def Serialize(self): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - return { - 'visscalecb' : self.visscalecb.IsChecked(), - 'visscalesc' : self.visscalesc.GetValue(), - 'dofweightcb' : self.dofweightcb.IsChecked(), - 'dofweightsc' : self.dofweightsc.GetValue(), - 'fsaacb' : self.fsaacb.IsChecked(), - 'fsaach' : fsaavalue, - 'bloomscalecb' : self.bloomscalecb.IsChecked(), - 'bloomscalech' : bloomscalevalue, - 'bloomweightcb' : self.bloomweightcb.IsChecked(), - 'bloomweightsc' : self.bloomweightsc.GetValue(), - 'lodbiascb' : self.lodbiascb.IsChecked(), - 'lodbiassc' : self.lodbiassc.GetValue(), - 'renderscalecb' : self.renderscalecb.IsChecked(), - 'renderscalesc' : self.renderscalesc.GetValue(), - } - - def Deserialize(self, init): - self.visscalecb.SetValue(init.get('visscalecb', False)) - self.visscalesc.SetValue(init.get('visscalesc', 1.0)) - self.dofweightcb.SetValue(init.get('dofweightcb', False)) - self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) - self.fsaacb.SetValue(init.get('fsaacb', False)) - self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) - self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) - self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) - self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) - self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) - self.lodbiascb.SetValue(init.get('lodbiascb', False)) - self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) - self.renderscalecb.SetValue(init.get('renderscalecb', False)) - self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) - -####### Custom Bind -class CustomBindCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.customBindName = wx.TextCtrl(dialog, -1) - self.customBindName.SetHint('Custom Bind Text') - sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - return self.customBindName.GetValue() - - def Serialize(self): - return { 'customBindName': self.customBindName.GetValue() } - - def Deserialize(self,init): - if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) - -####### Emote -class EmoteCmd(PowerBindCmd): - def BuildUI(self, dialog): - emoteSizer = wx.BoxSizer(wx.HORIZONTAL) - self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") - emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - self.emoteName = wx.Button(dialog, -1, "...") - self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) - emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) - - return emoteSizer - - def MakeBindString(self): - displayedEmoteName = self.emoteName.GetLabel() - actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] - - return actualEmotePayload - - def Serialize(self): - return {'emoteName': self.emoteName.GetLabel()} - - def Deserialize(self, init): - if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) - -####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): - def BuildUI(self, dialog): - mainSizer = wx.BoxSizer(wx.VERTICAL) - - lbSizer = wx.BoxSizer(wx.HORIZONTAL) - lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") - lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - profiles = Profile.GetAllProfileBindsDirs() - - self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) - lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) - - mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") - self.lbResetCB.SetValue(True) - - mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - return mainSizer - - def MakeBindString(self): - - # If the specified binds directory disappeared between runs, we'd crash, so handle that. - if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' - - config = wx.ConfigBase.Get() - if config.Exists('GameBindPath'): - bindpath = config.Read('GameBindPath') - else: - bindpath = config.Read('BindPath') - - reset = "" - if self.lbResetCB.GetValue(): - reset = "keybind_reset$$" - - resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' - return reset + 'bindloadfile ' + str(resetfilepath) - - def Serialize(self): - return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), - 'ResetKeybinds' : self.lbResetCB.GetValue(), - } - - def Deserialize(self, init): - if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) - self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) - -####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' - -####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' - -####### SG Mode -class SGModeCmd(PowerBindCmd): - def BuildUI(self, dialog): - sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) - sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") - self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") - - sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) - - return sgmodeSizer - - def MakeBindString(self): - if self.sgmodeOnRB.GetValue(): - return 'sgmodeset 1' - elif self.sgmodeOffRB.GetValue(): - return 'sgmodeset 0' - else: - return 'sgmode' - - def Serialize(self): - if self.sgmodeOnRB.GetValue(): - val = "On" - elif self.sgmodeOffRB.GetValue(): - val = "Off" - else: - val = "Toggle" - - return {"value" : val} - - def Deserialize(self, init): - val = init.get('value', '') - if val == "On": - self.sgmodeOnRB.SetValue(True) - elif val == "Off": - self.sgmodeOffRB.SetValue(True) - else: - self.sgmodeToggleRB.SetValue(True) - -####### Target Custom -class TargetCustomCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetCustomSizer = wx.GridBagSizer(5,5) - targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), - flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) - self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetCustomModeChoice.SetSelection(0) - targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) - self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) - self.targetCustomOptionalName.SetHint("Optional name to match") - targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) - self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") - targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) - self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") - targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) - self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") - targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) - self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") - targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) - self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") - targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) - self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") - targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) - self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") - targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) - self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") - targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) - - targetCustomSizer.AddGrowableCol(2) - - return targetCustomSizer - - def MakeBindString(self): - choice = self.targetCustomModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - targetCommand = "targetcustom" + mode.lower() - - enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" - friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" - defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" - alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" - mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" - notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" - base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" - notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" - - name = self.targetCustomOptionalName.GetValue() - - return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" - - def Serialize(self): - return { - 'mode' : self.targetCustomModeChoice.GetSelection(), - 'enemy' : self.targetCustomCBEnemies. IsChecked(), - 'friend' : self.targetCustomCBFriends. IsChecked(), - 'defeated' : self.targetCustomCBDefeated. IsChecked(), - 'alive' : self.targetCustomCBAlive. IsChecked(), - 'mypet' : self.targetCustomCBMyPets. IsChecked(), - 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), - 'base' : self.targetCustomCBBaseItems. IsChecked(), - 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), - 'name' : self.targetCustomOptionalName.GetValue(), - } - - def Deserialize(self, init): - if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) - if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) - if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) - if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) - if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) - if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) - if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) - if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) - if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) - if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - +from UI.PowerBinderCommand import PowerBinderCommand ####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): +class TargetEnemyCmd(PowerBinderCommand): + Name = "Target Enemy" + Menu = "Targeting" + def BuildUI(self, dialog): targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, @@ -1207,594 +27,3 @@ def Serialize(self): def Deserialize(self, init): if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) - -####### Target Friend -class TargetFriendCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) - targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetFriendModeChoice.SetSelection(0) - targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetFriendSizer - - def MakeBindString(self): - choice = self.targetFriendModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetfriend" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetFriendModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) - -####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): - def BuildUI(self, dialog): - teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], - style=wx.ALIGN_CENTER_VERTICAL) - self.teamPetSelectNumber.SetSelection(0) - teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) - - return teamPetSelectSizer - - def MakeBindString(self): - teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' - targetNumber = self.teamPetSelectNumber.GetSelection()+1 - - return f"{teamOrPet}select {targetNumber}" - - def Serialize(self): - return { - 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', - 'targetNum': self.teamPetSelectNumber.GetSelection(), - } - - def Deserialize(self, init): - ToP = init.get('teamOrPet', '') - if ToP == 'pet': - self.teamPetSelectPetRB.SetValue(True) - else: - self.teamPetSelectTeamRB.SetValue(True) - if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) - -####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' - -####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) - for _, types in GameData.Inspirations.items(): - for _, info in types.items(): - for insp in info['tiers']: - name = re.sub(' ', '', str(insp)) - icon = GetIcon(f'Inspirations/{name}') - self.useInspByNameModeChoice.Append(insp, icon) - self.useInspByNameModeChoice.SetSelection(0) - useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) - - return useInspByNameSizer - - def MakeBindString(self): - choice = self.useInspByNameModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "inspexecname " + mode.lower() - - def GetAllInsps(self): - Insplist = [] - for _, info in GameData.Inspirations.items(): - for insp in info['tiers']: - Insplist.append(insp) - Insplist.append("---") - Insplist.pop(-1) # snip the terminal "---" - - return Insplist - - def Serialize(self): - return { 'insp' : self.useInspByNameModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) - -####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnRow.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) - self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnCol.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) - - return useInspRowColumnSizer - - def MakeBindString(self): - row = self.useInspRowColumnRow.GetSelection()+1 - col = self.useInspRowColumnCol.GetSelection()+1 - - return f"inspexectray {col} {row}" - - def Serialize(self): - return { - 'col' : self.useInspRowColumnCol.GetSelection(), - 'row' : self.useInspRowColumnRow.GetSelection(), - } - - def Deserialize(self, init): - if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) - if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) - -####### Use Power -class UsePowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - outerSizer = wx.BoxSizer(wx.HORIZONTAL) - - usePowerSizer = wx.GridBagSizer(5,5) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBToggle, (0,1)) - self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOn, (0,2)) - self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOff, (0,3)) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerName = PowerPicker(dialog) - usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) - usePowerSizer.AddGrowableCol(3) - - outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) - - return outerSizer - - def MakeBindString(self): - if self.usePowerRBToggle.GetValue(): - method = "powexecname" - elif self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') - return '' - - return f"{method} {self.usePowerName.GetLabel()}" - - def Serialize(self): - if self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - method = "powexecname" - return { - 'method': method, - 'pname' : self.usePowerName.GetLabel(), - 'picon' : self.usePowerName.IconFilename - } - - def Deserialize(self, init): - method = init.get('method', '') - if method == 'powexectoggleon': - self.usePowerRBOn.SetValue(True) - elif method == 'powexectoggleoff': - self.usePowerRBOff.SetValue(True) - else: - self.usePowerRBToggle.SetValue(True) - if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) - -####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): - def BuildUI(self, dialog): - usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTrayTray = wx.Choice(dialog, -1, - choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', - 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) - self.usePowerFromTrayTray.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) - self.usePowerFromTraySlot.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return usePowerFromTraySizer - - def MakeBindString(self): - choice = self.usePowerFromTrayTray - tray = choice.GetSelection() - - choice = self.usePowerFromTraySlot - slot = choice.GetSelection()+1 - - mode = "slot" - mode2 = '' - if tray > 3: - mode = "tray" - mode2 = f" {tray - 3}" - elif tray == 3: - mode = "alt2slot" - elif tray == 2: - mode = "altslot" - - return f"powexec{mode} {slot}{mode2}" - - def Serialize(self): - return { - 'tray' : self.usePowerFromTrayTray.GetSelection(), - 'slot' : self.usePowerFromTraySlot.GetSelection(), - } - - def Deserialize(self, init): - if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) - if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) - -####### Window Color -class WindowColorCmd(PowerBindCmd): - def BuildUI(self, dialog): - windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) - borderSizer = wx.BoxSizer(wx.VERTICAL) - self.ColorBorder.SetSizer(borderSizer) - self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) - borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) - - windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) - - RGBASizer = wx.FlexGridSizer(3, 4, 5) - - RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) - self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) - self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - windowColorSizer.Add(RGBASizer) - - self.UpdateFromSlider() - - return windowColorSizer - - def MakeBindString(self): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - return f"windowcolor {Rval} {Gval} {Bval} {Aval}" - - def Serialize(self): - return { - 'Rval' : self.RSlider.GetValue(), - 'Gval' : self.GSlider.GetValue(), - 'Bval' : self.BSlider.GetValue(), - 'Aval' : self.ASlider.GetValue(), - } - - def Deserialize(self, init): - self.RSlider.SetValue(init['Rval']) - self.GSlider.SetValue(init['Gval']) - self.BSlider.SetValue(init['Bval']) - self.ASlider.SetValue(init['Aval']) - self.UpdateFromSlider() - - def UpdateFromSlider(self, _ = None): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RReadout.SetValue(Rval) - self.GReadout.SetValue(Gval) - self.BReadout.SetValue(Bval) - self.AReadout.SetValue(Aval) - self.ColorBorder.Refresh() - - def UpdateFromText(self, _ = None): - Rval = self.RReadout.GetValue() - Gval = self.GReadout.GetValue() - Bval = self.BReadout.GetValue() - Aval = self.AReadout.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RSlider.SetValue(Rval) - self.GSlider.SetValue(Gval) - self.BSlider.SetValue(Bval) - self.ASlider.SetValue(Aval) - self.ColorBorder.Refresh() - -####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) - self.CommandChoice.SetSelection(0) - sizer.Add(self.CommandChoice, 0, wx.ALL, 5) - - self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), - value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) - sizer.Add(self.FilePath, 0, wx.ALL, 5) - - return sizer - - def MakeBindString(self): - command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] - return f'{command} "{self.FilePath.GetValue()}"' - - def Serialize(self): - return { - 'command' : self.CommandChoice.GetSelection(), - 'filename' : self.FilePath.GetValue(), - } - - def Deserialize(self, init): - self.CommandChoice.SetSelection(init.get('command', 0)) - self.FilePath.SetValue(init.get('filename', '')) - -####### Window Toggle -class WindowToggleCmd(PowerBindCmd): - def BuildUI(self, dialog): - self.WindowNames = { - 'Actions' : 'actions', - 'Auction House' : 'ah', - 'Badge' : 'badge', - 'Channel Search' : 'chansearch', - 'Chat' : 'chat', - 'Custom Chat 1' : 'chat1', - 'Custom Chat 2' : 'chat2', - 'Custom Chat 3' : 'chat3', - 'Custom Chat 4' : 'chat4', - 'Clues' : 'clue', - 'Combat Numbers' : 'combatnumbers', - 'Contacts' : 'contact', - 'Contact Finder' : 'contactfinder', - 'Costumes' : 'costume', - 'Email' : 'email', - 'Enhancements' : 'enhancements', - 'Friends' : 'friend', - 'Group' : 'group', - 'Help' : 'helpwindow', - 'Incarnate' : 'incarnate', - 'Inspirations' : 'insp', - 'League' : 'league', - 'LFG' : 'lfg', - 'Map' : 'map', - 'Mission' : 'mission', - 'Nav / Compass' : 'nav', - 'Options' : 'options', - 'Pets' : 'pet', - 'Petition' : 'petition', - 'Power Tray' : 'powers', - 'Power List' : 'powerlist', - 'Quit' : 'quit', - 'Recipes' : 'recipe', - 'Salvage' : 'salvage', - 'Search' : 'search', - 'Supergroup' : 'sg', - 'Target' : 'target', - 'Team' : 'team', - 'Tray' : 'tray', - 'Tray1' : 'tray1', - 'Tray2' : 'tray2', - 'Tray3' : 'tray3', - 'Tray4' : 'tray4', - 'Tray5' : 'tray5', - 'Tray6' : 'tray6', - 'Tray7' : 'tray7', - 'Tray8' : 'tray8', - 'Vault' : 'vault', - } - - self.ShortToggleCommands = { - 'Auction House' : 'ah', - 'Chat' : 'chat', - 'Help' : 'helpwindow', - 'Map' : 'map', - 'Nav / Compass' : 'nav', - 'Power Tray' : 'powers', - 'Target' : 'target', - 'Tray' : 'tray', - } - - windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) - windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) - self.windowToggleTray.SetSelection(0) - windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.windowShowRB = wx.RadioButton(dialog, -1, "Show") - self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") - - windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) - - return windowToggleSizer - - def MakeBindString(self): - choice = self.windowToggleTray - index = choice.GetSelection() - windowdesc = choice.GetString(index) - windowname = self.WindowNames[windowdesc] - - if self.windowShowRB.GetValue(): - return 'show ' + windowname - elif self.windowHideRB.GetValue(): - return 'windowhide ' + windowname - else: - if shortcmd := self.ShortToggleCommands.get(windowdesc, None): - return shortcmd - else: - return 'toggle ' + windowname - - - def Serialize(self): - choice = self.windowToggleTray - if self.windowShowRB.GetValue(): - action = "Show" - elif self.windowHideRB.GetValue(): - action = "Hide" - else: - action = "Toggle" - return { - 'window': choice.GetString(choice.GetSelection()), - 'action': action, - } - - def Deserialize(self, init): - choice = self.windowToggleTray - if window := init.get('window', ''): - if isinstance(window, int): - choice.SetSelection(window) - else: - choice.SetSelection(choice.FindString(window)) - - if choice.GetSelection() == wx.NOT_FOUND: - choice.SetSelection(0) - - action = init.get('action', '') - if action == "Show": - self.windowShowRB.SetValue(True) - elif action == "Hide": - self.windowHideRB.SetValue(True) - else: - self.windowToggleRB.SetValue(True) - - -# Must always add to this list when adding a new command class above -menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], - # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, - # but I'm leaving it here to remind myself that we do that. - } - -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/TargetFriendCmd.py b/UI/PowerBinderCommand/TargetFriendCmd.py index 4c02ab7..f4f1a3c 100644 --- a/UI/PowerBinderCommand/TargetFriendCmd.py +++ b/UI/PowerBinderCommand/TargetFriendCmd.py @@ -1,1215 +1,11 @@ import wx -import re -import UI -import UI.EmotePicker -from UI.ControlGroup import ControlGroup -from UI.PowerPicker import PowerPicker -from Help import HelpButton -import wx.adv -from wx.adv import BitmapComboBox, EditableListBox -from pathlib import PureWindowsPath -import GameData -import Profile -from Icon import GetIcon - -class PowerBinderDialog(wx.Dialog): - def __init__(self, parent, button, init = {}): - wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) - - self.Page = parent.Page - self.EditDialog = PowerBinderEditDialog(self) - self.Button = button - self.AddStepMenu = self.makeAddStepMenu() - - sizer = wx.BoxSizer(wx.VERTICAL); - self.mainSizer = sizer - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) - AddStepButton = wx.Button(self, -1, 'Add Step') - AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) - AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) - choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) - choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) - sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) - - rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) - - self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) - self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) - self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) - rearrangeCtrl.Add(self.RearrangeList, 1) - - rearrangeButtons = wx.BoxSizer(wx.VERTICAL) - self.DelButton = wx.Button(self, -1, "Delete") - self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) - self.EditButton = wx.Button(self, -1, "Edit") - self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) - self.EditButton.Disable() - upButton = wx.Button(self, -1, "\u25B2") - upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) - downButton = wx.Button(self, -1, "\u25BC") - downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) - rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) - rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) - - sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.BindStringDisplay = wx.TextCtrl(self, -1) - self.BindStringDisplay.Disable() - choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, - wx.ALIGN_CENTER_VERTICAL) - choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) - - sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) - - sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) - - # need to dig around and get the OK button since we show this dialog modelessly now. - okButton = self.FindWindow(self.GetAffirmativeId()) - okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) - - # Wrap everything in a vbox to add some padding - vbox = wx.BoxSizer(wx.VERTICAL); - vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); - - self.SetSizerAndFit(vbox); - self.Layout() - self.Fit() - self.SetFocus() - - # if we are loading from profile, ie, have "init", build the list from it - if init: self.LoadFromData(init) - - def LoadFromData(self, init): - for item in init: - for type, data in item.items(): - commandClass = commandClasses.get(type, None) - if not commandClass: - commandClass = deprecatedCommandClasses.get(type, None) - if not commandClass: - wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") - continue - newCommand = commandClass(self.EditDialog, data) - index = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.SetClientData(index, newCommand) - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) - self.EditDialog.mainSizer.Hide(newCommand.UI) - self.UpdateBindStringDisplay() - - def SaveToData(self): - data = [] - index = 0 - for _ in self.RearrangeList.GetItems(): - # check whether we have an object already attached to this choice - cmdObject = self.RearrangeList.GetClientData(index) - commandClassName = commandRevClasses[type(cmdObject)] - data.append({commandClassName: cmdObject.Serialize()}) - index = index + 1 - return data - - def OnAddStepButton(self, evt): - button = evt.EventObject - if not self.AddStepMenu: - self.AddStepMenu = self.makeAddStepMenu() - button.PopupMenu(self.AddStepMenu) - - - def OnOKButton(self, _): - if self.Button.tgtTxtCtrl: - bindString = self.MakeBindString() - if bindString != self.Button.tgtTxtCtrl.GetValue(): - self.Button.tgtTxtCtrl.SetValue(bindString) - wx.App.Get().Main.Profile.SetModified() - self.Close() - - def OnRearrangeDelete(self, _): - current = self.RearrangeList.GetSelection() - if current == wx.NOT_FOUND: return - - self.RearrangeList.Delete(current) - self.UpdateBindStringDisplay() - - def OnRearrangeUp(self, _): - self.RearrangeList.MoveCurrentUp() - self.UpdateBindStringDisplay() - - def OnRearrangeDown(self, _): - self.RearrangeList.MoveCurrentDown() - self.UpdateBindStringDisplay() - - def OnRearrangeEdit(self, _): - index = self.RearrangeList.GetSelection() - - # check whether we have an object already attached to this choice - cmdObject = None - try: - cmdObject = self.RearrangeList.GetClientData(index) - except Exception: - pass - - if cmdObject: - self.ShowEditDialogFor(cmdObject) - self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) - else: - print("cmdObject was None") - self.UpdateBindStringDisplay() - - # OnAddStepMenu creates a new step and adds it to the rearrangelist - def OnAddStepMenu(self, evt): - menuitem = self.AddStepMenu.FindItemById(evt.GetId()) - chosenName = menuitem.GetItemLabel() - - # make a new command object, attached to the parent dialog - newCommandClass = commandClasses[chosenName] - newCommand = newCommandClass(self.EditDialog) - - # show the edit dialog if this command needs it - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) - if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): - self.EditDialog.mainSizer.Remove(newCommand.UI) - return - - newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.Select(newBindIndex) - self.RearrangeList.SetClientData(newBindIndex, newCommand) - - self.OnListSelect() - self.UpdateBindStringDisplay() - - def OnListSelect(self, _ = None): - selected = self.RearrangeList.GetSelection() - - if selected != wx.NOT_FOUND: - selCommand = self.RearrangeList.GetClientData(selected) - if selCommand.UI: - self.EditButton.Enable() - else: - self.EditButton.Disable() - - def UpdateBindStringDisplay(self): - self.BindStringDisplay.SetValue(self.MakeBindString()) - self.BindStringDisplay.SetToolTip(self.MakeBindString()) - - def MakeBindString(self): - cmdBindStrings = [] - for index in range(self.RearrangeList.GetCount()): - c = self.RearrangeList.GetClientData(index) - if c: cmdBindStrings.append(c.MakeBindString()) - - bindstring = ('$$'.join(cmdBindStrings)) - return bindstring - - def ShowEditDialogFor(self, command): - if not command.UI: return - - self.EditDialog.mainSizer.Show(command.UI) - - self.EditDialog.Layout() - self.EditDialog.Fit() - - self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') - returnval = self.EditDialog.ShowModal() - - self.EditDialog.mainSizer.Hide(command.UI) - - return returnval - - def makeAddStepMenu(self): - - stepMenu = wx.Menu() - - for subname in menuStructure: - submenu = wx.Menu() - stepMenu.AppendSubMenu(submenu, subname) - for classname in menuStructure[subname]: - submenu.Append(wx.ID_ANY, classname) - - stepMenu.Append(wx.ID_ANY, 'Custom Bind') - - return stepMenu - -class PowerBinderButton(wx.BitmapButton): - - def __init__(self, parent, tgtTxtCtrl, init = {}): - wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) - self.Init = init - self.Dialog = None - self.DialogParent = parent - - self.tgtTxtCtrl = tgtTxtCtrl - self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) - self.SetToolTip("Launch PowerBinder") - - def PowerBinderEventHandler(self, _): - self.PowerBinderDialog().Show() - - def LoadFromData(self, data): - self.PowerBinderDialog().LoadFromData(data) - - def SaveToData(self): - return self.PowerBinderDialog().SaveToData() - - def PowerBinderDialog(self): - if not self.Dialog: - self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) - return self.Dialog - - -class PowerBinderEditDialog(wx.Dialog): - def __init__(self, parent): - wx.Dialog.__init__(self, parent, -1, "Edit Step", - style = wx.DEFAULT_DIALOG_STYLE) - - outerSizer = wx.BoxSizer(wx.VERTICAL) - - self.mainSizer = wx.BoxSizer(wx.VERTICAL) - self.mainSizer.SetMinSize([500, 150]) - - self.Page = parent.Page - - self.mainSizer.Add( - self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), - 0, wx.EXPAND|wx.ALL, 10) - - outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) - - self.SetSizerAndFit(outerSizer) - self.Layout() - self.Fit() - -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" - - -####### Away From Keyboard -class AFKCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.Groups = {} - self.AttributeTable = { - 'Base' : { - 'Current Hit Points' : 'NT H', - 'Max Hit Points' : 'X H', - 'Current Endurance' : 'T E', - 'Max Endurance' : 'X EN', - 'Regeneration Rate' : 'N RAT', - 'Recovery Rate' : 'Y RA', - 'Endurance Consumption' : 'SU', - 'ToHit Bonus' : 'T B', - 'Accuracy Bonus' : 'CC', - 'Last Hit Chance' : 'T C', - 'Damage Bonus' : 'DA', - 'Healing Bonus' : 'NG B', - 'Recharge Time Bonus' : 'ME B', - 'Endurance Discount' : 'CE DIS', - 'Stealth Radius (PvP)' : 'PVP', - 'Stealth Radius (PvE)' : 'PVE', - 'Perception Radius' : 'RC', - 'Range Bonus' : 'GE B', - 'Threat Level' : 'AT L', - 'Experience to Next Level' : 'XT', - 'Experience Debt' : 'XP', - 'Influence / Infamy' : 'INF', - 'Inherent' : 'NH', - }, - 'Movement Speed' : { - 'Flying Speed' : 'FL', - 'Jumping Speed' : 'PI', - 'Max Jump Height' : 'X J', - 'Run Speed' : 'RU', - }, - 'Damage Resistance' : { - 'Smashing Resistance' : 'G R', - 'Lethal Resistance' : 'L R', - 'Fire Resistance' : 'RE R', - 'Cold Resistance' : 'COLD R', - 'Energy Resistance' : 'DamageType[4]', - 'Negative Energy Resistance' : 'GY R', - 'Psyonic Resistance' : 'NIC R', - 'Toxic Resistance' : 'XIC R', - }, - 'Defense' : { - 'Base Defense' : 'BAS', - 'Ranged Defense' : 'ED', - 'Melee Defense' : 'MEL', - 'AoE Defense' : '2', - 'Smashing Defense' : '3', - 'Lethal Defense' : '4', - 'Fire Defense' : '5', - 'Cold Defense' : '6', - 'Energy Defense' : '7', - 'Negative Energy Defense' : '8', - 'Psionic Defense' : '9', - 'Toxic Defense' : '1', - }, - 'Debuff Resistance' : { - 'Regeneration Resistance' : 'ON R', - 'Recovery Resistance' : 'RY R', - 'To Hit Resistance' : 'IT R', - 'Defense Resistance' : 'NSE RES', - }, - 'Status Effect Protection' : { - 'Hold Protection' : 'D P', - 'Immobilize Protection' : 'LIZE P', - 'Stun Protection' : 'N P', - 'Sleep Protection' : 'P P', - 'Knockback Protection' : 'K P', - 'Confuse Protection' : 'SE P', - 'Terrorize Protection' : 'ZE P', - 'Repel Protection' : 'EL P', - 'Teleport Protection' : 'T P', - }, - 'Status Effect Resistance' : { - 'Hold Resistance' : 'D R', - 'Immobilize Resistance' : 'LIZE R', - 'Stun Resistance' : 'N R', - 'Sleep Resistance' : 'P R', - 'Knockback Resistance' : 'K R', - 'Confuse Resistance' : 'SE R', - 'Terrorize Resistance' : 'ZE R', - 'Placate Resistance' : 'TE R', - 'Taunt Resistance' : 'NT R', - }, - 'Miscellaneous' : { - 'Level Shift' : 'L S', - }, - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.AttributeMenu = wx.Menu() - for group, controls in self.AttributeTable.items(): - submenu = wx.Menu() - self.AttributeMenu.AppendSubMenu(submenu, group) - for cb in controls: - submenu.Append(wx.ID_ANY, cb) - - self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) - - self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) - groupSizer.Add(self.editbox) - - newButton = self.editbox.GetNewButton() - newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) - - return groupSizer - - def MakeBindString(self): - map = {} - bindstrings = [] - for _, controls in self.AttributeTable.items(): - for cb, data in controls.items(): - map[cb] = data - - for string in self.editbox.GetStrings(): - if string: - bindstrings.append(f'monitorattribute {map[string]}') - - return '$$'.join(bindstrings) - - def Serialize(self): - return { - 'attributes' : self.editbox.GetStrings() - } - - def Deserialize(self, init): - self.editbox.SetStrings(init.get('attributes', [])) - - def OnNewButton(self, evt): - evt.GetEventObject().PopupMenu(self.AttributeMenu) - - def OnMenuItem(self, evt): - menuitem = evt.EventObject.FindItemById(evt.GetId()) - existingstrings = self.editbox.GetStrings() - existingstrings.append(menuitem.GetItemLabel()) - self.editbox.SetStrings(existingstrings) - -####### Auto Power -class AutoPowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) - autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.autoPowerName = PowerPicker(dialog) - autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) - - return autoPowerSizer - - def MakeBindString(self): - return f"powexecauto {self.autoPowerName.GetLabel()}" - - def Serialize(self): - return { - 'pname' : self.autoPowerName.GetLabel(), - 'picon' : self.autoPowerName.IconFilename - } - - def Deserialize(self, init): - if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.buffDisplayMap = { - 'Status Window' : { - 'Hide Auto' : 1, - 'Hide Toggles' : 2, - 'No Blinking' : 4, - 'No Stacking' : 8, - 'Numeric Stacking' : 16, - 'Hide Buff Numbers' : 32, - 'Stop Sending Buffs' : 64, - }, - 'Group Window' : { - 'Hide Auto' : 256, - 'Hide Toggles' : 512, - 'No Blinking' : 1024, - 'No Stacking' : 2048, - 'Numeric Stacking' : 4096, - 'Hide Buff Numbers' : 8192, - 'Stop Sending Buffs' : 16384, - }, - 'Pet Window' : { - 'Hide Auto' : 65536, - 'Hide Toggles' : 131072, - 'No Blinking' : 262144, - 'No Stacking' : 524288, - 'Numeric Stacking' : 1048576, - 'Hide Buff Numbers' : 2097152, - 'Stop Sending Buffs' : 4194304, - }, - } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - for group, controls in self.buffDisplayMap.items(): - self.Groups[group] = ControlGroup(dialog, self.Page, label = group) - groupid = self.Groups[group].GetStaticBox().GetId() - for cb, data in controls.items(): - self.Groups[group].AddControl( - ctlType = 'checkbox', - ctlName = f"{groupid}_{group}_{cb}", - label = cb, - data = data, - ) - - groupSizer.Add(self.Groups[group]) - - return groupSizer - - def CalculateValue(self): - page = wx.App.Get().Main.Profile.CustomBinds - - total = 0 - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] - if checkbox.IsChecked(): - total = total + checkbox.Data - return total - - def MakeBindString(self): - return f"optionset buffsettings {self.CalculateValue()}" - - def Serialize(self): - return { 'value' : self.CalculateValue() } - - def Deserialize(self, init): - value = init.get('value', 0) - - value = value or 0 # in case we had for some reason 'None' stashed in the init values - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] - checkbox.SetValue( checkbox.Data & value ) - -####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - chatCommandSizer = wx.GridBagSizer(5, 5) - self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") - chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) - # row 1 - self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) - self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) - self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) - # row 2 - self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) - self.chatCommandDuration.SetRange(1, 20) - self.chatCommandDuration.SetValue(7) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandDuration, (2,1)) - self.chatCommandChatSize = wx.Choice(dialog, -1, - choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) - self.chatCommandChatSize.SetSelection(5) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) - self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) - self.chatCommandChannel.SetSelection(0) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChannel, (2,5)) - # row 3 - self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") - chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) - self.chatCommandMessage = wx.TextCtrl(dialog, -1) - self.chatCommandMessage.SetHint('Chat Command Text') - chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) - - return chatCommandSizer - - def MakeBindString(self): - duration = self.chatCommandDuration.GetValue() - - choice = self.chatCommandChatSize - index = choice.GetSelection() - size = choice.GetString(index) - - duration = f"" if duration != 7 else "" - size = f"" if size != "1" else "" - - bdcolor = fgcolor = bgcolor = '' - if self.chatCommandUseColorsCB.IsChecked(): - bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - - bdcolor = f"" - fgcolor = f"" - bgcolor = f"" - - beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' - text = self.chatCommandMessage.GetValue() - - choice = self.chatCommandChannel - index = choice.GetSelection() - channel = choice.GetString(index) - - return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" - - def Serialize(self): - return { - 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), - 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), - 'channel' : self.chatCommandChannel .GetSelection(), - 'size' : self.chatCommandChatSize.GetSelection(), - 'duration' : self.chatCommandDuration.GetValue(), - 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'text' : self.chatCommandMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) - if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) - if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) - if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) - if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) - if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) - if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) - if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) - if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - - -####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): - def BuildUI(self, dialog): - chatCommandGlobalSizer = wx.GridBagSizer(5,5) - - self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") - chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) - - self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalChannel.SetHint("Channel") - chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) - - self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') - chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) - - chatCommandGlobalSizer.AddGrowableCol(1) - - return chatCommandGlobalSizer - - def MakeBindString(self): - useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() - channel = self.chatCommandGlobalChannel.GetValue() - message = self.chatCommandGlobalMessage.GetValue() - - preface = "beginchat /" if useBeginchat else "" - - return f'{preface}send "{channel}" {message}' - - def Serialize(self): - return { - 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), - 'channel' : self.chatCommandGlobalChannel.GetValue(), - 'message' : self.chatCommandGlobalMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) - if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) - if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) - -#######Costume Change -class CostumeChangeCmd(PowerBindCmd): - def BuildUI(self, dialog): - costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeCostume = wx.Choice(dialog, -1, - choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) - self.costumeChangeCostume.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeEmote = wx.Choice(dialog, -1, - choices = GameData.Emotes['costumechange']) - self.costumeChangeEmote.Insert("- None -", 0) - self.costumeChangeEmote.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return costumeChangeSizer - - def MakeBindString(self): - costumeNumber = self.costumeChangeCostume.GetSelection() - costumeEmote = self.costumeChangeEmote.GetSelection() - - if costumeEmote: # None, or 0 == "- None -" - ccCmd = 'cce' - emoteName = self.costumeChangeEmote.GetString(costumeEmote) - emoteName = " CC" + emoteName.replace(" ","") - else: - ccCmd = 'cc' - emoteName = '' - - return f"{ccCmd} {costumeNumber}{emoteName}" - - def Serialize(self): - return{ - 'costumeNumber': self.costumeChangeCostume.GetSelection(), - 'costumeEmote' : self.costumeChangeEmote.GetSelection(), - } - - def Deserialize(self, init): - if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) - if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) - -####### Movement Command -class MovementCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - self.plusbutton.SetValue(True) - - self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.commandchoice = wx.Choice(dialog, choices = [ - "forward", "left", "right", "backward", "up", "down", - "turnleft", "turnright", "first", "autorun", "clicktomove", - ],) - sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) - self.commandchoice.SetSelection(0) - - self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - pre = post = '' - if self.plusbutton.GetValue() : pre = "+" - elif self.plusplusbutton.GetValue() : pre = "++" - elif self.minusbutton.GetValue() : pre = "-" - elif self.zerobutton.GetValue() : post = " 0" - elif self.onebutton.GetValue() : post = " 1" - - command = self.commandchoice.GetString(self.commandchoice.GetSelection()) - - return f"{pre}{command}{post}" - - def Serialize(self): - mod = '' - if self.plusbutton.GetValue() : mod = "plus" - elif self.plusplusbutton.GetValue() : mod = "plusplus" - elif self.minusbutton.GetValue() : mod = "minus" - elif self.zerobutton.GetValue() : mod = "zero" - elif self.onebutton.GetValue() : mod = "one" - - return { - 'mod' : mod, - 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), - } - - def Deserialize(self, init): - mod = init.get('mod', 'plus') - - if mod == 'plus' : self.plusbutton.SetValue(True) - elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) - elif mod == 'minus' : self.minusbutton.SetValue(True) - elif mod == 'zero' : self.zerobutton.SetValue(True) - elif mod == 'one' : self.onebutton.SetValue(True) - - self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) - -####### Graphics Command -class GraphicsCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.FlexGridSizer(2) - - self.visscalecb = wx.CheckBox(dialog, label = "visscale") - sizer.Add(self.visscalecb) - self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) - sizer.Add(self.visscalesc) - - self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") - sizer.Add(self.dofweightcb) - self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) - sizer.Add(self.dofweightsc) - - self.fsaacb = wx.CheckBox(dialog, label = "fsaa") - sizer.Add(self.fsaacb) - self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) - self.fsaach.SetSelection(0) - sizer.Add(self.fsaach) - - self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") - sizer.Add(self.bloomscalecb) - self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) - self.bloomscalech.SetSelection(0) - sizer.Add(self.bloomscalech) - - self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") - sizer.Add(self.bloomweightcb) - self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) - sizer.Add(self.bloomweightsc) - - self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") - sizer.Add(self.lodbiascb) - self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) - sizer.Add(self.lodbiassc) - - self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") - sizer.Add(self.renderscalecb) - self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) - sizer.Add(self.renderscalesc) - - return sizer - - def MakeBindString(self): - # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. - bindstrings = [] - if self.visscalecb.IsChecked(): - bindstrings.append("visscale " + str(self.visscalesc.GetValue())) - if self.dofweightcb.IsChecked(): - bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) - if self.fsaacb.IsChecked(): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bindstrings.append("fsaa " + fsaavalue) - if self.bloomscalecb.IsChecked(): - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - bindstrings.append("bloomscale " + bloomscalevalue) - if self.bloomweightcb.IsChecked(): - bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) - if self.lodbiascb.IsChecked(): - bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) - if self.renderscalecb.IsChecked(): - bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) - - return '$$'.join(bindstrings) - - def Serialize(self): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - return { - 'visscalecb' : self.visscalecb.IsChecked(), - 'visscalesc' : self.visscalesc.GetValue(), - 'dofweightcb' : self.dofweightcb.IsChecked(), - 'dofweightsc' : self.dofweightsc.GetValue(), - 'fsaacb' : self.fsaacb.IsChecked(), - 'fsaach' : fsaavalue, - 'bloomscalecb' : self.bloomscalecb.IsChecked(), - 'bloomscalech' : bloomscalevalue, - 'bloomweightcb' : self.bloomweightcb.IsChecked(), - 'bloomweightsc' : self.bloomweightsc.GetValue(), - 'lodbiascb' : self.lodbiascb.IsChecked(), - 'lodbiassc' : self.lodbiassc.GetValue(), - 'renderscalecb' : self.renderscalecb.IsChecked(), - 'renderscalesc' : self.renderscalesc.GetValue(), - } - - def Deserialize(self, init): - self.visscalecb.SetValue(init.get('visscalecb', False)) - self.visscalesc.SetValue(init.get('visscalesc', 1.0)) - self.dofweightcb.SetValue(init.get('dofweightcb', False)) - self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) - self.fsaacb.SetValue(init.get('fsaacb', False)) - self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) - self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) - self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) - self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) - self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) - self.lodbiascb.SetValue(init.get('lodbiascb', False)) - self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) - self.renderscalecb.SetValue(init.get('renderscalecb', False)) - self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) - -####### Custom Bind -class CustomBindCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.customBindName = wx.TextCtrl(dialog, -1) - self.customBindName.SetHint('Custom Bind Text') - sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - return self.customBindName.GetValue() - - def Serialize(self): - return { 'customBindName': self.customBindName.GetValue() } - - def Deserialize(self,init): - if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) - -####### Emote -class EmoteCmd(PowerBindCmd): - def BuildUI(self, dialog): - emoteSizer = wx.BoxSizer(wx.HORIZONTAL) - self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") - emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - self.emoteName = wx.Button(dialog, -1, "...") - self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) - emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) - - return emoteSizer - - def MakeBindString(self): - displayedEmoteName = self.emoteName.GetLabel() - actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] - - return actualEmotePayload - - def Serialize(self): - return {'emoteName': self.emoteName.GetLabel()} - - def Deserialize(self, init): - if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) - -####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): - def BuildUI(self, dialog): - mainSizer = wx.BoxSizer(wx.VERTICAL) - - lbSizer = wx.BoxSizer(wx.HORIZONTAL) - lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") - lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - profiles = Profile.GetAllProfileBindsDirs() - - self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) - lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) - - mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") - self.lbResetCB.SetValue(True) - - mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - return mainSizer - - def MakeBindString(self): - - # If the specified binds directory disappeared between runs, we'd crash, so handle that. - if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' - - config = wx.ConfigBase.Get() - if config.Exists('GameBindPath'): - bindpath = config.Read('GameBindPath') - else: - bindpath = config.Read('BindPath') - - reset = "" - if self.lbResetCB.GetValue(): - reset = "keybind_reset$$" - - resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' - return reset + 'bindloadfile ' + str(resetfilepath) - - def Serialize(self): - return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), - 'ResetKeybinds' : self.lbResetCB.GetValue(), - } - - def Deserialize(self, init): - if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) - self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) - -####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' - -####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' - -####### SG Mode -class SGModeCmd(PowerBindCmd): - def BuildUI(self, dialog): - sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) - sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") - self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") - - sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) - - return sgmodeSizer - - def MakeBindString(self): - if self.sgmodeOnRB.GetValue(): - return 'sgmodeset 1' - elif self.sgmodeOffRB.GetValue(): - return 'sgmodeset 0' - else: - return 'sgmode' - - def Serialize(self): - if self.sgmodeOnRB.GetValue(): - val = "On" - elif self.sgmodeOffRB.GetValue(): - val = "Off" - else: - val = "Toggle" - - return {"value" : val} - - def Deserialize(self, init): - val = init.get('value', '') - if val == "On": - self.sgmodeOnRB.SetValue(True) - elif val == "Off": - self.sgmodeOffRB.SetValue(True) - else: - self.sgmodeToggleRB.SetValue(True) - -####### Target Custom -class TargetCustomCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetCustomSizer = wx.GridBagSizer(5,5) - targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), - flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) - self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetCustomModeChoice.SetSelection(0) - targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) - self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) - self.targetCustomOptionalName.SetHint("Optional name to match") - targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) - self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") - targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) - self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") - targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) - self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") - targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) - self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") - targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) - self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") - targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) - self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") - targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) - self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") - targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) - self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") - targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) - - targetCustomSizer.AddGrowableCol(2) - - return targetCustomSizer - - def MakeBindString(self): - choice = self.targetCustomModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - targetCommand = "targetcustom" + mode.lower() - - enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" - friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" - defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" - alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" - mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" - notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" - base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" - notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" - - name = self.targetCustomOptionalName.GetValue() - - return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" - - def Serialize(self): - return { - 'mode' : self.targetCustomModeChoice.GetSelection(), - 'enemy' : self.targetCustomCBEnemies. IsChecked(), - 'friend' : self.targetCustomCBFriends. IsChecked(), - 'defeated' : self.targetCustomCBDefeated. IsChecked(), - 'alive' : self.targetCustomCBAlive. IsChecked(), - 'mypet' : self.targetCustomCBMyPets. IsChecked(), - 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), - 'base' : self.targetCustomCBBaseItems. IsChecked(), - 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), - 'name' : self.targetCustomOptionalName.GetValue(), - } - - def Deserialize(self, init): - if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) - if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) - if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) - if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) - if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) - if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) - if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) - if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) - if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) - if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - - -####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) - targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetEnemyModeChoice.SetSelection(0) - targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetEnemySizer - - def MakeBindString(self): - choice = self.targetEnemyModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetenemy" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetEnemyModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) +from UI.PowerBinderCommand import PowerBinderCommand ####### Target Friend -class TargetFriendCmd(PowerBindCmd): +class TargetFriendCmd(PowerBinderCommand): + Name = "Target Friend" + Menu = "Targeting" + def BuildUI(self, dialog): targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, @@ -1231,570 +27,3 @@ def Serialize(self): def Deserialize(self, init): if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) - -####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): - def BuildUI(self, dialog): - teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], - style=wx.ALIGN_CENTER_VERTICAL) - self.teamPetSelectNumber.SetSelection(0) - teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) - - return teamPetSelectSizer - - def MakeBindString(self): - teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' - targetNumber = self.teamPetSelectNumber.GetSelection()+1 - - return f"{teamOrPet}select {targetNumber}" - - def Serialize(self): - return { - 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', - 'targetNum': self.teamPetSelectNumber.GetSelection(), - } - - def Deserialize(self, init): - ToP = init.get('teamOrPet', '') - if ToP == 'pet': - self.teamPetSelectPetRB.SetValue(True) - else: - self.teamPetSelectTeamRB.SetValue(True) - if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) - -####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' - -####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) - for _, types in GameData.Inspirations.items(): - for _, info in types.items(): - for insp in info['tiers']: - name = re.sub(' ', '', str(insp)) - icon = GetIcon(f'Inspirations/{name}') - self.useInspByNameModeChoice.Append(insp, icon) - self.useInspByNameModeChoice.SetSelection(0) - useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) - - return useInspByNameSizer - - def MakeBindString(self): - choice = self.useInspByNameModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "inspexecname " + mode.lower() - - def GetAllInsps(self): - Insplist = [] - for _, info in GameData.Inspirations.items(): - for insp in info['tiers']: - Insplist.append(insp) - Insplist.append("---") - Insplist.pop(-1) # snip the terminal "---" - - return Insplist - - def Serialize(self): - return { 'insp' : self.useInspByNameModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) - -####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnRow.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) - self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnCol.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) - - return useInspRowColumnSizer - - def MakeBindString(self): - row = self.useInspRowColumnRow.GetSelection()+1 - col = self.useInspRowColumnCol.GetSelection()+1 - - return f"inspexectray {col} {row}" - - def Serialize(self): - return { - 'col' : self.useInspRowColumnCol.GetSelection(), - 'row' : self.useInspRowColumnRow.GetSelection(), - } - - def Deserialize(self, init): - if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) - if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) - -####### Use Power -class UsePowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - outerSizer = wx.BoxSizer(wx.HORIZONTAL) - - usePowerSizer = wx.GridBagSizer(5,5) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBToggle, (0,1)) - self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOn, (0,2)) - self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOff, (0,3)) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerName = PowerPicker(dialog) - usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) - usePowerSizer.AddGrowableCol(3) - - outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) - - return outerSizer - - def MakeBindString(self): - if self.usePowerRBToggle.GetValue(): - method = "powexecname" - elif self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') - return '' - - return f"{method} {self.usePowerName.GetLabel()}" - - def Serialize(self): - if self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - method = "powexecname" - return { - 'method': method, - 'pname' : self.usePowerName.GetLabel(), - 'picon' : self.usePowerName.IconFilename - } - - def Deserialize(self, init): - method = init.get('method', '') - if method == 'powexectoggleon': - self.usePowerRBOn.SetValue(True) - elif method == 'powexectoggleoff': - self.usePowerRBOff.SetValue(True) - else: - self.usePowerRBToggle.SetValue(True) - if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) - -####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): - def BuildUI(self, dialog): - usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTrayTray = wx.Choice(dialog, -1, - choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', - 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) - self.usePowerFromTrayTray.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) - self.usePowerFromTraySlot.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return usePowerFromTraySizer - - def MakeBindString(self): - choice = self.usePowerFromTrayTray - tray = choice.GetSelection() - - choice = self.usePowerFromTraySlot - slot = choice.GetSelection()+1 - - mode = "slot" - mode2 = '' - if tray > 3: - mode = "tray" - mode2 = f" {tray - 3}" - elif tray == 3: - mode = "alt2slot" - elif tray == 2: - mode = "altslot" - - return f"powexec{mode} {slot}{mode2}" - - def Serialize(self): - return { - 'tray' : self.usePowerFromTrayTray.GetSelection(), - 'slot' : self.usePowerFromTraySlot.GetSelection(), - } - - def Deserialize(self, init): - if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) - if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) - -####### Window Color -class WindowColorCmd(PowerBindCmd): - def BuildUI(self, dialog): - windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) - borderSizer = wx.BoxSizer(wx.VERTICAL) - self.ColorBorder.SetSizer(borderSizer) - self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) - borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) - - windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) - - RGBASizer = wx.FlexGridSizer(3, 4, 5) - - RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) - self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) - self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - windowColorSizer.Add(RGBASizer) - - self.UpdateFromSlider() - - return windowColorSizer - - def MakeBindString(self): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - return f"windowcolor {Rval} {Gval} {Bval} {Aval}" - - def Serialize(self): - return { - 'Rval' : self.RSlider.GetValue(), - 'Gval' : self.GSlider.GetValue(), - 'Bval' : self.BSlider.GetValue(), - 'Aval' : self.ASlider.GetValue(), - } - - def Deserialize(self, init): - self.RSlider.SetValue(init['Rval']) - self.GSlider.SetValue(init['Gval']) - self.BSlider.SetValue(init['Bval']) - self.ASlider.SetValue(init['Aval']) - self.UpdateFromSlider() - - def UpdateFromSlider(self, _ = None): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RReadout.SetValue(Rval) - self.GReadout.SetValue(Gval) - self.BReadout.SetValue(Bval) - self.AReadout.SetValue(Aval) - self.ColorBorder.Refresh() - - def UpdateFromText(self, _ = None): - Rval = self.RReadout.GetValue() - Gval = self.GReadout.GetValue() - Bval = self.BReadout.GetValue() - Aval = self.AReadout.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RSlider.SetValue(Rval) - self.GSlider.SetValue(Gval) - self.BSlider.SetValue(Bval) - self.ASlider.SetValue(Aval) - self.ColorBorder.Refresh() - -####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) - self.CommandChoice.SetSelection(0) - sizer.Add(self.CommandChoice, 0, wx.ALL, 5) - - self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), - value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) - sizer.Add(self.FilePath, 0, wx.ALL, 5) - - return sizer - - def MakeBindString(self): - command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] - return f'{command} "{self.FilePath.GetValue()}"' - - def Serialize(self): - return { - 'command' : self.CommandChoice.GetSelection(), - 'filename' : self.FilePath.GetValue(), - } - - def Deserialize(self, init): - self.CommandChoice.SetSelection(init.get('command', 0)) - self.FilePath.SetValue(init.get('filename', '')) - -####### Window Toggle -class WindowToggleCmd(PowerBindCmd): - def BuildUI(self, dialog): - self.WindowNames = { - 'Actions' : 'actions', - 'Auction House' : 'ah', - 'Badge' : 'badge', - 'Channel Search' : 'chansearch', - 'Chat' : 'chat', - 'Custom Chat 1' : 'chat1', - 'Custom Chat 2' : 'chat2', - 'Custom Chat 3' : 'chat3', - 'Custom Chat 4' : 'chat4', - 'Clues' : 'clue', - 'Combat Numbers' : 'combatnumbers', - 'Contacts' : 'contact', - 'Contact Finder' : 'contactfinder', - 'Costumes' : 'costume', - 'Email' : 'email', - 'Enhancements' : 'enhancements', - 'Friends' : 'friend', - 'Group' : 'group', - 'Help' : 'helpwindow', - 'Incarnate' : 'incarnate', - 'Inspirations' : 'insp', - 'League' : 'league', - 'LFG' : 'lfg', - 'Map' : 'map', - 'Mission' : 'mission', - 'Nav / Compass' : 'nav', - 'Options' : 'options', - 'Pets' : 'pet', - 'Petition' : 'petition', - 'Power Tray' : 'powers', - 'Power List' : 'powerlist', - 'Quit' : 'quit', - 'Recipes' : 'recipe', - 'Salvage' : 'salvage', - 'Search' : 'search', - 'Supergroup' : 'sg', - 'Target' : 'target', - 'Team' : 'team', - 'Tray' : 'tray', - 'Tray1' : 'tray1', - 'Tray2' : 'tray2', - 'Tray3' : 'tray3', - 'Tray4' : 'tray4', - 'Tray5' : 'tray5', - 'Tray6' : 'tray6', - 'Tray7' : 'tray7', - 'Tray8' : 'tray8', - 'Vault' : 'vault', - } - - self.ShortToggleCommands = { - 'Auction House' : 'ah', - 'Chat' : 'chat', - 'Help' : 'helpwindow', - 'Map' : 'map', - 'Nav / Compass' : 'nav', - 'Power Tray' : 'powers', - 'Target' : 'target', - 'Tray' : 'tray', - } - - windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) - windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) - self.windowToggleTray.SetSelection(0) - windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.windowShowRB = wx.RadioButton(dialog, -1, "Show") - self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") - - windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) - - return windowToggleSizer - - def MakeBindString(self): - choice = self.windowToggleTray - index = choice.GetSelection() - windowdesc = choice.GetString(index) - windowname = self.WindowNames[windowdesc] - - if self.windowShowRB.GetValue(): - return 'show ' + windowname - elif self.windowHideRB.GetValue(): - return 'windowhide ' + windowname - else: - if shortcmd := self.ShortToggleCommands.get(windowdesc, None): - return shortcmd - else: - return 'toggle ' + windowname - - - def Serialize(self): - choice = self.windowToggleTray - if self.windowShowRB.GetValue(): - action = "Show" - elif self.windowHideRB.GetValue(): - action = "Hide" - else: - action = "Toggle" - return { - 'window': choice.GetString(choice.GetSelection()), - 'action': action, - } - - def Deserialize(self, init): - choice = self.windowToggleTray - if window := init.get('window', ''): - if isinstance(window, int): - choice.SetSelection(window) - else: - choice.SetSelection(choice.FindString(window)) - - if choice.GetSelection() == wx.NOT_FOUND: - choice.SetSelection(0) - - action = init.get('action', '') - if action == "Show": - self.windowShowRB.SetValue(True) - elif action == "Hide": - self.windowHideRB.SetValue(True) - else: - self.windowToggleRB.SetValue(True) - - -# Must always add to this list when adding a new command class above -menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], - # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, - # but I'm leaving it here to remind myself that we do that. - } - -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/TeamPetSelectCmd.py b/UI/PowerBinderCommand/TeamPetSelectCmd.py index 4c02ab7..b402b69 100644 --- a/UI/PowerBinderCommand/TeamPetSelectCmd.py +++ b/UI/PowerBinderCommand/TeamPetSelectCmd.py @@ -1,1239 +1,11 @@ import wx -import re -import UI -import UI.EmotePicker -from UI.ControlGroup import ControlGroup -from UI.PowerPicker import PowerPicker -from Help import HelpButton -import wx.adv -from wx.adv import BitmapComboBox, EditableListBox -from pathlib import PureWindowsPath -import GameData -import Profile -from Icon import GetIcon - -class PowerBinderDialog(wx.Dialog): - def __init__(self, parent, button, init = {}): - wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) - - self.Page = parent.Page - self.EditDialog = PowerBinderEditDialog(self) - self.Button = button - self.AddStepMenu = self.makeAddStepMenu() - - sizer = wx.BoxSizer(wx.VERTICAL); - self.mainSizer = sizer - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) - AddStepButton = wx.Button(self, -1, 'Add Step') - AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) - AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) - choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) - choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) - sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) - - rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) - - self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) - self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) - self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) - rearrangeCtrl.Add(self.RearrangeList, 1) - - rearrangeButtons = wx.BoxSizer(wx.VERTICAL) - self.DelButton = wx.Button(self, -1, "Delete") - self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) - self.EditButton = wx.Button(self, -1, "Edit") - self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) - self.EditButton.Disable() - upButton = wx.Button(self, -1, "\u25B2") - upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) - downButton = wx.Button(self, -1, "\u25BC") - downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) - rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) - rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) - - sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.BindStringDisplay = wx.TextCtrl(self, -1) - self.BindStringDisplay.Disable() - choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, - wx.ALIGN_CENTER_VERTICAL) - choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) - - sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) - - sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) - - # need to dig around and get the OK button since we show this dialog modelessly now. - okButton = self.FindWindow(self.GetAffirmativeId()) - okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) - - # Wrap everything in a vbox to add some padding - vbox = wx.BoxSizer(wx.VERTICAL); - vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); - - self.SetSizerAndFit(vbox); - self.Layout() - self.Fit() - self.SetFocus() - - # if we are loading from profile, ie, have "init", build the list from it - if init: self.LoadFromData(init) - - def LoadFromData(self, init): - for item in init: - for type, data in item.items(): - commandClass = commandClasses.get(type, None) - if not commandClass: - commandClass = deprecatedCommandClasses.get(type, None) - if not commandClass: - wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") - continue - newCommand = commandClass(self.EditDialog, data) - index = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.SetClientData(index, newCommand) - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) - self.EditDialog.mainSizer.Hide(newCommand.UI) - self.UpdateBindStringDisplay() - - def SaveToData(self): - data = [] - index = 0 - for _ in self.RearrangeList.GetItems(): - # check whether we have an object already attached to this choice - cmdObject = self.RearrangeList.GetClientData(index) - commandClassName = commandRevClasses[type(cmdObject)] - data.append({commandClassName: cmdObject.Serialize()}) - index = index + 1 - return data - - def OnAddStepButton(self, evt): - button = evt.EventObject - if not self.AddStepMenu: - self.AddStepMenu = self.makeAddStepMenu() - button.PopupMenu(self.AddStepMenu) - - - def OnOKButton(self, _): - if self.Button.tgtTxtCtrl: - bindString = self.MakeBindString() - if bindString != self.Button.tgtTxtCtrl.GetValue(): - self.Button.tgtTxtCtrl.SetValue(bindString) - wx.App.Get().Main.Profile.SetModified() - self.Close() - - def OnRearrangeDelete(self, _): - current = self.RearrangeList.GetSelection() - if current == wx.NOT_FOUND: return - - self.RearrangeList.Delete(current) - self.UpdateBindStringDisplay() - - def OnRearrangeUp(self, _): - self.RearrangeList.MoveCurrentUp() - self.UpdateBindStringDisplay() - - def OnRearrangeDown(self, _): - self.RearrangeList.MoveCurrentDown() - self.UpdateBindStringDisplay() - - def OnRearrangeEdit(self, _): - index = self.RearrangeList.GetSelection() - - # check whether we have an object already attached to this choice - cmdObject = None - try: - cmdObject = self.RearrangeList.GetClientData(index) - except Exception: - pass - - if cmdObject: - self.ShowEditDialogFor(cmdObject) - self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) - else: - print("cmdObject was None") - self.UpdateBindStringDisplay() - - # OnAddStepMenu creates a new step and adds it to the rearrangelist - def OnAddStepMenu(self, evt): - menuitem = self.AddStepMenu.FindItemById(evt.GetId()) - chosenName = menuitem.GetItemLabel() - - # make a new command object, attached to the parent dialog - newCommandClass = commandClasses[chosenName] - newCommand = newCommandClass(self.EditDialog) - - # show the edit dialog if this command needs it - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) - if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): - self.EditDialog.mainSizer.Remove(newCommand.UI) - return - - newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.Select(newBindIndex) - self.RearrangeList.SetClientData(newBindIndex, newCommand) - - self.OnListSelect() - self.UpdateBindStringDisplay() - - def OnListSelect(self, _ = None): - selected = self.RearrangeList.GetSelection() - - if selected != wx.NOT_FOUND: - selCommand = self.RearrangeList.GetClientData(selected) - if selCommand.UI: - self.EditButton.Enable() - else: - self.EditButton.Disable() - - def UpdateBindStringDisplay(self): - self.BindStringDisplay.SetValue(self.MakeBindString()) - self.BindStringDisplay.SetToolTip(self.MakeBindString()) - - def MakeBindString(self): - cmdBindStrings = [] - for index in range(self.RearrangeList.GetCount()): - c = self.RearrangeList.GetClientData(index) - if c: cmdBindStrings.append(c.MakeBindString()) - - bindstring = ('$$'.join(cmdBindStrings)) - return bindstring - - def ShowEditDialogFor(self, command): - if not command.UI: return - - self.EditDialog.mainSizer.Show(command.UI) - - self.EditDialog.Layout() - self.EditDialog.Fit() - - self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') - returnval = self.EditDialog.ShowModal() - - self.EditDialog.mainSizer.Hide(command.UI) - - return returnval - - def makeAddStepMenu(self): - - stepMenu = wx.Menu() - - for subname in menuStructure: - submenu = wx.Menu() - stepMenu.AppendSubMenu(submenu, subname) - for classname in menuStructure[subname]: - submenu.Append(wx.ID_ANY, classname) - - stepMenu.Append(wx.ID_ANY, 'Custom Bind') - - return stepMenu - -class PowerBinderButton(wx.BitmapButton): - - def __init__(self, parent, tgtTxtCtrl, init = {}): - wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) - self.Init = init - self.Dialog = None - self.DialogParent = parent - - self.tgtTxtCtrl = tgtTxtCtrl - self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) - self.SetToolTip("Launch PowerBinder") - - def PowerBinderEventHandler(self, _): - self.PowerBinderDialog().Show() - - def LoadFromData(self, data): - self.PowerBinderDialog().LoadFromData(data) - - def SaveToData(self): - return self.PowerBinderDialog().SaveToData() - - def PowerBinderDialog(self): - if not self.Dialog: - self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) - return self.Dialog - - -class PowerBinderEditDialog(wx.Dialog): - def __init__(self, parent): - wx.Dialog.__init__(self, parent, -1, "Edit Step", - style = wx.DEFAULT_DIALOG_STYLE) - - outerSizer = wx.BoxSizer(wx.VERTICAL) - - self.mainSizer = wx.BoxSizer(wx.VERTICAL) - self.mainSizer.SetMinSize([500, 150]) - - self.Page = parent.Page - - self.mainSizer.Add( - self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), - 0, wx.EXPAND|wx.ALL, 10) - - outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) - - self.SetSizerAndFit(outerSizer) - self.Layout() - self.Fit() - -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" - - -####### Away From Keyboard -class AFKCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.Groups = {} - self.AttributeTable = { - 'Base' : { - 'Current Hit Points' : 'NT H', - 'Max Hit Points' : 'X H', - 'Current Endurance' : 'T E', - 'Max Endurance' : 'X EN', - 'Regeneration Rate' : 'N RAT', - 'Recovery Rate' : 'Y RA', - 'Endurance Consumption' : 'SU', - 'ToHit Bonus' : 'T B', - 'Accuracy Bonus' : 'CC', - 'Last Hit Chance' : 'T C', - 'Damage Bonus' : 'DA', - 'Healing Bonus' : 'NG B', - 'Recharge Time Bonus' : 'ME B', - 'Endurance Discount' : 'CE DIS', - 'Stealth Radius (PvP)' : 'PVP', - 'Stealth Radius (PvE)' : 'PVE', - 'Perception Radius' : 'RC', - 'Range Bonus' : 'GE B', - 'Threat Level' : 'AT L', - 'Experience to Next Level' : 'XT', - 'Experience Debt' : 'XP', - 'Influence / Infamy' : 'INF', - 'Inherent' : 'NH', - }, - 'Movement Speed' : { - 'Flying Speed' : 'FL', - 'Jumping Speed' : 'PI', - 'Max Jump Height' : 'X J', - 'Run Speed' : 'RU', - }, - 'Damage Resistance' : { - 'Smashing Resistance' : 'G R', - 'Lethal Resistance' : 'L R', - 'Fire Resistance' : 'RE R', - 'Cold Resistance' : 'COLD R', - 'Energy Resistance' : 'DamageType[4]', - 'Negative Energy Resistance' : 'GY R', - 'Psyonic Resistance' : 'NIC R', - 'Toxic Resistance' : 'XIC R', - }, - 'Defense' : { - 'Base Defense' : 'BAS', - 'Ranged Defense' : 'ED', - 'Melee Defense' : 'MEL', - 'AoE Defense' : '2', - 'Smashing Defense' : '3', - 'Lethal Defense' : '4', - 'Fire Defense' : '5', - 'Cold Defense' : '6', - 'Energy Defense' : '7', - 'Negative Energy Defense' : '8', - 'Psionic Defense' : '9', - 'Toxic Defense' : '1', - }, - 'Debuff Resistance' : { - 'Regeneration Resistance' : 'ON R', - 'Recovery Resistance' : 'RY R', - 'To Hit Resistance' : 'IT R', - 'Defense Resistance' : 'NSE RES', - }, - 'Status Effect Protection' : { - 'Hold Protection' : 'D P', - 'Immobilize Protection' : 'LIZE P', - 'Stun Protection' : 'N P', - 'Sleep Protection' : 'P P', - 'Knockback Protection' : 'K P', - 'Confuse Protection' : 'SE P', - 'Terrorize Protection' : 'ZE P', - 'Repel Protection' : 'EL P', - 'Teleport Protection' : 'T P', - }, - 'Status Effect Resistance' : { - 'Hold Resistance' : 'D R', - 'Immobilize Resistance' : 'LIZE R', - 'Stun Resistance' : 'N R', - 'Sleep Resistance' : 'P R', - 'Knockback Resistance' : 'K R', - 'Confuse Resistance' : 'SE R', - 'Terrorize Resistance' : 'ZE R', - 'Placate Resistance' : 'TE R', - 'Taunt Resistance' : 'NT R', - }, - 'Miscellaneous' : { - 'Level Shift' : 'L S', - }, - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.AttributeMenu = wx.Menu() - for group, controls in self.AttributeTable.items(): - submenu = wx.Menu() - self.AttributeMenu.AppendSubMenu(submenu, group) - for cb in controls: - submenu.Append(wx.ID_ANY, cb) - - self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) - - self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) - groupSizer.Add(self.editbox) - - newButton = self.editbox.GetNewButton() - newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) - - return groupSizer - - def MakeBindString(self): - map = {} - bindstrings = [] - for _, controls in self.AttributeTable.items(): - for cb, data in controls.items(): - map[cb] = data - - for string in self.editbox.GetStrings(): - if string: - bindstrings.append(f'monitorattribute {map[string]}') - - return '$$'.join(bindstrings) - - def Serialize(self): - return { - 'attributes' : self.editbox.GetStrings() - } - - def Deserialize(self, init): - self.editbox.SetStrings(init.get('attributes', [])) - - def OnNewButton(self, evt): - evt.GetEventObject().PopupMenu(self.AttributeMenu) - - def OnMenuItem(self, evt): - menuitem = evt.EventObject.FindItemById(evt.GetId()) - existingstrings = self.editbox.GetStrings() - existingstrings.append(menuitem.GetItemLabel()) - self.editbox.SetStrings(existingstrings) - -####### Auto Power -class AutoPowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) - autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.autoPowerName = PowerPicker(dialog) - autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) - - return autoPowerSizer - - def MakeBindString(self): - return f"powexecauto {self.autoPowerName.GetLabel()}" - - def Serialize(self): - return { - 'pname' : self.autoPowerName.GetLabel(), - 'picon' : self.autoPowerName.IconFilename - } - - def Deserialize(self, init): - if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.buffDisplayMap = { - 'Status Window' : { - 'Hide Auto' : 1, - 'Hide Toggles' : 2, - 'No Blinking' : 4, - 'No Stacking' : 8, - 'Numeric Stacking' : 16, - 'Hide Buff Numbers' : 32, - 'Stop Sending Buffs' : 64, - }, - 'Group Window' : { - 'Hide Auto' : 256, - 'Hide Toggles' : 512, - 'No Blinking' : 1024, - 'No Stacking' : 2048, - 'Numeric Stacking' : 4096, - 'Hide Buff Numbers' : 8192, - 'Stop Sending Buffs' : 16384, - }, - 'Pet Window' : { - 'Hide Auto' : 65536, - 'Hide Toggles' : 131072, - 'No Blinking' : 262144, - 'No Stacking' : 524288, - 'Numeric Stacking' : 1048576, - 'Hide Buff Numbers' : 2097152, - 'Stop Sending Buffs' : 4194304, - }, - } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - for group, controls in self.buffDisplayMap.items(): - self.Groups[group] = ControlGroup(dialog, self.Page, label = group) - groupid = self.Groups[group].GetStaticBox().GetId() - for cb, data in controls.items(): - self.Groups[group].AddControl( - ctlType = 'checkbox', - ctlName = f"{groupid}_{group}_{cb}", - label = cb, - data = data, - ) - - groupSizer.Add(self.Groups[group]) - - return groupSizer - - def CalculateValue(self): - page = wx.App.Get().Main.Profile.CustomBinds - - total = 0 - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] - if checkbox.IsChecked(): - total = total + checkbox.Data - return total - - def MakeBindString(self): - return f"optionset buffsettings {self.CalculateValue()}" - - def Serialize(self): - return { 'value' : self.CalculateValue() } - - def Deserialize(self, init): - value = init.get('value', 0) - - value = value or 0 # in case we had for some reason 'None' stashed in the init values - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] - checkbox.SetValue( checkbox.Data & value ) - -####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - chatCommandSizer = wx.GridBagSizer(5, 5) - self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") - chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) - # row 1 - self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) - self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) - self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) - # row 2 - self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) - self.chatCommandDuration.SetRange(1, 20) - self.chatCommandDuration.SetValue(7) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandDuration, (2,1)) - self.chatCommandChatSize = wx.Choice(dialog, -1, - choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) - self.chatCommandChatSize.SetSelection(5) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) - self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) - self.chatCommandChannel.SetSelection(0) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChannel, (2,5)) - # row 3 - self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") - chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) - self.chatCommandMessage = wx.TextCtrl(dialog, -1) - self.chatCommandMessage.SetHint('Chat Command Text') - chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) - - return chatCommandSizer - - def MakeBindString(self): - duration = self.chatCommandDuration.GetValue() - - choice = self.chatCommandChatSize - index = choice.GetSelection() - size = choice.GetString(index) - - duration = f"" if duration != 7 else "" - size = f"" if size != "1" else "" - - bdcolor = fgcolor = bgcolor = '' - if self.chatCommandUseColorsCB.IsChecked(): - bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - - bdcolor = f"" - fgcolor = f"" - bgcolor = f"" - - beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' - text = self.chatCommandMessage.GetValue() - - choice = self.chatCommandChannel - index = choice.GetSelection() - channel = choice.GetString(index) - - return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" - - def Serialize(self): - return { - 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), - 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), - 'channel' : self.chatCommandChannel .GetSelection(), - 'size' : self.chatCommandChatSize.GetSelection(), - 'duration' : self.chatCommandDuration.GetValue(), - 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'text' : self.chatCommandMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) - if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) - if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) - if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) - if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) - if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) - if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) - if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) - if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - - -####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): - def BuildUI(self, dialog): - chatCommandGlobalSizer = wx.GridBagSizer(5,5) - - self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") - chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) - - self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalChannel.SetHint("Channel") - chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) - - self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') - chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) - - chatCommandGlobalSizer.AddGrowableCol(1) - - return chatCommandGlobalSizer - - def MakeBindString(self): - useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() - channel = self.chatCommandGlobalChannel.GetValue() - message = self.chatCommandGlobalMessage.GetValue() - - preface = "beginchat /" if useBeginchat else "" - - return f'{preface}send "{channel}" {message}' - - def Serialize(self): - return { - 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), - 'channel' : self.chatCommandGlobalChannel.GetValue(), - 'message' : self.chatCommandGlobalMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) - if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) - if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) - -#######Costume Change -class CostumeChangeCmd(PowerBindCmd): - def BuildUI(self, dialog): - costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeCostume = wx.Choice(dialog, -1, - choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) - self.costumeChangeCostume.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeEmote = wx.Choice(dialog, -1, - choices = GameData.Emotes['costumechange']) - self.costumeChangeEmote.Insert("- None -", 0) - self.costumeChangeEmote.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return costumeChangeSizer - - def MakeBindString(self): - costumeNumber = self.costumeChangeCostume.GetSelection() - costumeEmote = self.costumeChangeEmote.GetSelection() - - if costumeEmote: # None, or 0 == "- None -" - ccCmd = 'cce' - emoteName = self.costumeChangeEmote.GetString(costumeEmote) - emoteName = " CC" + emoteName.replace(" ","") - else: - ccCmd = 'cc' - emoteName = '' - - return f"{ccCmd} {costumeNumber}{emoteName}" - - def Serialize(self): - return{ - 'costumeNumber': self.costumeChangeCostume.GetSelection(), - 'costumeEmote' : self.costumeChangeEmote.GetSelection(), - } - - def Deserialize(self, init): - if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) - if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) - -####### Movement Command -class MovementCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - self.plusbutton.SetValue(True) - - self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.commandchoice = wx.Choice(dialog, choices = [ - "forward", "left", "right", "backward", "up", "down", - "turnleft", "turnright", "first", "autorun", "clicktomove", - ],) - sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) - self.commandchoice.SetSelection(0) - - self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - pre = post = '' - if self.plusbutton.GetValue() : pre = "+" - elif self.plusplusbutton.GetValue() : pre = "++" - elif self.minusbutton.GetValue() : pre = "-" - elif self.zerobutton.GetValue() : post = " 0" - elif self.onebutton.GetValue() : post = " 1" - - command = self.commandchoice.GetString(self.commandchoice.GetSelection()) - - return f"{pre}{command}{post}" - - def Serialize(self): - mod = '' - if self.plusbutton.GetValue() : mod = "plus" - elif self.plusplusbutton.GetValue() : mod = "plusplus" - elif self.minusbutton.GetValue() : mod = "minus" - elif self.zerobutton.GetValue() : mod = "zero" - elif self.onebutton.GetValue() : mod = "one" - - return { - 'mod' : mod, - 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), - } - - def Deserialize(self, init): - mod = init.get('mod', 'plus') - - if mod == 'plus' : self.plusbutton.SetValue(True) - elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) - elif mod == 'minus' : self.minusbutton.SetValue(True) - elif mod == 'zero' : self.zerobutton.SetValue(True) - elif mod == 'one' : self.onebutton.SetValue(True) - - self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) - -####### Graphics Command -class GraphicsCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.FlexGridSizer(2) - - self.visscalecb = wx.CheckBox(dialog, label = "visscale") - sizer.Add(self.visscalecb) - self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) - sizer.Add(self.visscalesc) - - self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") - sizer.Add(self.dofweightcb) - self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) - sizer.Add(self.dofweightsc) - - self.fsaacb = wx.CheckBox(dialog, label = "fsaa") - sizer.Add(self.fsaacb) - self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) - self.fsaach.SetSelection(0) - sizer.Add(self.fsaach) - - self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") - sizer.Add(self.bloomscalecb) - self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) - self.bloomscalech.SetSelection(0) - sizer.Add(self.bloomscalech) - - self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") - sizer.Add(self.bloomweightcb) - self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) - sizer.Add(self.bloomweightsc) - - self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") - sizer.Add(self.lodbiascb) - self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) - sizer.Add(self.lodbiassc) - - self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") - sizer.Add(self.renderscalecb) - self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) - sizer.Add(self.renderscalesc) - - return sizer - - def MakeBindString(self): - # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. - bindstrings = [] - if self.visscalecb.IsChecked(): - bindstrings.append("visscale " + str(self.visscalesc.GetValue())) - if self.dofweightcb.IsChecked(): - bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) - if self.fsaacb.IsChecked(): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bindstrings.append("fsaa " + fsaavalue) - if self.bloomscalecb.IsChecked(): - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - bindstrings.append("bloomscale " + bloomscalevalue) - if self.bloomweightcb.IsChecked(): - bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) - if self.lodbiascb.IsChecked(): - bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) - if self.renderscalecb.IsChecked(): - bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) - - return '$$'.join(bindstrings) - - def Serialize(self): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - return { - 'visscalecb' : self.visscalecb.IsChecked(), - 'visscalesc' : self.visscalesc.GetValue(), - 'dofweightcb' : self.dofweightcb.IsChecked(), - 'dofweightsc' : self.dofweightsc.GetValue(), - 'fsaacb' : self.fsaacb.IsChecked(), - 'fsaach' : fsaavalue, - 'bloomscalecb' : self.bloomscalecb.IsChecked(), - 'bloomscalech' : bloomscalevalue, - 'bloomweightcb' : self.bloomweightcb.IsChecked(), - 'bloomweightsc' : self.bloomweightsc.GetValue(), - 'lodbiascb' : self.lodbiascb.IsChecked(), - 'lodbiassc' : self.lodbiassc.GetValue(), - 'renderscalecb' : self.renderscalecb.IsChecked(), - 'renderscalesc' : self.renderscalesc.GetValue(), - } - - def Deserialize(self, init): - self.visscalecb.SetValue(init.get('visscalecb', False)) - self.visscalesc.SetValue(init.get('visscalesc', 1.0)) - self.dofweightcb.SetValue(init.get('dofweightcb', False)) - self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) - self.fsaacb.SetValue(init.get('fsaacb', False)) - self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) - self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) - self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) - self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) - self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) - self.lodbiascb.SetValue(init.get('lodbiascb', False)) - self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) - self.renderscalecb.SetValue(init.get('renderscalecb', False)) - self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) - -####### Custom Bind -class CustomBindCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.customBindName = wx.TextCtrl(dialog, -1) - self.customBindName.SetHint('Custom Bind Text') - sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - return self.customBindName.GetValue() - - def Serialize(self): - return { 'customBindName': self.customBindName.GetValue() } - - def Deserialize(self,init): - if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) - -####### Emote -class EmoteCmd(PowerBindCmd): - def BuildUI(self, dialog): - emoteSizer = wx.BoxSizer(wx.HORIZONTAL) - self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") - emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - self.emoteName = wx.Button(dialog, -1, "...") - self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) - emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) - - return emoteSizer - - def MakeBindString(self): - displayedEmoteName = self.emoteName.GetLabel() - actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] - - return actualEmotePayload - - def Serialize(self): - return {'emoteName': self.emoteName.GetLabel()} - - def Deserialize(self, init): - if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) - -####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): - def BuildUI(self, dialog): - mainSizer = wx.BoxSizer(wx.VERTICAL) - - lbSizer = wx.BoxSizer(wx.HORIZONTAL) - lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") - lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - profiles = Profile.GetAllProfileBindsDirs() - - self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) - lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) - - mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") - self.lbResetCB.SetValue(True) - - mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - return mainSizer - - def MakeBindString(self): - - # If the specified binds directory disappeared between runs, we'd crash, so handle that. - if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' - - config = wx.ConfigBase.Get() - if config.Exists('GameBindPath'): - bindpath = config.Read('GameBindPath') - else: - bindpath = config.Read('BindPath') - - reset = "" - if self.lbResetCB.GetValue(): - reset = "keybind_reset$$" - - resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' - return reset + 'bindloadfile ' + str(resetfilepath) - - def Serialize(self): - return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), - 'ResetKeybinds' : self.lbResetCB.GetValue(), - } - - def Deserialize(self, init): - if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) - self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) - -####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' - -####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' - -####### SG Mode -class SGModeCmd(PowerBindCmd): - def BuildUI(self, dialog): - sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) - sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") - self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") - - sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) - - return sgmodeSizer - - def MakeBindString(self): - if self.sgmodeOnRB.GetValue(): - return 'sgmodeset 1' - elif self.sgmodeOffRB.GetValue(): - return 'sgmodeset 0' - else: - return 'sgmode' - - def Serialize(self): - if self.sgmodeOnRB.GetValue(): - val = "On" - elif self.sgmodeOffRB.GetValue(): - val = "Off" - else: - val = "Toggle" - - return {"value" : val} - - def Deserialize(self, init): - val = init.get('value', '') - if val == "On": - self.sgmodeOnRB.SetValue(True) - elif val == "Off": - self.sgmodeOffRB.SetValue(True) - else: - self.sgmodeToggleRB.SetValue(True) - -####### Target Custom -class TargetCustomCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetCustomSizer = wx.GridBagSizer(5,5) - targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), - flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) - self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetCustomModeChoice.SetSelection(0) - targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) - self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) - self.targetCustomOptionalName.SetHint("Optional name to match") - targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) - self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") - targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) - self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") - targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) - self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") - targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) - self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") - targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) - self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") - targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) - self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") - targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) - self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") - targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) - self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") - targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) - - targetCustomSizer.AddGrowableCol(2) - - return targetCustomSizer - - def MakeBindString(self): - choice = self.targetCustomModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - targetCommand = "targetcustom" + mode.lower() - - enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" - friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" - defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" - alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" - mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" - notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" - base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" - notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" - - name = self.targetCustomOptionalName.GetValue() - - return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" - - def Serialize(self): - return { - 'mode' : self.targetCustomModeChoice.GetSelection(), - 'enemy' : self.targetCustomCBEnemies. IsChecked(), - 'friend' : self.targetCustomCBFriends. IsChecked(), - 'defeated' : self.targetCustomCBDefeated. IsChecked(), - 'alive' : self.targetCustomCBAlive. IsChecked(), - 'mypet' : self.targetCustomCBMyPets. IsChecked(), - 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), - 'base' : self.targetCustomCBBaseItems. IsChecked(), - 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), - 'name' : self.targetCustomOptionalName.GetValue(), - } - - def Deserialize(self, init): - if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) - if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) - if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) - if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) - if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) - if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) - if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) - if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) - if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) - if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - - -####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) - targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetEnemyModeChoice.SetSelection(0) - targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetEnemySizer - - def MakeBindString(self): - choice = self.targetEnemyModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetenemy" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetEnemyModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) - -####### Target Friend -class TargetFriendCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) - targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetFriendModeChoice.SetSelection(0) - targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetFriendSizer - - def MakeBindString(self): - choice = self.targetFriendModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetfriend" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetFriendModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) +from UI.PowerBinderCommand import PowerBinderCommand ####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): +class TeamPetSelectCmd(PowerBinderCommand): + Name = "Team/Pet Select" + Menu = "Targeting" + def BuildUI(self, dialog): teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) @@ -1269,532 +41,3 @@ def Deserialize(self, init): else: self.teamPetSelectTeamRB.SetValue(True) if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) - -####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' - -####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) - for _, types in GameData.Inspirations.items(): - for _, info in types.items(): - for insp in info['tiers']: - name = re.sub(' ', '', str(insp)) - icon = GetIcon(f'Inspirations/{name}') - self.useInspByNameModeChoice.Append(insp, icon) - self.useInspByNameModeChoice.SetSelection(0) - useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) - - return useInspByNameSizer - - def MakeBindString(self): - choice = self.useInspByNameModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "inspexecname " + mode.lower() - - def GetAllInsps(self): - Insplist = [] - for _, info in GameData.Inspirations.items(): - for insp in info['tiers']: - Insplist.append(insp) - Insplist.append("---") - Insplist.pop(-1) # snip the terminal "---" - - return Insplist - - def Serialize(self): - return { 'insp' : self.useInspByNameModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) - -####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnRow.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) - self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnCol.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) - - return useInspRowColumnSizer - - def MakeBindString(self): - row = self.useInspRowColumnRow.GetSelection()+1 - col = self.useInspRowColumnCol.GetSelection()+1 - - return f"inspexectray {col} {row}" - - def Serialize(self): - return { - 'col' : self.useInspRowColumnCol.GetSelection(), - 'row' : self.useInspRowColumnRow.GetSelection(), - } - - def Deserialize(self, init): - if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) - if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) - -####### Use Power -class UsePowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - outerSizer = wx.BoxSizer(wx.HORIZONTAL) - - usePowerSizer = wx.GridBagSizer(5,5) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBToggle, (0,1)) - self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOn, (0,2)) - self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOff, (0,3)) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerName = PowerPicker(dialog) - usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) - usePowerSizer.AddGrowableCol(3) - - outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) - - return outerSizer - - def MakeBindString(self): - if self.usePowerRBToggle.GetValue(): - method = "powexecname" - elif self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') - return '' - - return f"{method} {self.usePowerName.GetLabel()}" - - def Serialize(self): - if self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - method = "powexecname" - return { - 'method': method, - 'pname' : self.usePowerName.GetLabel(), - 'picon' : self.usePowerName.IconFilename - } - - def Deserialize(self, init): - method = init.get('method', '') - if method == 'powexectoggleon': - self.usePowerRBOn.SetValue(True) - elif method == 'powexectoggleoff': - self.usePowerRBOff.SetValue(True) - else: - self.usePowerRBToggle.SetValue(True) - if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) - -####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): - def BuildUI(self, dialog): - usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTrayTray = wx.Choice(dialog, -1, - choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', - 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) - self.usePowerFromTrayTray.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) - self.usePowerFromTraySlot.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return usePowerFromTraySizer - - def MakeBindString(self): - choice = self.usePowerFromTrayTray - tray = choice.GetSelection() - - choice = self.usePowerFromTraySlot - slot = choice.GetSelection()+1 - - mode = "slot" - mode2 = '' - if tray > 3: - mode = "tray" - mode2 = f" {tray - 3}" - elif tray == 3: - mode = "alt2slot" - elif tray == 2: - mode = "altslot" - - return f"powexec{mode} {slot}{mode2}" - - def Serialize(self): - return { - 'tray' : self.usePowerFromTrayTray.GetSelection(), - 'slot' : self.usePowerFromTraySlot.GetSelection(), - } - - def Deserialize(self, init): - if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) - if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) - -####### Window Color -class WindowColorCmd(PowerBindCmd): - def BuildUI(self, dialog): - windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) - borderSizer = wx.BoxSizer(wx.VERTICAL) - self.ColorBorder.SetSizer(borderSizer) - self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) - borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) - - windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) - - RGBASizer = wx.FlexGridSizer(3, 4, 5) - - RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) - self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) - self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - windowColorSizer.Add(RGBASizer) - - self.UpdateFromSlider() - - return windowColorSizer - - def MakeBindString(self): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - return f"windowcolor {Rval} {Gval} {Bval} {Aval}" - - def Serialize(self): - return { - 'Rval' : self.RSlider.GetValue(), - 'Gval' : self.GSlider.GetValue(), - 'Bval' : self.BSlider.GetValue(), - 'Aval' : self.ASlider.GetValue(), - } - - def Deserialize(self, init): - self.RSlider.SetValue(init['Rval']) - self.GSlider.SetValue(init['Gval']) - self.BSlider.SetValue(init['Bval']) - self.ASlider.SetValue(init['Aval']) - self.UpdateFromSlider() - - def UpdateFromSlider(self, _ = None): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RReadout.SetValue(Rval) - self.GReadout.SetValue(Gval) - self.BReadout.SetValue(Bval) - self.AReadout.SetValue(Aval) - self.ColorBorder.Refresh() - - def UpdateFromText(self, _ = None): - Rval = self.RReadout.GetValue() - Gval = self.GReadout.GetValue() - Bval = self.BReadout.GetValue() - Aval = self.AReadout.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RSlider.SetValue(Rval) - self.GSlider.SetValue(Gval) - self.BSlider.SetValue(Bval) - self.ASlider.SetValue(Aval) - self.ColorBorder.Refresh() - -####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) - self.CommandChoice.SetSelection(0) - sizer.Add(self.CommandChoice, 0, wx.ALL, 5) - - self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), - value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) - sizer.Add(self.FilePath, 0, wx.ALL, 5) - - return sizer - - def MakeBindString(self): - command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] - return f'{command} "{self.FilePath.GetValue()}"' - - def Serialize(self): - return { - 'command' : self.CommandChoice.GetSelection(), - 'filename' : self.FilePath.GetValue(), - } - - def Deserialize(self, init): - self.CommandChoice.SetSelection(init.get('command', 0)) - self.FilePath.SetValue(init.get('filename', '')) - -####### Window Toggle -class WindowToggleCmd(PowerBindCmd): - def BuildUI(self, dialog): - self.WindowNames = { - 'Actions' : 'actions', - 'Auction House' : 'ah', - 'Badge' : 'badge', - 'Channel Search' : 'chansearch', - 'Chat' : 'chat', - 'Custom Chat 1' : 'chat1', - 'Custom Chat 2' : 'chat2', - 'Custom Chat 3' : 'chat3', - 'Custom Chat 4' : 'chat4', - 'Clues' : 'clue', - 'Combat Numbers' : 'combatnumbers', - 'Contacts' : 'contact', - 'Contact Finder' : 'contactfinder', - 'Costumes' : 'costume', - 'Email' : 'email', - 'Enhancements' : 'enhancements', - 'Friends' : 'friend', - 'Group' : 'group', - 'Help' : 'helpwindow', - 'Incarnate' : 'incarnate', - 'Inspirations' : 'insp', - 'League' : 'league', - 'LFG' : 'lfg', - 'Map' : 'map', - 'Mission' : 'mission', - 'Nav / Compass' : 'nav', - 'Options' : 'options', - 'Pets' : 'pet', - 'Petition' : 'petition', - 'Power Tray' : 'powers', - 'Power List' : 'powerlist', - 'Quit' : 'quit', - 'Recipes' : 'recipe', - 'Salvage' : 'salvage', - 'Search' : 'search', - 'Supergroup' : 'sg', - 'Target' : 'target', - 'Team' : 'team', - 'Tray' : 'tray', - 'Tray1' : 'tray1', - 'Tray2' : 'tray2', - 'Tray3' : 'tray3', - 'Tray4' : 'tray4', - 'Tray5' : 'tray5', - 'Tray6' : 'tray6', - 'Tray7' : 'tray7', - 'Tray8' : 'tray8', - 'Vault' : 'vault', - } - - self.ShortToggleCommands = { - 'Auction House' : 'ah', - 'Chat' : 'chat', - 'Help' : 'helpwindow', - 'Map' : 'map', - 'Nav / Compass' : 'nav', - 'Power Tray' : 'powers', - 'Target' : 'target', - 'Tray' : 'tray', - } - - windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) - windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) - self.windowToggleTray.SetSelection(0) - windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.windowShowRB = wx.RadioButton(dialog, -1, "Show") - self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") - - windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) - - return windowToggleSizer - - def MakeBindString(self): - choice = self.windowToggleTray - index = choice.GetSelection() - windowdesc = choice.GetString(index) - windowname = self.WindowNames[windowdesc] - - if self.windowShowRB.GetValue(): - return 'show ' + windowname - elif self.windowHideRB.GetValue(): - return 'windowhide ' + windowname - else: - if shortcmd := self.ShortToggleCommands.get(windowdesc, None): - return shortcmd - else: - return 'toggle ' + windowname - - - def Serialize(self): - choice = self.windowToggleTray - if self.windowShowRB.GetValue(): - action = "Show" - elif self.windowHideRB.GetValue(): - action = "Hide" - else: - action = "Toggle" - return { - 'window': choice.GetString(choice.GetSelection()), - 'action': action, - } - - def Deserialize(self, init): - choice = self.windowToggleTray - if window := init.get('window', ''): - if isinstance(window, int): - choice.SetSelection(window) - else: - choice.SetSelection(choice.FindString(window)) - - if choice.GetSelection() == wx.NOT_FOUND: - choice.SetSelection(0) - - action = init.get('action', '') - if action == "Show": - self.windowShowRB.SetValue(True) - elif action == "Hide": - self.windowHideRB.SetValue(True) - else: - self.windowToggleRB.SetValue(True) - - -# Must always add to this list when adding a new command class above -menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], - # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, - # but I'm leaving it here to remind myself that we do that. - } - -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/UnselectCmd.py b/UI/PowerBinderCommand/UnselectCmd.py index 4c02ab7..7271757 100644 --- a/UI/PowerBinderCommand/UnselectCmd.py +++ b/UI/PowerBinderCommand/UnselectCmd.py @@ -1,1800 +1,9 @@ -import wx -import re -import UI -import UI.EmotePicker -from UI.ControlGroup import ControlGroup -from UI.PowerPicker import PowerPicker -from Help import HelpButton -import wx.adv -from wx.adv import BitmapComboBox, EditableListBox -from pathlib import PureWindowsPath -import GameData -import Profile -from Icon import GetIcon - -class PowerBinderDialog(wx.Dialog): - def __init__(self, parent, button, init = {}): - wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) - - self.Page = parent.Page - self.EditDialog = PowerBinderEditDialog(self) - self.Button = button - self.AddStepMenu = self.makeAddStepMenu() - - sizer = wx.BoxSizer(wx.VERTICAL); - self.mainSizer = sizer - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) - AddStepButton = wx.Button(self, -1, 'Add Step') - AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) - AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) - choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) - choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) - sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) - - rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) - - self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) - self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) - self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) - rearrangeCtrl.Add(self.RearrangeList, 1) - - rearrangeButtons = wx.BoxSizer(wx.VERTICAL) - self.DelButton = wx.Button(self, -1, "Delete") - self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) - self.EditButton = wx.Button(self, -1, "Edit") - self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) - self.EditButton.Disable() - upButton = wx.Button(self, -1, "\u25B2") - upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) - downButton = wx.Button(self, -1, "\u25BC") - downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) - rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) - rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) - - sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.BindStringDisplay = wx.TextCtrl(self, -1) - self.BindStringDisplay.Disable() - choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, - wx.ALIGN_CENTER_VERTICAL) - choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) - - sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) - - sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) - - # need to dig around and get the OK button since we show this dialog modelessly now. - okButton = self.FindWindow(self.GetAffirmativeId()) - okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) - - # Wrap everything in a vbox to add some padding - vbox = wx.BoxSizer(wx.VERTICAL); - vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); - - self.SetSizerAndFit(vbox); - self.Layout() - self.Fit() - self.SetFocus() - - # if we are loading from profile, ie, have "init", build the list from it - if init: self.LoadFromData(init) - - def LoadFromData(self, init): - for item in init: - for type, data in item.items(): - commandClass = commandClasses.get(type, None) - if not commandClass: - commandClass = deprecatedCommandClasses.get(type, None) - if not commandClass: - wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") - continue - newCommand = commandClass(self.EditDialog, data) - index = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.SetClientData(index, newCommand) - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) - self.EditDialog.mainSizer.Hide(newCommand.UI) - self.UpdateBindStringDisplay() - - def SaveToData(self): - data = [] - index = 0 - for _ in self.RearrangeList.GetItems(): - # check whether we have an object already attached to this choice - cmdObject = self.RearrangeList.GetClientData(index) - commandClassName = commandRevClasses[type(cmdObject)] - data.append({commandClassName: cmdObject.Serialize()}) - index = index + 1 - return data - - def OnAddStepButton(self, evt): - button = evt.EventObject - if not self.AddStepMenu: - self.AddStepMenu = self.makeAddStepMenu() - button.PopupMenu(self.AddStepMenu) - - - def OnOKButton(self, _): - if self.Button.tgtTxtCtrl: - bindString = self.MakeBindString() - if bindString != self.Button.tgtTxtCtrl.GetValue(): - self.Button.tgtTxtCtrl.SetValue(bindString) - wx.App.Get().Main.Profile.SetModified() - self.Close() - - def OnRearrangeDelete(self, _): - current = self.RearrangeList.GetSelection() - if current == wx.NOT_FOUND: return - - self.RearrangeList.Delete(current) - self.UpdateBindStringDisplay() - - def OnRearrangeUp(self, _): - self.RearrangeList.MoveCurrentUp() - self.UpdateBindStringDisplay() - - def OnRearrangeDown(self, _): - self.RearrangeList.MoveCurrentDown() - self.UpdateBindStringDisplay() - - def OnRearrangeEdit(self, _): - index = self.RearrangeList.GetSelection() - - # check whether we have an object already attached to this choice - cmdObject = None - try: - cmdObject = self.RearrangeList.GetClientData(index) - except Exception: - pass - - if cmdObject: - self.ShowEditDialogFor(cmdObject) - self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) - else: - print("cmdObject was None") - self.UpdateBindStringDisplay() - - # OnAddStepMenu creates a new step and adds it to the rearrangelist - def OnAddStepMenu(self, evt): - menuitem = self.AddStepMenu.FindItemById(evt.GetId()) - chosenName = menuitem.GetItemLabel() - - # make a new command object, attached to the parent dialog - newCommandClass = commandClasses[chosenName] - newCommand = newCommandClass(self.EditDialog) - - # show the edit dialog if this command needs it - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) - if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): - self.EditDialog.mainSizer.Remove(newCommand.UI) - return - - newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.Select(newBindIndex) - self.RearrangeList.SetClientData(newBindIndex, newCommand) - - self.OnListSelect() - self.UpdateBindStringDisplay() - - def OnListSelect(self, _ = None): - selected = self.RearrangeList.GetSelection() - - if selected != wx.NOT_FOUND: - selCommand = self.RearrangeList.GetClientData(selected) - if selCommand.UI: - self.EditButton.Enable() - else: - self.EditButton.Disable() - - def UpdateBindStringDisplay(self): - self.BindStringDisplay.SetValue(self.MakeBindString()) - self.BindStringDisplay.SetToolTip(self.MakeBindString()) - - def MakeBindString(self): - cmdBindStrings = [] - for index in range(self.RearrangeList.GetCount()): - c = self.RearrangeList.GetClientData(index) - if c: cmdBindStrings.append(c.MakeBindString()) - - bindstring = ('$$'.join(cmdBindStrings)) - return bindstring - - def ShowEditDialogFor(self, command): - if not command.UI: return - - self.EditDialog.mainSizer.Show(command.UI) - - self.EditDialog.Layout() - self.EditDialog.Fit() - - self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') - returnval = self.EditDialog.ShowModal() - - self.EditDialog.mainSizer.Hide(command.UI) - - return returnval - - def makeAddStepMenu(self): - - stepMenu = wx.Menu() - - for subname in menuStructure: - submenu = wx.Menu() - stepMenu.AppendSubMenu(submenu, subname) - for classname in menuStructure[subname]: - submenu.Append(wx.ID_ANY, classname) - - stepMenu.Append(wx.ID_ANY, 'Custom Bind') - - return stepMenu - -class PowerBinderButton(wx.BitmapButton): - - def __init__(self, parent, tgtTxtCtrl, init = {}): - wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) - self.Init = init - self.Dialog = None - self.DialogParent = parent - - self.tgtTxtCtrl = tgtTxtCtrl - self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) - self.SetToolTip("Launch PowerBinder") - - def PowerBinderEventHandler(self, _): - self.PowerBinderDialog().Show() - - def LoadFromData(self, data): - self.PowerBinderDialog().LoadFromData(data) - - def SaveToData(self): - return self.PowerBinderDialog().SaveToData() - - def PowerBinderDialog(self): - if not self.Dialog: - self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) - return self.Dialog - - -class PowerBinderEditDialog(wx.Dialog): - def __init__(self, parent): - wx.Dialog.__init__(self, parent, -1, "Edit Step", - style = wx.DEFAULT_DIALOG_STYLE) - - outerSizer = wx.BoxSizer(wx.VERTICAL) - - self.mainSizer = wx.BoxSizer(wx.VERTICAL) - self.mainSizer.SetMinSize([500, 150]) - - self.Page = parent.Page - - self.mainSizer.Add( - self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), - 0, wx.EXPAND|wx.ALL, 10) - - outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) - - self.SetSizerAndFit(outerSizer) - self.Layout() - self.Fit() - -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" - - -####### Away From Keyboard -class AFKCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.Groups = {} - self.AttributeTable = { - 'Base' : { - 'Current Hit Points' : 'NT H', - 'Max Hit Points' : 'X H', - 'Current Endurance' : 'T E', - 'Max Endurance' : 'X EN', - 'Regeneration Rate' : 'N RAT', - 'Recovery Rate' : 'Y RA', - 'Endurance Consumption' : 'SU', - 'ToHit Bonus' : 'T B', - 'Accuracy Bonus' : 'CC', - 'Last Hit Chance' : 'T C', - 'Damage Bonus' : 'DA', - 'Healing Bonus' : 'NG B', - 'Recharge Time Bonus' : 'ME B', - 'Endurance Discount' : 'CE DIS', - 'Stealth Radius (PvP)' : 'PVP', - 'Stealth Radius (PvE)' : 'PVE', - 'Perception Radius' : 'RC', - 'Range Bonus' : 'GE B', - 'Threat Level' : 'AT L', - 'Experience to Next Level' : 'XT', - 'Experience Debt' : 'XP', - 'Influence / Infamy' : 'INF', - 'Inherent' : 'NH', - }, - 'Movement Speed' : { - 'Flying Speed' : 'FL', - 'Jumping Speed' : 'PI', - 'Max Jump Height' : 'X J', - 'Run Speed' : 'RU', - }, - 'Damage Resistance' : { - 'Smashing Resistance' : 'G R', - 'Lethal Resistance' : 'L R', - 'Fire Resistance' : 'RE R', - 'Cold Resistance' : 'COLD R', - 'Energy Resistance' : 'DamageType[4]', - 'Negative Energy Resistance' : 'GY R', - 'Psyonic Resistance' : 'NIC R', - 'Toxic Resistance' : 'XIC R', - }, - 'Defense' : { - 'Base Defense' : 'BAS', - 'Ranged Defense' : 'ED', - 'Melee Defense' : 'MEL', - 'AoE Defense' : '2', - 'Smashing Defense' : '3', - 'Lethal Defense' : '4', - 'Fire Defense' : '5', - 'Cold Defense' : '6', - 'Energy Defense' : '7', - 'Negative Energy Defense' : '8', - 'Psionic Defense' : '9', - 'Toxic Defense' : '1', - }, - 'Debuff Resistance' : { - 'Regeneration Resistance' : 'ON R', - 'Recovery Resistance' : 'RY R', - 'To Hit Resistance' : 'IT R', - 'Defense Resistance' : 'NSE RES', - }, - 'Status Effect Protection' : { - 'Hold Protection' : 'D P', - 'Immobilize Protection' : 'LIZE P', - 'Stun Protection' : 'N P', - 'Sleep Protection' : 'P P', - 'Knockback Protection' : 'K P', - 'Confuse Protection' : 'SE P', - 'Terrorize Protection' : 'ZE P', - 'Repel Protection' : 'EL P', - 'Teleport Protection' : 'T P', - }, - 'Status Effect Resistance' : { - 'Hold Resistance' : 'D R', - 'Immobilize Resistance' : 'LIZE R', - 'Stun Resistance' : 'N R', - 'Sleep Resistance' : 'P R', - 'Knockback Resistance' : 'K R', - 'Confuse Resistance' : 'SE R', - 'Terrorize Resistance' : 'ZE R', - 'Placate Resistance' : 'TE R', - 'Taunt Resistance' : 'NT R', - }, - 'Miscellaneous' : { - 'Level Shift' : 'L S', - }, - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.AttributeMenu = wx.Menu() - for group, controls in self.AttributeTable.items(): - submenu = wx.Menu() - self.AttributeMenu.AppendSubMenu(submenu, group) - for cb in controls: - submenu.Append(wx.ID_ANY, cb) - - self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) - - self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) - groupSizer.Add(self.editbox) - - newButton = self.editbox.GetNewButton() - newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) - - return groupSizer - - def MakeBindString(self): - map = {} - bindstrings = [] - for _, controls in self.AttributeTable.items(): - for cb, data in controls.items(): - map[cb] = data - - for string in self.editbox.GetStrings(): - if string: - bindstrings.append(f'monitorattribute {map[string]}') - - return '$$'.join(bindstrings) - - def Serialize(self): - return { - 'attributes' : self.editbox.GetStrings() - } - - def Deserialize(self, init): - self.editbox.SetStrings(init.get('attributes', [])) - - def OnNewButton(self, evt): - evt.GetEventObject().PopupMenu(self.AttributeMenu) - - def OnMenuItem(self, evt): - menuitem = evt.EventObject.FindItemById(evt.GetId()) - existingstrings = self.editbox.GetStrings() - existingstrings.append(menuitem.GetItemLabel()) - self.editbox.SetStrings(existingstrings) - -####### Auto Power -class AutoPowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) - autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.autoPowerName = PowerPicker(dialog) - autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) - - return autoPowerSizer - - def MakeBindString(self): - return f"powexecauto {self.autoPowerName.GetLabel()}" - - def Serialize(self): - return { - 'pname' : self.autoPowerName.GetLabel(), - 'picon' : self.autoPowerName.IconFilename - } - - def Deserialize(self, init): - if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.buffDisplayMap = { - 'Status Window' : { - 'Hide Auto' : 1, - 'Hide Toggles' : 2, - 'No Blinking' : 4, - 'No Stacking' : 8, - 'Numeric Stacking' : 16, - 'Hide Buff Numbers' : 32, - 'Stop Sending Buffs' : 64, - }, - 'Group Window' : { - 'Hide Auto' : 256, - 'Hide Toggles' : 512, - 'No Blinking' : 1024, - 'No Stacking' : 2048, - 'Numeric Stacking' : 4096, - 'Hide Buff Numbers' : 8192, - 'Stop Sending Buffs' : 16384, - }, - 'Pet Window' : { - 'Hide Auto' : 65536, - 'Hide Toggles' : 131072, - 'No Blinking' : 262144, - 'No Stacking' : 524288, - 'Numeric Stacking' : 1048576, - 'Hide Buff Numbers' : 2097152, - 'Stop Sending Buffs' : 4194304, - }, - } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - for group, controls in self.buffDisplayMap.items(): - self.Groups[group] = ControlGroup(dialog, self.Page, label = group) - groupid = self.Groups[group].GetStaticBox().GetId() - for cb, data in controls.items(): - self.Groups[group].AddControl( - ctlType = 'checkbox', - ctlName = f"{groupid}_{group}_{cb}", - label = cb, - data = data, - ) - - groupSizer.Add(self.Groups[group]) - - return groupSizer - - def CalculateValue(self): - page = wx.App.Get().Main.Profile.CustomBinds - - total = 0 - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] - if checkbox.IsChecked(): - total = total + checkbox.Data - return total - - def MakeBindString(self): - return f"optionset buffsettings {self.CalculateValue()}" - - def Serialize(self): - return { 'value' : self.CalculateValue() } - - def Deserialize(self, init): - value = init.get('value', 0) - - value = value or 0 # in case we had for some reason 'None' stashed in the init values - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] - checkbox.SetValue( checkbox.Data & value ) - -####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - chatCommandSizer = wx.GridBagSizer(5, 5) - self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") - chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) - # row 1 - self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) - self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) - self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) - # row 2 - self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) - self.chatCommandDuration.SetRange(1, 20) - self.chatCommandDuration.SetValue(7) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandDuration, (2,1)) - self.chatCommandChatSize = wx.Choice(dialog, -1, - choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) - self.chatCommandChatSize.SetSelection(5) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) - self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) - self.chatCommandChannel.SetSelection(0) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChannel, (2,5)) - # row 3 - self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") - chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) - self.chatCommandMessage = wx.TextCtrl(dialog, -1) - self.chatCommandMessage.SetHint('Chat Command Text') - chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) - - return chatCommandSizer - - def MakeBindString(self): - duration = self.chatCommandDuration.GetValue() - - choice = self.chatCommandChatSize - index = choice.GetSelection() - size = choice.GetString(index) - - duration = f"" if duration != 7 else "" - size = f"" if size != "1" else "" - - bdcolor = fgcolor = bgcolor = '' - if self.chatCommandUseColorsCB.IsChecked(): - bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - - bdcolor = f"" - fgcolor = f"" - bgcolor = f"" - - beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' - text = self.chatCommandMessage.GetValue() - - choice = self.chatCommandChannel - index = choice.GetSelection() - channel = choice.GetString(index) - - return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" - - def Serialize(self): - return { - 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), - 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), - 'channel' : self.chatCommandChannel .GetSelection(), - 'size' : self.chatCommandChatSize.GetSelection(), - 'duration' : self.chatCommandDuration.GetValue(), - 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'text' : self.chatCommandMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) - if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) - if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) - if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) - if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) - if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) - if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) - if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) - if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - - -####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): - def BuildUI(self, dialog): - chatCommandGlobalSizer = wx.GridBagSizer(5,5) - - self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") - chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) - - self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalChannel.SetHint("Channel") - chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) - - self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') - chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) - - chatCommandGlobalSizer.AddGrowableCol(1) - - return chatCommandGlobalSizer - - def MakeBindString(self): - useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() - channel = self.chatCommandGlobalChannel.GetValue() - message = self.chatCommandGlobalMessage.GetValue() - - preface = "beginchat /" if useBeginchat else "" - - return f'{preface}send "{channel}" {message}' - - def Serialize(self): - return { - 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), - 'channel' : self.chatCommandGlobalChannel.GetValue(), - 'message' : self.chatCommandGlobalMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) - if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) - if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) - -#######Costume Change -class CostumeChangeCmd(PowerBindCmd): - def BuildUI(self, dialog): - costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeCostume = wx.Choice(dialog, -1, - choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) - self.costumeChangeCostume.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeEmote = wx.Choice(dialog, -1, - choices = GameData.Emotes['costumechange']) - self.costumeChangeEmote.Insert("- None -", 0) - self.costumeChangeEmote.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return costumeChangeSizer - - def MakeBindString(self): - costumeNumber = self.costumeChangeCostume.GetSelection() - costumeEmote = self.costumeChangeEmote.GetSelection() - - if costumeEmote: # None, or 0 == "- None -" - ccCmd = 'cce' - emoteName = self.costumeChangeEmote.GetString(costumeEmote) - emoteName = " CC" + emoteName.replace(" ","") - else: - ccCmd = 'cc' - emoteName = '' - - return f"{ccCmd} {costumeNumber}{emoteName}" - - def Serialize(self): - return{ - 'costumeNumber': self.costumeChangeCostume.GetSelection(), - 'costumeEmote' : self.costumeChangeEmote.GetSelection(), - } - - def Deserialize(self, init): - if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) - if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) - -####### Movement Command -class MovementCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - self.plusbutton.SetValue(True) - - self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.commandchoice = wx.Choice(dialog, choices = [ - "forward", "left", "right", "backward", "up", "down", - "turnleft", "turnright", "first", "autorun", "clicktomove", - ],) - sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) - self.commandchoice.SetSelection(0) - - self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - pre = post = '' - if self.plusbutton.GetValue() : pre = "+" - elif self.plusplusbutton.GetValue() : pre = "++" - elif self.minusbutton.GetValue() : pre = "-" - elif self.zerobutton.GetValue() : post = " 0" - elif self.onebutton.GetValue() : post = " 1" - - command = self.commandchoice.GetString(self.commandchoice.GetSelection()) - - return f"{pre}{command}{post}" - - def Serialize(self): - mod = '' - if self.plusbutton.GetValue() : mod = "plus" - elif self.plusplusbutton.GetValue() : mod = "plusplus" - elif self.minusbutton.GetValue() : mod = "minus" - elif self.zerobutton.GetValue() : mod = "zero" - elif self.onebutton.GetValue() : mod = "one" - - return { - 'mod' : mod, - 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), - } - - def Deserialize(self, init): - mod = init.get('mod', 'plus') - - if mod == 'plus' : self.plusbutton.SetValue(True) - elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) - elif mod == 'minus' : self.minusbutton.SetValue(True) - elif mod == 'zero' : self.zerobutton.SetValue(True) - elif mod == 'one' : self.onebutton.SetValue(True) - - self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) - -####### Graphics Command -class GraphicsCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.FlexGridSizer(2) - - self.visscalecb = wx.CheckBox(dialog, label = "visscale") - sizer.Add(self.visscalecb) - self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) - sizer.Add(self.visscalesc) - - self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") - sizer.Add(self.dofweightcb) - self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) - sizer.Add(self.dofweightsc) - - self.fsaacb = wx.CheckBox(dialog, label = "fsaa") - sizer.Add(self.fsaacb) - self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) - self.fsaach.SetSelection(0) - sizer.Add(self.fsaach) - - self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") - sizer.Add(self.bloomscalecb) - self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) - self.bloomscalech.SetSelection(0) - sizer.Add(self.bloomscalech) - - self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") - sizer.Add(self.bloomweightcb) - self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) - sizer.Add(self.bloomweightsc) - - self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") - sizer.Add(self.lodbiascb) - self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) - sizer.Add(self.lodbiassc) - - self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") - sizer.Add(self.renderscalecb) - self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) - sizer.Add(self.renderscalesc) - - return sizer - - def MakeBindString(self): - # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. - bindstrings = [] - if self.visscalecb.IsChecked(): - bindstrings.append("visscale " + str(self.visscalesc.GetValue())) - if self.dofweightcb.IsChecked(): - bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) - if self.fsaacb.IsChecked(): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bindstrings.append("fsaa " + fsaavalue) - if self.bloomscalecb.IsChecked(): - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - bindstrings.append("bloomscale " + bloomscalevalue) - if self.bloomweightcb.IsChecked(): - bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) - if self.lodbiascb.IsChecked(): - bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) - if self.renderscalecb.IsChecked(): - bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) - - return '$$'.join(bindstrings) - - def Serialize(self): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - return { - 'visscalecb' : self.visscalecb.IsChecked(), - 'visscalesc' : self.visscalesc.GetValue(), - 'dofweightcb' : self.dofweightcb.IsChecked(), - 'dofweightsc' : self.dofweightsc.GetValue(), - 'fsaacb' : self.fsaacb.IsChecked(), - 'fsaach' : fsaavalue, - 'bloomscalecb' : self.bloomscalecb.IsChecked(), - 'bloomscalech' : bloomscalevalue, - 'bloomweightcb' : self.bloomweightcb.IsChecked(), - 'bloomweightsc' : self.bloomweightsc.GetValue(), - 'lodbiascb' : self.lodbiascb.IsChecked(), - 'lodbiassc' : self.lodbiassc.GetValue(), - 'renderscalecb' : self.renderscalecb.IsChecked(), - 'renderscalesc' : self.renderscalesc.GetValue(), - } - - def Deserialize(self, init): - self.visscalecb.SetValue(init.get('visscalecb', False)) - self.visscalesc.SetValue(init.get('visscalesc', 1.0)) - self.dofweightcb.SetValue(init.get('dofweightcb', False)) - self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) - self.fsaacb.SetValue(init.get('fsaacb', False)) - self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) - self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) - self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) - self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) - self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) - self.lodbiascb.SetValue(init.get('lodbiascb', False)) - self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) - self.renderscalecb.SetValue(init.get('renderscalecb', False)) - self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) - -####### Custom Bind -class CustomBindCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.customBindName = wx.TextCtrl(dialog, -1) - self.customBindName.SetHint('Custom Bind Text') - sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - return self.customBindName.GetValue() - - def Serialize(self): - return { 'customBindName': self.customBindName.GetValue() } - - def Deserialize(self,init): - if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) - -####### Emote -class EmoteCmd(PowerBindCmd): - def BuildUI(self, dialog): - emoteSizer = wx.BoxSizer(wx.HORIZONTAL) - self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") - emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - self.emoteName = wx.Button(dialog, -1, "...") - self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) - emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) - - return emoteSizer - - def MakeBindString(self): - displayedEmoteName = self.emoteName.GetLabel() - actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] - - return actualEmotePayload - - def Serialize(self): - return {'emoteName': self.emoteName.GetLabel()} - - def Deserialize(self, init): - if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) - -####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): - def BuildUI(self, dialog): - mainSizer = wx.BoxSizer(wx.VERTICAL) - - lbSizer = wx.BoxSizer(wx.HORIZONTAL) - lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") - lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - profiles = Profile.GetAllProfileBindsDirs() - - self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) - lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) - - mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") - self.lbResetCB.SetValue(True) - - mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - return mainSizer - - def MakeBindString(self): - - # If the specified binds directory disappeared between runs, we'd crash, so handle that. - if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' - - config = wx.ConfigBase.Get() - if config.Exists('GameBindPath'): - bindpath = config.Read('GameBindPath') - else: - bindpath = config.Read('BindPath') - - reset = "" - if self.lbResetCB.GetValue(): - reset = "keybind_reset$$" - - resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' - return reset + 'bindloadfile ' + str(resetfilepath) - - def Serialize(self): - return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), - 'ResetKeybinds' : self.lbResetCB.GetValue(), - } - - def Deserialize(self, init): - if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) - self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) - -####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' - -####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' - -####### SG Mode -class SGModeCmd(PowerBindCmd): - def BuildUI(self, dialog): - sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) - sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") - self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") - - sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) - - return sgmodeSizer - - def MakeBindString(self): - if self.sgmodeOnRB.GetValue(): - return 'sgmodeset 1' - elif self.sgmodeOffRB.GetValue(): - return 'sgmodeset 0' - else: - return 'sgmode' - - def Serialize(self): - if self.sgmodeOnRB.GetValue(): - val = "On" - elif self.sgmodeOffRB.GetValue(): - val = "Off" - else: - val = "Toggle" - - return {"value" : val} - - def Deserialize(self, init): - val = init.get('value', '') - if val == "On": - self.sgmodeOnRB.SetValue(True) - elif val == "Off": - self.sgmodeOffRB.SetValue(True) - else: - self.sgmodeToggleRB.SetValue(True) - -####### Target Custom -class TargetCustomCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetCustomSizer = wx.GridBagSizer(5,5) - targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), - flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) - self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetCustomModeChoice.SetSelection(0) - targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) - self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) - self.targetCustomOptionalName.SetHint("Optional name to match") - targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) - self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") - targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) - self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") - targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) - self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") - targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) - self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") - targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) - self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") - targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) - self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") - targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) - self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") - targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) - self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") - targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) - - targetCustomSizer.AddGrowableCol(2) - - return targetCustomSizer - - def MakeBindString(self): - choice = self.targetCustomModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - targetCommand = "targetcustom" + mode.lower() - - enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" - friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" - defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" - alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" - mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" - notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" - base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" - notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" - - name = self.targetCustomOptionalName.GetValue() - - return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" - - def Serialize(self): - return { - 'mode' : self.targetCustomModeChoice.GetSelection(), - 'enemy' : self.targetCustomCBEnemies. IsChecked(), - 'friend' : self.targetCustomCBFriends. IsChecked(), - 'defeated' : self.targetCustomCBDefeated. IsChecked(), - 'alive' : self.targetCustomCBAlive. IsChecked(), - 'mypet' : self.targetCustomCBMyPets. IsChecked(), - 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), - 'base' : self.targetCustomCBBaseItems. IsChecked(), - 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), - 'name' : self.targetCustomOptionalName.GetValue(), - } - - def Deserialize(self, init): - if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) - if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) - if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) - if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) - if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) - if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) - if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) - if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) - if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) - if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - - -####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) - targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetEnemyModeChoice.SetSelection(0) - targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetEnemySizer - - def MakeBindString(self): - choice = self.targetEnemyModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetenemy" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetEnemyModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) - -####### Target Friend -class TargetFriendCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) - targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetFriendModeChoice.SetSelection(0) - targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetFriendSizer - - def MakeBindString(self): - choice = self.targetFriendModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetfriend" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetFriendModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) - -####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): - def BuildUI(self, dialog): - teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], - style=wx.ALIGN_CENTER_VERTICAL) - self.teamPetSelectNumber.SetSelection(0) - teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) - - return teamPetSelectSizer - - def MakeBindString(self): - teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' - targetNumber = self.teamPetSelectNumber.GetSelection()+1 - - return f"{teamOrPet}select {targetNumber}" - - def Serialize(self): - return { - 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', - 'targetNum': self.teamPetSelectNumber.GetSelection(), - } - - def Deserialize(self, init): - ToP = init.get('teamOrPet', '') - if ToP == 'pet': - self.teamPetSelectPetRB.SetValue(True) - else: - self.teamPetSelectTeamRB.SetValue(True) - if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) +from UI.PowerBinderCommand import PowerBinderCommand ####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' - -####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) - for _, types in GameData.Inspirations.items(): - for _, info in types.items(): - for insp in info['tiers']: - name = re.sub(' ', '', str(insp)) - icon = GetIcon(f'Inspirations/{name}') - self.useInspByNameModeChoice.Append(insp, icon) - self.useInspByNameModeChoice.SetSelection(0) - useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) - - return useInspByNameSizer - - def MakeBindString(self): - choice = self.useInspByNameModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "inspexecname " + mode.lower() - - def GetAllInsps(self): - Insplist = [] - for _, info in GameData.Inspirations.items(): - for insp in info['tiers']: - Insplist.append(insp) - Insplist.append("---") - Insplist.pop(-1) # snip the terminal "---" - - return Insplist - - def Serialize(self): - return { 'insp' : self.useInspByNameModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) - -####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnRow.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) - self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnCol.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) - - return useInspRowColumnSizer - - def MakeBindString(self): - row = self.useInspRowColumnRow.GetSelection()+1 - col = self.useInspRowColumnCol.GetSelection()+1 - - return f"inspexectray {col} {row}" - - def Serialize(self): - return { - 'col' : self.useInspRowColumnCol.GetSelection(), - 'row' : self.useInspRowColumnRow.GetSelection(), - } - - def Deserialize(self, init): - if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) - if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) - -####### Use Power -class UsePowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - outerSizer = wx.BoxSizer(wx.HORIZONTAL) - - usePowerSizer = wx.GridBagSizer(5,5) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBToggle, (0,1)) - self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOn, (0,2)) - self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOff, (0,3)) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerName = PowerPicker(dialog) - usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) - usePowerSizer.AddGrowableCol(3) - - outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) - - return outerSizer - - def MakeBindString(self): - if self.usePowerRBToggle.GetValue(): - method = "powexecname" - elif self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') - return '' - - return f"{method} {self.usePowerName.GetLabel()}" - - def Serialize(self): - if self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - method = "powexecname" - return { - 'method': method, - 'pname' : self.usePowerName.GetLabel(), - 'picon' : self.usePowerName.IconFilename - } - - def Deserialize(self, init): - method = init.get('method', '') - if method == 'powexectoggleon': - self.usePowerRBOn.SetValue(True) - elif method == 'powexectoggleoff': - self.usePowerRBOff.SetValue(True) - else: - self.usePowerRBToggle.SetValue(True) - if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) - -####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): - def BuildUI(self, dialog): - usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTrayTray = wx.Choice(dialog, -1, - choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', - 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) - self.usePowerFromTrayTray.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) - self.usePowerFromTraySlot.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return usePowerFromTraySizer - - def MakeBindString(self): - choice = self.usePowerFromTrayTray - tray = choice.GetSelection() - - choice = self.usePowerFromTraySlot - slot = choice.GetSelection()+1 - - mode = "slot" - mode2 = '' - if tray > 3: - mode = "tray" - mode2 = f" {tray - 3}" - elif tray == 3: - mode = "alt2slot" - elif tray == 2: - mode = "altslot" - - return f"powexec{mode} {slot}{mode2}" - - def Serialize(self): - return { - 'tray' : self.usePowerFromTrayTray.GetSelection(), - 'slot' : self.usePowerFromTraySlot.GetSelection(), - } - - def Deserialize(self, init): - if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) - if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) - -####### Window Color -class WindowColorCmd(PowerBindCmd): - def BuildUI(self, dialog): - windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) - borderSizer = wx.BoxSizer(wx.VERTICAL) - self.ColorBorder.SetSizer(borderSizer) - self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) - borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) - - windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) - - RGBASizer = wx.FlexGridSizer(3, 4, 5) - - RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) - self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) - self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - windowColorSizer.Add(RGBASizer) - - self.UpdateFromSlider() - - return windowColorSizer - - def MakeBindString(self): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - return f"windowcolor {Rval} {Gval} {Bval} {Aval}" - - def Serialize(self): - return { - 'Rval' : self.RSlider.GetValue(), - 'Gval' : self.GSlider.GetValue(), - 'Bval' : self.BSlider.GetValue(), - 'Aval' : self.ASlider.GetValue(), - } - - def Deserialize(self, init): - self.RSlider.SetValue(init['Rval']) - self.GSlider.SetValue(init['Gval']) - self.BSlider.SetValue(init['Bval']) - self.ASlider.SetValue(init['Aval']) - self.UpdateFromSlider() - - def UpdateFromSlider(self, _ = None): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RReadout.SetValue(Rval) - self.GReadout.SetValue(Gval) - self.BReadout.SetValue(Bval) - self.AReadout.SetValue(Aval) - self.ColorBorder.Refresh() - - def UpdateFromText(self, _ = None): - Rval = self.RReadout.GetValue() - Gval = self.GReadout.GetValue() - Bval = self.BReadout.GetValue() - Aval = self.AReadout.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RSlider.SetValue(Rval) - self.GSlider.SetValue(Gval) - self.BSlider.SetValue(Bval) - self.ASlider.SetValue(Aval) - self.ColorBorder.Refresh() - -####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) - self.CommandChoice.SetSelection(0) - sizer.Add(self.CommandChoice, 0, wx.ALL, 5) - - self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), - value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) - sizer.Add(self.FilePath, 0, wx.ALL, 5) - - return sizer +class UnselectCmd(PowerBinderCommand): + Name = "Unselect" + Menu = "Targeting" def MakeBindString(self): - command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] - return f'{command} "{self.FilePath.GetValue()}"' - - def Serialize(self): - return { - 'command' : self.CommandChoice.GetSelection(), - 'filename' : self.FilePath.GetValue(), - } - - def Deserialize(self, init): - self.CommandChoice.SetSelection(init.get('command', 0)) - self.FilePath.SetValue(init.get('filename', '')) - -####### Window Toggle -class WindowToggleCmd(PowerBindCmd): - def BuildUI(self, dialog): - self.WindowNames = { - 'Actions' : 'actions', - 'Auction House' : 'ah', - 'Badge' : 'badge', - 'Channel Search' : 'chansearch', - 'Chat' : 'chat', - 'Custom Chat 1' : 'chat1', - 'Custom Chat 2' : 'chat2', - 'Custom Chat 3' : 'chat3', - 'Custom Chat 4' : 'chat4', - 'Clues' : 'clue', - 'Combat Numbers' : 'combatnumbers', - 'Contacts' : 'contact', - 'Contact Finder' : 'contactfinder', - 'Costumes' : 'costume', - 'Email' : 'email', - 'Enhancements' : 'enhancements', - 'Friends' : 'friend', - 'Group' : 'group', - 'Help' : 'helpwindow', - 'Incarnate' : 'incarnate', - 'Inspirations' : 'insp', - 'League' : 'league', - 'LFG' : 'lfg', - 'Map' : 'map', - 'Mission' : 'mission', - 'Nav / Compass' : 'nav', - 'Options' : 'options', - 'Pets' : 'pet', - 'Petition' : 'petition', - 'Power Tray' : 'powers', - 'Power List' : 'powerlist', - 'Quit' : 'quit', - 'Recipes' : 'recipe', - 'Salvage' : 'salvage', - 'Search' : 'search', - 'Supergroup' : 'sg', - 'Target' : 'target', - 'Team' : 'team', - 'Tray' : 'tray', - 'Tray1' : 'tray1', - 'Tray2' : 'tray2', - 'Tray3' : 'tray3', - 'Tray4' : 'tray4', - 'Tray5' : 'tray5', - 'Tray6' : 'tray6', - 'Tray7' : 'tray7', - 'Tray8' : 'tray8', - 'Vault' : 'vault', - } - - self.ShortToggleCommands = { - 'Auction House' : 'ah', - 'Chat' : 'chat', - 'Help' : 'helpwindow', - 'Map' : 'map', - 'Nav / Compass' : 'nav', - 'Power Tray' : 'powers', - 'Target' : 'target', - 'Tray' : 'tray', - } - - windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) - windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) - self.windowToggleTray.SetSelection(0) - windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.windowShowRB = wx.RadioButton(dialog, -1, "Show") - self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") - - windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) - - return windowToggleSizer - - def MakeBindString(self): - choice = self.windowToggleTray - index = choice.GetSelection() - windowdesc = choice.GetString(index) - windowname = self.WindowNames[windowdesc] - - if self.windowShowRB.GetValue(): - return 'show ' + windowname - elif self.windowHideRB.GetValue(): - return 'windowhide ' + windowname - else: - if shortcmd := self.ShortToggleCommands.get(windowdesc, None): - return shortcmd - else: - return 'toggle ' + windowname - - - def Serialize(self): - choice = self.windowToggleTray - if self.windowShowRB.GetValue(): - action = "Show" - elif self.windowHideRB.GetValue(): - action = "Hide" - else: - action = "Toggle" - return { - 'window': choice.GetString(choice.GetSelection()), - 'action': action, - } - - def Deserialize(self, init): - choice = self.windowToggleTray - if window := init.get('window', ''): - if isinstance(window, int): - choice.SetSelection(window) - else: - choice.SetSelection(choice.FindString(window)) - - if choice.GetSelection() == wx.NOT_FOUND: - choice.SetSelection(0) - - action = init.get('action', '') - if action == "Show": - self.windowShowRB.SetValue(True) - elif action == "Hide": - self.windowHideRB.SetValue(True) - else: - self.windowToggleRB.SetValue(True) - - -# Must always add to this list when adding a new command class above -menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], - # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, - # but I'm leaving it here to remind myself that we do that. - } - -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} + return 'unselect' diff --git a/UI/PowerBinderCommand/UseInspByNameCmd.py b/UI/PowerBinderCommand/UseInspByNameCmd.py index 4c02ab7..84039b6 100644 --- a/UI/PowerBinderCommand/UseInspByNameCmd.py +++ b/UI/PowerBinderCommand/UseInspByNameCmd.py @@ -1,1282 +1,15 @@ import wx import re -import UI -import UI.EmotePicker -from UI.ControlGroup import ControlGroup -from UI.PowerPicker import PowerPicker -from Help import HelpButton -import wx.adv -from wx.adv import BitmapComboBox, EditableListBox -from pathlib import PureWindowsPath +from wx.adv import BitmapComboBox import GameData -import Profile from Icon import GetIcon - -class PowerBinderDialog(wx.Dialog): - def __init__(self, parent, button, init = {}): - wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) - - self.Page = parent.Page - self.EditDialog = PowerBinderEditDialog(self) - self.Button = button - self.AddStepMenu = self.makeAddStepMenu() - - sizer = wx.BoxSizer(wx.VERTICAL); - self.mainSizer = sizer - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) - AddStepButton = wx.Button(self, -1, 'Add Step') - AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) - AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) - choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) - choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) - sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) - - rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) - - self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) - self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) - self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) - rearrangeCtrl.Add(self.RearrangeList, 1) - - rearrangeButtons = wx.BoxSizer(wx.VERTICAL) - self.DelButton = wx.Button(self, -1, "Delete") - self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) - self.EditButton = wx.Button(self, -1, "Edit") - self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) - self.EditButton.Disable() - upButton = wx.Button(self, -1, "\u25B2") - upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) - downButton = wx.Button(self, -1, "\u25BC") - downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) - rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) - rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) - - sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.BindStringDisplay = wx.TextCtrl(self, -1) - self.BindStringDisplay.Disable() - choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, - wx.ALIGN_CENTER_VERTICAL) - choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) - - sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) - - sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) - - # need to dig around and get the OK button since we show this dialog modelessly now. - okButton = self.FindWindow(self.GetAffirmativeId()) - okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) - - # Wrap everything in a vbox to add some padding - vbox = wx.BoxSizer(wx.VERTICAL); - vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); - - self.SetSizerAndFit(vbox); - self.Layout() - self.Fit() - self.SetFocus() - - # if we are loading from profile, ie, have "init", build the list from it - if init: self.LoadFromData(init) - - def LoadFromData(self, init): - for item in init: - for type, data in item.items(): - commandClass = commandClasses.get(type, None) - if not commandClass: - commandClass = deprecatedCommandClasses.get(type, None) - if not commandClass: - wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") - continue - newCommand = commandClass(self.EditDialog, data) - index = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.SetClientData(index, newCommand) - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) - self.EditDialog.mainSizer.Hide(newCommand.UI) - self.UpdateBindStringDisplay() - - def SaveToData(self): - data = [] - index = 0 - for _ in self.RearrangeList.GetItems(): - # check whether we have an object already attached to this choice - cmdObject = self.RearrangeList.GetClientData(index) - commandClassName = commandRevClasses[type(cmdObject)] - data.append({commandClassName: cmdObject.Serialize()}) - index = index + 1 - return data - - def OnAddStepButton(self, evt): - button = evt.EventObject - if not self.AddStepMenu: - self.AddStepMenu = self.makeAddStepMenu() - button.PopupMenu(self.AddStepMenu) - - - def OnOKButton(self, _): - if self.Button.tgtTxtCtrl: - bindString = self.MakeBindString() - if bindString != self.Button.tgtTxtCtrl.GetValue(): - self.Button.tgtTxtCtrl.SetValue(bindString) - wx.App.Get().Main.Profile.SetModified() - self.Close() - - def OnRearrangeDelete(self, _): - current = self.RearrangeList.GetSelection() - if current == wx.NOT_FOUND: return - - self.RearrangeList.Delete(current) - self.UpdateBindStringDisplay() - - def OnRearrangeUp(self, _): - self.RearrangeList.MoveCurrentUp() - self.UpdateBindStringDisplay() - - def OnRearrangeDown(self, _): - self.RearrangeList.MoveCurrentDown() - self.UpdateBindStringDisplay() - - def OnRearrangeEdit(self, _): - index = self.RearrangeList.GetSelection() - - # check whether we have an object already attached to this choice - cmdObject = None - try: - cmdObject = self.RearrangeList.GetClientData(index) - except Exception: - pass - - if cmdObject: - self.ShowEditDialogFor(cmdObject) - self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) - else: - print("cmdObject was None") - self.UpdateBindStringDisplay() - - # OnAddStepMenu creates a new step and adds it to the rearrangelist - def OnAddStepMenu(self, evt): - menuitem = self.AddStepMenu.FindItemById(evt.GetId()) - chosenName = menuitem.GetItemLabel() - - # make a new command object, attached to the parent dialog - newCommandClass = commandClasses[chosenName] - newCommand = newCommandClass(self.EditDialog) - - # show the edit dialog if this command needs it - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) - if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): - self.EditDialog.mainSizer.Remove(newCommand.UI) - return - - newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.Select(newBindIndex) - self.RearrangeList.SetClientData(newBindIndex, newCommand) - - self.OnListSelect() - self.UpdateBindStringDisplay() - - def OnListSelect(self, _ = None): - selected = self.RearrangeList.GetSelection() - - if selected != wx.NOT_FOUND: - selCommand = self.RearrangeList.GetClientData(selected) - if selCommand.UI: - self.EditButton.Enable() - else: - self.EditButton.Disable() - - def UpdateBindStringDisplay(self): - self.BindStringDisplay.SetValue(self.MakeBindString()) - self.BindStringDisplay.SetToolTip(self.MakeBindString()) - - def MakeBindString(self): - cmdBindStrings = [] - for index in range(self.RearrangeList.GetCount()): - c = self.RearrangeList.GetClientData(index) - if c: cmdBindStrings.append(c.MakeBindString()) - - bindstring = ('$$'.join(cmdBindStrings)) - return bindstring - - def ShowEditDialogFor(self, command): - if not command.UI: return - - self.EditDialog.mainSizer.Show(command.UI) - - self.EditDialog.Layout() - self.EditDialog.Fit() - - self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') - returnval = self.EditDialog.ShowModal() - - self.EditDialog.mainSizer.Hide(command.UI) - - return returnval - - def makeAddStepMenu(self): - - stepMenu = wx.Menu() - - for subname in menuStructure: - submenu = wx.Menu() - stepMenu.AppendSubMenu(submenu, subname) - for classname in menuStructure[subname]: - submenu.Append(wx.ID_ANY, classname) - - stepMenu.Append(wx.ID_ANY, 'Custom Bind') - - return stepMenu - -class PowerBinderButton(wx.BitmapButton): - - def __init__(self, parent, tgtTxtCtrl, init = {}): - wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) - self.Init = init - self.Dialog = None - self.DialogParent = parent - - self.tgtTxtCtrl = tgtTxtCtrl - self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) - self.SetToolTip("Launch PowerBinder") - - def PowerBinderEventHandler(self, _): - self.PowerBinderDialog().Show() - - def LoadFromData(self, data): - self.PowerBinderDialog().LoadFromData(data) - - def SaveToData(self): - return self.PowerBinderDialog().SaveToData() - - def PowerBinderDialog(self): - if not self.Dialog: - self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) - return self.Dialog - - -class PowerBinderEditDialog(wx.Dialog): - def __init__(self, parent): - wx.Dialog.__init__(self, parent, -1, "Edit Step", - style = wx.DEFAULT_DIALOG_STYLE) - - outerSizer = wx.BoxSizer(wx.VERTICAL) - - self.mainSizer = wx.BoxSizer(wx.VERTICAL) - self.mainSizer.SetMinSize([500, 150]) - - self.Page = parent.Page - - self.mainSizer.Add( - self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), - 0, wx.EXPAND|wx.ALL, 10) - - outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) - - self.SetSizerAndFit(outerSizer) - self.Layout() - self.Fit() - -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" - - -####### Away From Keyboard -class AFKCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.Groups = {} - self.AttributeTable = { - 'Base' : { - 'Current Hit Points' : 'NT H', - 'Max Hit Points' : 'X H', - 'Current Endurance' : 'T E', - 'Max Endurance' : 'X EN', - 'Regeneration Rate' : 'N RAT', - 'Recovery Rate' : 'Y RA', - 'Endurance Consumption' : 'SU', - 'ToHit Bonus' : 'T B', - 'Accuracy Bonus' : 'CC', - 'Last Hit Chance' : 'T C', - 'Damage Bonus' : 'DA', - 'Healing Bonus' : 'NG B', - 'Recharge Time Bonus' : 'ME B', - 'Endurance Discount' : 'CE DIS', - 'Stealth Radius (PvP)' : 'PVP', - 'Stealth Radius (PvE)' : 'PVE', - 'Perception Radius' : 'RC', - 'Range Bonus' : 'GE B', - 'Threat Level' : 'AT L', - 'Experience to Next Level' : 'XT', - 'Experience Debt' : 'XP', - 'Influence / Infamy' : 'INF', - 'Inherent' : 'NH', - }, - 'Movement Speed' : { - 'Flying Speed' : 'FL', - 'Jumping Speed' : 'PI', - 'Max Jump Height' : 'X J', - 'Run Speed' : 'RU', - }, - 'Damage Resistance' : { - 'Smashing Resistance' : 'G R', - 'Lethal Resistance' : 'L R', - 'Fire Resistance' : 'RE R', - 'Cold Resistance' : 'COLD R', - 'Energy Resistance' : 'DamageType[4]', - 'Negative Energy Resistance' : 'GY R', - 'Psyonic Resistance' : 'NIC R', - 'Toxic Resistance' : 'XIC R', - }, - 'Defense' : { - 'Base Defense' : 'BAS', - 'Ranged Defense' : 'ED', - 'Melee Defense' : 'MEL', - 'AoE Defense' : '2', - 'Smashing Defense' : '3', - 'Lethal Defense' : '4', - 'Fire Defense' : '5', - 'Cold Defense' : '6', - 'Energy Defense' : '7', - 'Negative Energy Defense' : '8', - 'Psionic Defense' : '9', - 'Toxic Defense' : '1', - }, - 'Debuff Resistance' : { - 'Regeneration Resistance' : 'ON R', - 'Recovery Resistance' : 'RY R', - 'To Hit Resistance' : 'IT R', - 'Defense Resistance' : 'NSE RES', - }, - 'Status Effect Protection' : { - 'Hold Protection' : 'D P', - 'Immobilize Protection' : 'LIZE P', - 'Stun Protection' : 'N P', - 'Sleep Protection' : 'P P', - 'Knockback Protection' : 'K P', - 'Confuse Protection' : 'SE P', - 'Terrorize Protection' : 'ZE P', - 'Repel Protection' : 'EL P', - 'Teleport Protection' : 'T P', - }, - 'Status Effect Resistance' : { - 'Hold Resistance' : 'D R', - 'Immobilize Resistance' : 'LIZE R', - 'Stun Resistance' : 'N R', - 'Sleep Resistance' : 'P R', - 'Knockback Resistance' : 'K R', - 'Confuse Resistance' : 'SE R', - 'Terrorize Resistance' : 'ZE R', - 'Placate Resistance' : 'TE R', - 'Taunt Resistance' : 'NT R', - }, - 'Miscellaneous' : { - 'Level Shift' : 'L S', - }, - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.AttributeMenu = wx.Menu() - for group, controls in self.AttributeTable.items(): - submenu = wx.Menu() - self.AttributeMenu.AppendSubMenu(submenu, group) - for cb in controls: - submenu.Append(wx.ID_ANY, cb) - - self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) - - self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) - groupSizer.Add(self.editbox) - - newButton = self.editbox.GetNewButton() - newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) - - return groupSizer - - def MakeBindString(self): - map = {} - bindstrings = [] - for _, controls in self.AttributeTable.items(): - for cb, data in controls.items(): - map[cb] = data - - for string in self.editbox.GetStrings(): - if string: - bindstrings.append(f'monitorattribute {map[string]}') - - return '$$'.join(bindstrings) - - def Serialize(self): - return { - 'attributes' : self.editbox.GetStrings() - } - - def Deserialize(self, init): - self.editbox.SetStrings(init.get('attributes', [])) - - def OnNewButton(self, evt): - evt.GetEventObject().PopupMenu(self.AttributeMenu) - - def OnMenuItem(self, evt): - menuitem = evt.EventObject.FindItemById(evt.GetId()) - existingstrings = self.editbox.GetStrings() - existingstrings.append(menuitem.GetItemLabel()) - self.editbox.SetStrings(existingstrings) - -####### Auto Power -class AutoPowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) - autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.autoPowerName = PowerPicker(dialog) - autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) - - return autoPowerSizer - - def MakeBindString(self): - return f"powexecauto {self.autoPowerName.GetLabel()}" - - def Serialize(self): - return { - 'pname' : self.autoPowerName.GetLabel(), - 'picon' : self.autoPowerName.IconFilename - } - - def Deserialize(self, init): - if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.buffDisplayMap = { - 'Status Window' : { - 'Hide Auto' : 1, - 'Hide Toggles' : 2, - 'No Blinking' : 4, - 'No Stacking' : 8, - 'Numeric Stacking' : 16, - 'Hide Buff Numbers' : 32, - 'Stop Sending Buffs' : 64, - }, - 'Group Window' : { - 'Hide Auto' : 256, - 'Hide Toggles' : 512, - 'No Blinking' : 1024, - 'No Stacking' : 2048, - 'Numeric Stacking' : 4096, - 'Hide Buff Numbers' : 8192, - 'Stop Sending Buffs' : 16384, - }, - 'Pet Window' : { - 'Hide Auto' : 65536, - 'Hide Toggles' : 131072, - 'No Blinking' : 262144, - 'No Stacking' : 524288, - 'Numeric Stacking' : 1048576, - 'Hide Buff Numbers' : 2097152, - 'Stop Sending Buffs' : 4194304, - }, - } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - for group, controls in self.buffDisplayMap.items(): - self.Groups[group] = ControlGroup(dialog, self.Page, label = group) - groupid = self.Groups[group].GetStaticBox().GetId() - for cb, data in controls.items(): - self.Groups[group].AddControl( - ctlType = 'checkbox', - ctlName = f"{groupid}_{group}_{cb}", - label = cb, - data = data, - ) - - groupSizer.Add(self.Groups[group]) - - return groupSizer - - def CalculateValue(self): - page = wx.App.Get().Main.Profile.CustomBinds - - total = 0 - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] - if checkbox.IsChecked(): - total = total + checkbox.Data - return total - - def MakeBindString(self): - return f"optionset buffsettings {self.CalculateValue()}" - - def Serialize(self): - return { 'value' : self.CalculateValue() } - - def Deserialize(self, init): - value = init.get('value', 0) - - value = value or 0 # in case we had for some reason 'None' stashed in the init values - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] - checkbox.SetValue( checkbox.Data & value ) - -####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - chatCommandSizer = wx.GridBagSizer(5, 5) - self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") - chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) - # row 1 - self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) - self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) - self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) - # row 2 - self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) - self.chatCommandDuration.SetRange(1, 20) - self.chatCommandDuration.SetValue(7) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandDuration, (2,1)) - self.chatCommandChatSize = wx.Choice(dialog, -1, - choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) - self.chatCommandChatSize.SetSelection(5) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) - self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) - self.chatCommandChannel.SetSelection(0) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChannel, (2,5)) - # row 3 - self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") - chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) - self.chatCommandMessage = wx.TextCtrl(dialog, -1) - self.chatCommandMessage.SetHint('Chat Command Text') - chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) - - return chatCommandSizer - - def MakeBindString(self): - duration = self.chatCommandDuration.GetValue() - - choice = self.chatCommandChatSize - index = choice.GetSelection() - size = choice.GetString(index) - - duration = f"" if duration != 7 else "" - size = f"" if size != "1" else "" - - bdcolor = fgcolor = bgcolor = '' - if self.chatCommandUseColorsCB.IsChecked(): - bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - - bdcolor = f"" - fgcolor = f"" - bgcolor = f"" - - beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' - text = self.chatCommandMessage.GetValue() - - choice = self.chatCommandChannel - index = choice.GetSelection() - channel = choice.GetString(index) - - return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" - - def Serialize(self): - return { - 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), - 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), - 'channel' : self.chatCommandChannel .GetSelection(), - 'size' : self.chatCommandChatSize.GetSelection(), - 'duration' : self.chatCommandDuration.GetValue(), - 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'text' : self.chatCommandMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) - if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) - if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) - if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) - if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) - if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) - if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) - if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) - if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - - -####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): - def BuildUI(self, dialog): - chatCommandGlobalSizer = wx.GridBagSizer(5,5) - - self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") - chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) - - self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalChannel.SetHint("Channel") - chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) - - self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') - chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) - - chatCommandGlobalSizer.AddGrowableCol(1) - - return chatCommandGlobalSizer - - def MakeBindString(self): - useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() - channel = self.chatCommandGlobalChannel.GetValue() - message = self.chatCommandGlobalMessage.GetValue() - - preface = "beginchat /" if useBeginchat else "" - - return f'{preface}send "{channel}" {message}' - - def Serialize(self): - return { - 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), - 'channel' : self.chatCommandGlobalChannel.GetValue(), - 'message' : self.chatCommandGlobalMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) - if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) - if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) - -#######Costume Change -class CostumeChangeCmd(PowerBindCmd): - def BuildUI(self, dialog): - costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeCostume = wx.Choice(dialog, -1, - choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) - self.costumeChangeCostume.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeEmote = wx.Choice(dialog, -1, - choices = GameData.Emotes['costumechange']) - self.costumeChangeEmote.Insert("- None -", 0) - self.costumeChangeEmote.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return costumeChangeSizer - - def MakeBindString(self): - costumeNumber = self.costumeChangeCostume.GetSelection() - costumeEmote = self.costumeChangeEmote.GetSelection() - - if costumeEmote: # None, or 0 == "- None -" - ccCmd = 'cce' - emoteName = self.costumeChangeEmote.GetString(costumeEmote) - emoteName = " CC" + emoteName.replace(" ","") - else: - ccCmd = 'cc' - emoteName = '' - - return f"{ccCmd} {costumeNumber}{emoteName}" - - def Serialize(self): - return{ - 'costumeNumber': self.costumeChangeCostume.GetSelection(), - 'costumeEmote' : self.costumeChangeEmote.GetSelection(), - } - - def Deserialize(self, init): - if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) - if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) - -####### Movement Command -class MovementCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - self.plusbutton.SetValue(True) - - self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.commandchoice = wx.Choice(dialog, choices = [ - "forward", "left", "right", "backward", "up", "down", - "turnleft", "turnright", "first", "autorun", "clicktomove", - ],) - sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) - self.commandchoice.SetSelection(0) - - self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - pre = post = '' - if self.plusbutton.GetValue() : pre = "+" - elif self.plusplusbutton.GetValue() : pre = "++" - elif self.minusbutton.GetValue() : pre = "-" - elif self.zerobutton.GetValue() : post = " 0" - elif self.onebutton.GetValue() : post = " 1" - - command = self.commandchoice.GetString(self.commandchoice.GetSelection()) - - return f"{pre}{command}{post}" - - def Serialize(self): - mod = '' - if self.plusbutton.GetValue() : mod = "plus" - elif self.plusplusbutton.GetValue() : mod = "plusplus" - elif self.minusbutton.GetValue() : mod = "minus" - elif self.zerobutton.GetValue() : mod = "zero" - elif self.onebutton.GetValue() : mod = "one" - - return { - 'mod' : mod, - 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), - } - - def Deserialize(self, init): - mod = init.get('mod', 'plus') - - if mod == 'plus' : self.plusbutton.SetValue(True) - elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) - elif mod == 'minus' : self.minusbutton.SetValue(True) - elif mod == 'zero' : self.zerobutton.SetValue(True) - elif mod == 'one' : self.onebutton.SetValue(True) - - self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) - -####### Graphics Command -class GraphicsCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.FlexGridSizer(2) - - self.visscalecb = wx.CheckBox(dialog, label = "visscale") - sizer.Add(self.visscalecb) - self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) - sizer.Add(self.visscalesc) - - self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") - sizer.Add(self.dofweightcb) - self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) - sizer.Add(self.dofweightsc) - - self.fsaacb = wx.CheckBox(dialog, label = "fsaa") - sizer.Add(self.fsaacb) - self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) - self.fsaach.SetSelection(0) - sizer.Add(self.fsaach) - - self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") - sizer.Add(self.bloomscalecb) - self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) - self.bloomscalech.SetSelection(0) - sizer.Add(self.bloomscalech) - - self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") - sizer.Add(self.bloomweightcb) - self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) - sizer.Add(self.bloomweightsc) - - self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") - sizer.Add(self.lodbiascb) - self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) - sizer.Add(self.lodbiassc) - - self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") - sizer.Add(self.renderscalecb) - self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) - sizer.Add(self.renderscalesc) - - return sizer - - def MakeBindString(self): - # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. - bindstrings = [] - if self.visscalecb.IsChecked(): - bindstrings.append("visscale " + str(self.visscalesc.GetValue())) - if self.dofweightcb.IsChecked(): - bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) - if self.fsaacb.IsChecked(): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bindstrings.append("fsaa " + fsaavalue) - if self.bloomscalecb.IsChecked(): - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - bindstrings.append("bloomscale " + bloomscalevalue) - if self.bloomweightcb.IsChecked(): - bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) - if self.lodbiascb.IsChecked(): - bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) - if self.renderscalecb.IsChecked(): - bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) - - return '$$'.join(bindstrings) - - def Serialize(self): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - return { - 'visscalecb' : self.visscalecb.IsChecked(), - 'visscalesc' : self.visscalesc.GetValue(), - 'dofweightcb' : self.dofweightcb.IsChecked(), - 'dofweightsc' : self.dofweightsc.GetValue(), - 'fsaacb' : self.fsaacb.IsChecked(), - 'fsaach' : fsaavalue, - 'bloomscalecb' : self.bloomscalecb.IsChecked(), - 'bloomscalech' : bloomscalevalue, - 'bloomweightcb' : self.bloomweightcb.IsChecked(), - 'bloomweightsc' : self.bloomweightsc.GetValue(), - 'lodbiascb' : self.lodbiascb.IsChecked(), - 'lodbiassc' : self.lodbiassc.GetValue(), - 'renderscalecb' : self.renderscalecb.IsChecked(), - 'renderscalesc' : self.renderscalesc.GetValue(), - } - - def Deserialize(self, init): - self.visscalecb.SetValue(init.get('visscalecb', False)) - self.visscalesc.SetValue(init.get('visscalesc', 1.0)) - self.dofweightcb.SetValue(init.get('dofweightcb', False)) - self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) - self.fsaacb.SetValue(init.get('fsaacb', False)) - self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) - self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) - self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) - self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) - self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) - self.lodbiascb.SetValue(init.get('lodbiascb', False)) - self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) - self.renderscalecb.SetValue(init.get('renderscalecb', False)) - self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) - -####### Custom Bind -class CustomBindCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.customBindName = wx.TextCtrl(dialog, -1) - self.customBindName.SetHint('Custom Bind Text') - sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - return self.customBindName.GetValue() - - def Serialize(self): - return { 'customBindName': self.customBindName.GetValue() } - - def Deserialize(self,init): - if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) - -####### Emote -class EmoteCmd(PowerBindCmd): - def BuildUI(self, dialog): - emoteSizer = wx.BoxSizer(wx.HORIZONTAL) - self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") - emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - self.emoteName = wx.Button(dialog, -1, "...") - self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) - emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) - - return emoteSizer - - def MakeBindString(self): - displayedEmoteName = self.emoteName.GetLabel() - actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] - - return actualEmotePayload - - def Serialize(self): - return {'emoteName': self.emoteName.GetLabel()} - - def Deserialize(self, init): - if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) - -####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): - def BuildUI(self, dialog): - mainSizer = wx.BoxSizer(wx.VERTICAL) - - lbSizer = wx.BoxSizer(wx.HORIZONTAL) - lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") - lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - profiles = Profile.GetAllProfileBindsDirs() - - self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) - lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) - - mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") - self.lbResetCB.SetValue(True) - - mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - return mainSizer - - def MakeBindString(self): - - # If the specified binds directory disappeared between runs, we'd crash, so handle that. - if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' - - config = wx.ConfigBase.Get() - if config.Exists('GameBindPath'): - bindpath = config.Read('GameBindPath') - else: - bindpath = config.Read('BindPath') - - reset = "" - if self.lbResetCB.GetValue(): - reset = "keybind_reset$$" - - resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' - return reset + 'bindloadfile ' + str(resetfilepath) - - def Serialize(self): - return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), - 'ResetKeybinds' : self.lbResetCB.GetValue(), - } - - def Deserialize(self, init): - if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) - self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) - -####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' - -####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' - -####### SG Mode -class SGModeCmd(PowerBindCmd): - def BuildUI(self, dialog): - sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) - sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") - self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") - - sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) - - return sgmodeSizer - - def MakeBindString(self): - if self.sgmodeOnRB.GetValue(): - return 'sgmodeset 1' - elif self.sgmodeOffRB.GetValue(): - return 'sgmodeset 0' - else: - return 'sgmode' - - def Serialize(self): - if self.sgmodeOnRB.GetValue(): - val = "On" - elif self.sgmodeOffRB.GetValue(): - val = "Off" - else: - val = "Toggle" - - return {"value" : val} - - def Deserialize(self, init): - val = init.get('value', '') - if val == "On": - self.sgmodeOnRB.SetValue(True) - elif val == "Off": - self.sgmodeOffRB.SetValue(True) - else: - self.sgmodeToggleRB.SetValue(True) - -####### Target Custom -class TargetCustomCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetCustomSizer = wx.GridBagSizer(5,5) - targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), - flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) - self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetCustomModeChoice.SetSelection(0) - targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) - self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) - self.targetCustomOptionalName.SetHint("Optional name to match") - targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) - self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") - targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) - self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") - targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) - self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") - targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) - self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") - targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) - self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") - targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) - self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") - targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) - self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") - targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) - self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") - targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) - - targetCustomSizer.AddGrowableCol(2) - - return targetCustomSizer - - def MakeBindString(self): - choice = self.targetCustomModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - targetCommand = "targetcustom" + mode.lower() - - enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" - friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" - defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" - alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" - mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" - notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" - base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" - notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" - - name = self.targetCustomOptionalName.GetValue() - - return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" - - def Serialize(self): - return { - 'mode' : self.targetCustomModeChoice.GetSelection(), - 'enemy' : self.targetCustomCBEnemies. IsChecked(), - 'friend' : self.targetCustomCBFriends. IsChecked(), - 'defeated' : self.targetCustomCBDefeated. IsChecked(), - 'alive' : self.targetCustomCBAlive. IsChecked(), - 'mypet' : self.targetCustomCBMyPets. IsChecked(), - 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), - 'base' : self.targetCustomCBBaseItems. IsChecked(), - 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), - 'name' : self.targetCustomOptionalName.GetValue(), - } - - def Deserialize(self, init): - if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) - if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) - if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) - if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) - if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) - if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) - if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) - if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) - if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) - if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - - -####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) - targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetEnemyModeChoice.SetSelection(0) - targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetEnemySizer - - def MakeBindString(self): - choice = self.targetEnemyModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetenemy" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetEnemyModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) - -####### Target Friend -class TargetFriendCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) - targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetFriendModeChoice.SetSelection(0) - targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetFriendSizer - - def MakeBindString(self): - choice = self.targetFriendModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetfriend" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetFriendModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) - -####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): - def BuildUI(self, dialog): - teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], - style=wx.ALIGN_CENTER_VERTICAL) - self.teamPetSelectNumber.SetSelection(0) - teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) - - return teamPetSelectSizer - - def MakeBindString(self): - teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' - targetNumber = self.teamPetSelectNumber.GetSelection()+1 - - return f"{teamOrPet}select {targetNumber}" - - def Serialize(self): - return { - 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', - 'targetNum': self.teamPetSelectNumber.GetSelection(), - } - - def Deserialize(self, init): - ToP = init.get('teamOrPet', '') - if ToP == 'pet': - self.teamPetSelectPetRB.SetValue(True) - else: - self.teamPetSelectTeamRB.SetValue(True) - if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) - -####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' +from UI.PowerBinderCommand import PowerBinderCommand ####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): +class UseInspByNameCmd(PowerBinderCommand): + Name = "Use Inspiration By Name" + Menu = "Inspirations" + def BuildUI(self, dialog): useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, @@ -1309,492 +42,12 @@ def GetAllInsps(self): return Insplist + # TODO - we're serializing GetSelection() which could, in principle, change + # if the game changes up the inspirations. We should dtrt with storing the + # string instead, and still honoring isinstance(int) to support legacy profiles + def Serialize(self): return { 'insp' : self.useInspByNameModeChoice.GetSelection() } def Deserialize(self, init): if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) - -####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnRow.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) - self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnCol.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) - - return useInspRowColumnSizer - - def MakeBindString(self): - row = self.useInspRowColumnRow.GetSelection()+1 - col = self.useInspRowColumnCol.GetSelection()+1 - - return f"inspexectray {col} {row}" - - def Serialize(self): - return { - 'col' : self.useInspRowColumnCol.GetSelection(), - 'row' : self.useInspRowColumnRow.GetSelection(), - } - - def Deserialize(self, init): - if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) - if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) - -####### Use Power -class UsePowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - outerSizer = wx.BoxSizer(wx.HORIZONTAL) - - usePowerSizer = wx.GridBagSizer(5,5) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBToggle, (0,1)) - self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOn, (0,2)) - self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOff, (0,3)) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerName = PowerPicker(dialog) - usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) - usePowerSizer.AddGrowableCol(3) - - outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) - - return outerSizer - - def MakeBindString(self): - if self.usePowerRBToggle.GetValue(): - method = "powexecname" - elif self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') - return '' - - return f"{method} {self.usePowerName.GetLabel()}" - - def Serialize(self): - if self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - method = "powexecname" - return { - 'method': method, - 'pname' : self.usePowerName.GetLabel(), - 'picon' : self.usePowerName.IconFilename - } - - def Deserialize(self, init): - method = init.get('method', '') - if method == 'powexectoggleon': - self.usePowerRBOn.SetValue(True) - elif method == 'powexectoggleoff': - self.usePowerRBOff.SetValue(True) - else: - self.usePowerRBToggle.SetValue(True) - if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) - -####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): - def BuildUI(self, dialog): - usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTrayTray = wx.Choice(dialog, -1, - choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', - 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) - self.usePowerFromTrayTray.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) - self.usePowerFromTraySlot.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return usePowerFromTraySizer - - def MakeBindString(self): - choice = self.usePowerFromTrayTray - tray = choice.GetSelection() - - choice = self.usePowerFromTraySlot - slot = choice.GetSelection()+1 - - mode = "slot" - mode2 = '' - if tray > 3: - mode = "tray" - mode2 = f" {tray - 3}" - elif tray == 3: - mode = "alt2slot" - elif tray == 2: - mode = "altslot" - - return f"powexec{mode} {slot}{mode2}" - - def Serialize(self): - return { - 'tray' : self.usePowerFromTrayTray.GetSelection(), - 'slot' : self.usePowerFromTraySlot.GetSelection(), - } - - def Deserialize(self, init): - if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) - if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) - -####### Window Color -class WindowColorCmd(PowerBindCmd): - def BuildUI(self, dialog): - windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) - borderSizer = wx.BoxSizer(wx.VERTICAL) - self.ColorBorder.SetSizer(borderSizer) - self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) - borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) - - windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) - - RGBASizer = wx.FlexGridSizer(3, 4, 5) - - RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) - self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) - self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - windowColorSizer.Add(RGBASizer) - - self.UpdateFromSlider() - - return windowColorSizer - - def MakeBindString(self): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - return f"windowcolor {Rval} {Gval} {Bval} {Aval}" - - def Serialize(self): - return { - 'Rval' : self.RSlider.GetValue(), - 'Gval' : self.GSlider.GetValue(), - 'Bval' : self.BSlider.GetValue(), - 'Aval' : self.ASlider.GetValue(), - } - - def Deserialize(self, init): - self.RSlider.SetValue(init['Rval']) - self.GSlider.SetValue(init['Gval']) - self.BSlider.SetValue(init['Bval']) - self.ASlider.SetValue(init['Aval']) - self.UpdateFromSlider() - - def UpdateFromSlider(self, _ = None): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RReadout.SetValue(Rval) - self.GReadout.SetValue(Gval) - self.BReadout.SetValue(Bval) - self.AReadout.SetValue(Aval) - self.ColorBorder.Refresh() - - def UpdateFromText(self, _ = None): - Rval = self.RReadout.GetValue() - Gval = self.GReadout.GetValue() - Bval = self.BReadout.GetValue() - Aval = self.AReadout.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RSlider.SetValue(Rval) - self.GSlider.SetValue(Gval) - self.BSlider.SetValue(Bval) - self.ASlider.SetValue(Aval) - self.ColorBorder.Refresh() - -####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) - self.CommandChoice.SetSelection(0) - sizer.Add(self.CommandChoice, 0, wx.ALL, 5) - - self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), - value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) - sizer.Add(self.FilePath, 0, wx.ALL, 5) - - return sizer - - def MakeBindString(self): - command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] - return f'{command} "{self.FilePath.GetValue()}"' - - def Serialize(self): - return { - 'command' : self.CommandChoice.GetSelection(), - 'filename' : self.FilePath.GetValue(), - } - - def Deserialize(self, init): - self.CommandChoice.SetSelection(init.get('command', 0)) - self.FilePath.SetValue(init.get('filename', '')) - -####### Window Toggle -class WindowToggleCmd(PowerBindCmd): - def BuildUI(self, dialog): - self.WindowNames = { - 'Actions' : 'actions', - 'Auction House' : 'ah', - 'Badge' : 'badge', - 'Channel Search' : 'chansearch', - 'Chat' : 'chat', - 'Custom Chat 1' : 'chat1', - 'Custom Chat 2' : 'chat2', - 'Custom Chat 3' : 'chat3', - 'Custom Chat 4' : 'chat4', - 'Clues' : 'clue', - 'Combat Numbers' : 'combatnumbers', - 'Contacts' : 'contact', - 'Contact Finder' : 'contactfinder', - 'Costumes' : 'costume', - 'Email' : 'email', - 'Enhancements' : 'enhancements', - 'Friends' : 'friend', - 'Group' : 'group', - 'Help' : 'helpwindow', - 'Incarnate' : 'incarnate', - 'Inspirations' : 'insp', - 'League' : 'league', - 'LFG' : 'lfg', - 'Map' : 'map', - 'Mission' : 'mission', - 'Nav / Compass' : 'nav', - 'Options' : 'options', - 'Pets' : 'pet', - 'Petition' : 'petition', - 'Power Tray' : 'powers', - 'Power List' : 'powerlist', - 'Quit' : 'quit', - 'Recipes' : 'recipe', - 'Salvage' : 'salvage', - 'Search' : 'search', - 'Supergroup' : 'sg', - 'Target' : 'target', - 'Team' : 'team', - 'Tray' : 'tray', - 'Tray1' : 'tray1', - 'Tray2' : 'tray2', - 'Tray3' : 'tray3', - 'Tray4' : 'tray4', - 'Tray5' : 'tray5', - 'Tray6' : 'tray6', - 'Tray7' : 'tray7', - 'Tray8' : 'tray8', - 'Vault' : 'vault', - } - - self.ShortToggleCommands = { - 'Auction House' : 'ah', - 'Chat' : 'chat', - 'Help' : 'helpwindow', - 'Map' : 'map', - 'Nav / Compass' : 'nav', - 'Power Tray' : 'powers', - 'Target' : 'target', - 'Tray' : 'tray', - } - - windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) - windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) - self.windowToggleTray.SetSelection(0) - windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.windowShowRB = wx.RadioButton(dialog, -1, "Show") - self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") - - windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) - - return windowToggleSizer - - def MakeBindString(self): - choice = self.windowToggleTray - index = choice.GetSelection() - windowdesc = choice.GetString(index) - windowname = self.WindowNames[windowdesc] - - if self.windowShowRB.GetValue(): - return 'show ' + windowname - elif self.windowHideRB.GetValue(): - return 'windowhide ' + windowname - else: - if shortcmd := self.ShortToggleCommands.get(windowdesc, None): - return shortcmd - else: - return 'toggle ' + windowname - - - def Serialize(self): - choice = self.windowToggleTray - if self.windowShowRB.GetValue(): - action = "Show" - elif self.windowHideRB.GetValue(): - action = "Hide" - else: - action = "Toggle" - return { - 'window': choice.GetString(choice.GetSelection()), - 'action': action, - } - - def Deserialize(self, init): - choice = self.windowToggleTray - if window := init.get('window', ''): - if isinstance(window, int): - choice.SetSelection(window) - else: - choice.SetSelection(choice.FindString(window)) - - if choice.GetSelection() == wx.NOT_FOUND: - choice.SetSelection(0) - - action = init.get('action', '') - if action == "Show": - self.windowShowRB.SetValue(True) - elif action == "Hide": - self.windowHideRB.SetValue(True) - else: - self.windowToggleRB.SetValue(True) - - -# Must always add to this list when adding a new command class above -menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], - # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, - # but I'm leaving it here to remind myself that we do that. - } - -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/UseInspRowColCmd.py b/UI/PowerBinderCommand/UseInspRowColCmd.py index 4c02ab7..24ed094 100644 --- a/UI/PowerBinderCommand/UseInspRowColCmd.py +++ b/UI/PowerBinderCommand/UseInspRowColCmd.py @@ -1,1322 +1,11 @@ import wx -import re -import UI -import UI.EmotePicker -from UI.ControlGroup import ControlGroup -from UI.PowerPicker import PowerPicker -from Help import HelpButton -import wx.adv -from wx.adv import BitmapComboBox, EditableListBox -from pathlib import PureWindowsPath -import GameData -import Profile -from Icon import GetIcon - -class PowerBinderDialog(wx.Dialog): - def __init__(self, parent, button, init = {}): - wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) - - self.Page = parent.Page - self.EditDialog = PowerBinderEditDialog(self) - self.Button = button - self.AddStepMenu = self.makeAddStepMenu() - - sizer = wx.BoxSizer(wx.VERTICAL); - self.mainSizer = sizer - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) - AddStepButton = wx.Button(self, -1, 'Add Step') - AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) - AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) - choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) - choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) - sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) - - rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) - - self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) - self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) - self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) - rearrangeCtrl.Add(self.RearrangeList, 1) - - rearrangeButtons = wx.BoxSizer(wx.VERTICAL) - self.DelButton = wx.Button(self, -1, "Delete") - self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) - self.EditButton = wx.Button(self, -1, "Edit") - self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) - self.EditButton.Disable() - upButton = wx.Button(self, -1, "\u25B2") - upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) - downButton = wx.Button(self, -1, "\u25BC") - downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) - rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) - rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) - - sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.BindStringDisplay = wx.TextCtrl(self, -1) - self.BindStringDisplay.Disable() - choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, - wx.ALIGN_CENTER_VERTICAL) - choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) - - sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) - - sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) - - # need to dig around and get the OK button since we show this dialog modelessly now. - okButton = self.FindWindow(self.GetAffirmativeId()) - okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) - - # Wrap everything in a vbox to add some padding - vbox = wx.BoxSizer(wx.VERTICAL); - vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); - - self.SetSizerAndFit(vbox); - self.Layout() - self.Fit() - self.SetFocus() - - # if we are loading from profile, ie, have "init", build the list from it - if init: self.LoadFromData(init) - - def LoadFromData(self, init): - for item in init: - for type, data in item.items(): - commandClass = commandClasses.get(type, None) - if not commandClass: - commandClass = deprecatedCommandClasses.get(type, None) - if not commandClass: - wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") - continue - newCommand = commandClass(self.EditDialog, data) - index = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.SetClientData(index, newCommand) - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) - self.EditDialog.mainSizer.Hide(newCommand.UI) - self.UpdateBindStringDisplay() - - def SaveToData(self): - data = [] - index = 0 - for _ in self.RearrangeList.GetItems(): - # check whether we have an object already attached to this choice - cmdObject = self.RearrangeList.GetClientData(index) - commandClassName = commandRevClasses[type(cmdObject)] - data.append({commandClassName: cmdObject.Serialize()}) - index = index + 1 - return data - - def OnAddStepButton(self, evt): - button = evt.EventObject - if not self.AddStepMenu: - self.AddStepMenu = self.makeAddStepMenu() - button.PopupMenu(self.AddStepMenu) - - - def OnOKButton(self, _): - if self.Button.tgtTxtCtrl: - bindString = self.MakeBindString() - if bindString != self.Button.tgtTxtCtrl.GetValue(): - self.Button.tgtTxtCtrl.SetValue(bindString) - wx.App.Get().Main.Profile.SetModified() - self.Close() - - def OnRearrangeDelete(self, _): - current = self.RearrangeList.GetSelection() - if current == wx.NOT_FOUND: return - - self.RearrangeList.Delete(current) - self.UpdateBindStringDisplay() - - def OnRearrangeUp(self, _): - self.RearrangeList.MoveCurrentUp() - self.UpdateBindStringDisplay() - - def OnRearrangeDown(self, _): - self.RearrangeList.MoveCurrentDown() - self.UpdateBindStringDisplay() - - def OnRearrangeEdit(self, _): - index = self.RearrangeList.GetSelection() - - # check whether we have an object already attached to this choice - cmdObject = None - try: - cmdObject = self.RearrangeList.GetClientData(index) - except Exception: - pass - - if cmdObject: - self.ShowEditDialogFor(cmdObject) - self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) - else: - print("cmdObject was None") - self.UpdateBindStringDisplay() - - # OnAddStepMenu creates a new step and adds it to the rearrangelist - def OnAddStepMenu(self, evt): - menuitem = self.AddStepMenu.FindItemById(evt.GetId()) - chosenName = menuitem.GetItemLabel() - - # make a new command object, attached to the parent dialog - newCommandClass = commandClasses[chosenName] - newCommand = newCommandClass(self.EditDialog) - - # show the edit dialog if this command needs it - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) - if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): - self.EditDialog.mainSizer.Remove(newCommand.UI) - return - - newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.Select(newBindIndex) - self.RearrangeList.SetClientData(newBindIndex, newCommand) - - self.OnListSelect() - self.UpdateBindStringDisplay() - - def OnListSelect(self, _ = None): - selected = self.RearrangeList.GetSelection() - - if selected != wx.NOT_FOUND: - selCommand = self.RearrangeList.GetClientData(selected) - if selCommand.UI: - self.EditButton.Enable() - else: - self.EditButton.Disable() - - def UpdateBindStringDisplay(self): - self.BindStringDisplay.SetValue(self.MakeBindString()) - self.BindStringDisplay.SetToolTip(self.MakeBindString()) - - def MakeBindString(self): - cmdBindStrings = [] - for index in range(self.RearrangeList.GetCount()): - c = self.RearrangeList.GetClientData(index) - if c: cmdBindStrings.append(c.MakeBindString()) - - bindstring = ('$$'.join(cmdBindStrings)) - return bindstring - - def ShowEditDialogFor(self, command): - if not command.UI: return - - self.EditDialog.mainSizer.Show(command.UI) - - self.EditDialog.Layout() - self.EditDialog.Fit() - - self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') - returnval = self.EditDialog.ShowModal() - - self.EditDialog.mainSizer.Hide(command.UI) - - return returnval - - def makeAddStepMenu(self): - - stepMenu = wx.Menu() - - for subname in menuStructure: - submenu = wx.Menu() - stepMenu.AppendSubMenu(submenu, subname) - for classname in menuStructure[subname]: - submenu.Append(wx.ID_ANY, classname) - - stepMenu.Append(wx.ID_ANY, 'Custom Bind') - - return stepMenu - -class PowerBinderButton(wx.BitmapButton): - - def __init__(self, parent, tgtTxtCtrl, init = {}): - wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) - self.Init = init - self.Dialog = None - self.DialogParent = parent - - self.tgtTxtCtrl = tgtTxtCtrl - self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) - self.SetToolTip("Launch PowerBinder") - - def PowerBinderEventHandler(self, _): - self.PowerBinderDialog().Show() - - def LoadFromData(self, data): - self.PowerBinderDialog().LoadFromData(data) - - def SaveToData(self): - return self.PowerBinderDialog().SaveToData() - - def PowerBinderDialog(self): - if not self.Dialog: - self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) - return self.Dialog - - -class PowerBinderEditDialog(wx.Dialog): - def __init__(self, parent): - wx.Dialog.__init__(self, parent, -1, "Edit Step", - style = wx.DEFAULT_DIALOG_STYLE) - - outerSizer = wx.BoxSizer(wx.VERTICAL) - - self.mainSizer = wx.BoxSizer(wx.VERTICAL) - self.mainSizer.SetMinSize([500, 150]) - - self.Page = parent.Page - - self.mainSizer.Add( - self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), - 0, wx.EXPAND|wx.ALL, 10) - - outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) - - self.SetSizerAndFit(outerSizer) - self.Layout() - self.Fit() - -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" - - -####### Away From Keyboard -class AFKCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.Groups = {} - self.AttributeTable = { - 'Base' : { - 'Current Hit Points' : 'NT H', - 'Max Hit Points' : 'X H', - 'Current Endurance' : 'T E', - 'Max Endurance' : 'X EN', - 'Regeneration Rate' : 'N RAT', - 'Recovery Rate' : 'Y RA', - 'Endurance Consumption' : 'SU', - 'ToHit Bonus' : 'T B', - 'Accuracy Bonus' : 'CC', - 'Last Hit Chance' : 'T C', - 'Damage Bonus' : 'DA', - 'Healing Bonus' : 'NG B', - 'Recharge Time Bonus' : 'ME B', - 'Endurance Discount' : 'CE DIS', - 'Stealth Radius (PvP)' : 'PVP', - 'Stealth Radius (PvE)' : 'PVE', - 'Perception Radius' : 'RC', - 'Range Bonus' : 'GE B', - 'Threat Level' : 'AT L', - 'Experience to Next Level' : 'XT', - 'Experience Debt' : 'XP', - 'Influence / Infamy' : 'INF', - 'Inherent' : 'NH', - }, - 'Movement Speed' : { - 'Flying Speed' : 'FL', - 'Jumping Speed' : 'PI', - 'Max Jump Height' : 'X J', - 'Run Speed' : 'RU', - }, - 'Damage Resistance' : { - 'Smashing Resistance' : 'G R', - 'Lethal Resistance' : 'L R', - 'Fire Resistance' : 'RE R', - 'Cold Resistance' : 'COLD R', - 'Energy Resistance' : 'DamageType[4]', - 'Negative Energy Resistance' : 'GY R', - 'Psyonic Resistance' : 'NIC R', - 'Toxic Resistance' : 'XIC R', - }, - 'Defense' : { - 'Base Defense' : 'BAS', - 'Ranged Defense' : 'ED', - 'Melee Defense' : 'MEL', - 'AoE Defense' : '2', - 'Smashing Defense' : '3', - 'Lethal Defense' : '4', - 'Fire Defense' : '5', - 'Cold Defense' : '6', - 'Energy Defense' : '7', - 'Negative Energy Defense' : '8', - 'Psionic Defense' : '9', - 'Toxic Defense' : '1', - }, - 'Debuff Resistance' : { - 'Regeneration Resistance' : 'ON R', - 'Recovery Resistance' : 'RY R', - 'To Hit Resistance' : 'IT R', - 'Defense Resistance' : 'NSE RES', - }, - 'Status Effect Protection' : { - 'Hold Protection' : 'D P', - 'Immobilize Protection' : 'LIZE P', - 'Stun Protection' : 'N P', - 'Sleep Protection' : 'P P', - 'Knockback Protection' : 'K P', - 'Confuse Protection' : 'SE P', - 'Terrorize Protection' : 'ZE P', - 'Repel Protection' : 'EL P', - 'Teleport Protection' : 'T P', - }, - 'Status Effect Resistance' : { - 'Hold Resistance' : 'D R', - 'Immobilize Resistance' : 'LIZE R', - 'Stun Resistance' : 'N R', - 'Sleep Resistance' : 'P R', - 'Knockback Resistance' : 'K R', - 'Confuse Resistance' : 'SE R', - 'Terrorize Resistance' : 'ZE R', - 'Placate Resistance' : 'TE R', - 'Taunt Resistance' : 'NT R', - }, - 'Miscellaneous' : { - 'Level Shift' : 'L S', - }, - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.AttributeMenu = wx.Menu() - for group, controls in self.AttributeTable.items(): - submenu = wx.Menu() - self.AttributeMenu.AppendSubMenu(submenu, group) - for cb in controls: - submenu.Append(wx.ID_ANY, cb) - - self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) - - self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) - groupSizer.Add(self.editbox) - - newButton = self.editbox.GetNewButton() - newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) - - return groupSizer - - def MakeBindString(self): - map = {} - bindstrings = [] - for _, controls in self.AttributeTable.items(): - for cb, data in controls.items(): - map[cb] = data - - for string in self.editbox.GetStrings(): - if string: - bindstrings.append(f'monitorattribute {map[string]}') - - return '$$'.join(bindstrings) - - def Serialize(self): - return { - 'attributes' : self.editbox.GetStrings() - } - - def Deserialize(self, init): - self.editbox.SetStrings(init.get('attributes', [])) - - def OnNewButton(self, evt): - evt.GetEventObject().PopupMenu(self.AttributeMenu) - - def OnMenuItem(self, evt): - menuitem = evt.EventObject.FindItemById(evt.GetId()) - existingstrings = self.editbox.GetStrings() - existingstrings.append(menuitem.GetItemLabel()) - self.editbox.SetStrings(existingstrings) - -####### Auto Power -class AutoPowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) - autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.autoPowerName = PowerPicker(dialog) - autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) - - return autoPowerSizer - - def MakeBindString(self): - return f"powexecauto {self.autoPowerName.GetLabel()}" - - def Serialize(self): - return { - 'pname' : self.autoPowerName.GetLabel(), - 'picon' : self.autoPowerName.IconFilename - } - - def Deserialize(self, init): - if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.buffDisplayMap = { - 'Status Window' : { - 'Hide Auto' : 1, - 'Hide Toggles' : 2, - 'No Blinking' : 4, - 'No Stacking' : 8, - 'Numeric Stacking' : 16, - 'Hide Buff Numbers' : 32, - 'Stop Sending Buffs' : 64, - }, - 'Group Window' : { - 'Hide Auto' : 256, - 'Hide Toggles' : 512, - 'No Blinking' : 1024, - 'No Stacking' : 2048, - 'Numeric Stacking' : 4096, - 'Hide Buff Numbers' : 8192, - 'Stop Sending Buffs' : 16384, - }, - 'Pet Window' : { - 'Hide Auto' : 65536, - 'Hide Toggles' : 131072, - 'No Blinking' : 262144, - 'No Stacking' : 524288, - 'Numeric Stacking' : 1048576, - 'Hide Buff Numbers' : 2097152, - 'Stop Sending Buffs' : 4194304, - }, - } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - for group, controls in self.buffDisplayMap.items(): - self.Groups[group] = ControlGroup(dialog, self.Page, label = group) - groupid = self.Groups[group].GetStaticBox().GetId() - for cb, data in controls.items(): - self.Groups[group].AddControl( - ctlType = 'checkbox', - ctlName = f"{groupid}_{group}_{cb}", - label = cb, - data = data, - ) - - groupSizer.Add(self.Groups[group]) - - return groupSizer - - def CalculateValue(self): - page = wx.App.Get().Main.Profile.CustomBinds - - total = 0 - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] - if checkbox.IsChecked(): - total = total + checkbox.Data - return total - - def MakeBindString(self): - return f"optionset buffsettings {self.CalculateValue()}" - - def Serialize(self): - return { 'value' : self.CalculateValue() } - - def Deserialize(self, init): - value = init.get('value', 0) - - value = value or 0 # in case we had for some reason 'None' stashed in the init values - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] - checkbox.SetValue( checkbox.Data & value ) - -####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - chatCommandSizer = wx.GridBagSizer(5, 5) - self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") - chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) - # row 1 - self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) - self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) - self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) - # row 2 - self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) - self.chatCommandDuration.SetRange(1, 20) - self.chatCommandDuration.SetValue(7) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandDuration, (2,1)) - self.chatCommandChatSize = wx.Choice(dialog, -1, - choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) - self.chatCommandChatSize.SetSelection(5) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) - self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) - self.chatCommandChannel.SetSelection(0) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChannel, (2,5)) - # row 3 - self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") - chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) - self.chatCommandMessage = wx.TextCtrl(dialog, -1) - self.chatCommandMessage.SetHint('Chat Command Text') - chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) - - return chatCommandSizer - - def MakeBindString(self): - duration = self.chatCommandDuration.GetValue() - - choice = self.chatCommandChatSize - index = choice.GetSelection() - size = choice.GetString(index) - - duration = f"" if duration != 7 else "" - size = f"" if size != "1" else "" - - bdcolor = fgcolor = bgcolor = '' - if self.chatCommandUseColorsCB.IsChecked(): - bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - - bdcolor = f"" - fgcolor = f"" - bgcolor = f"" - - beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' - text = self.chatCommandMessage.GetValue() - - choice = self.chatCommandChannel - index = choice.GetSelection() - channel = choice.GetString(index) - - return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" - - def Serialize(self): - return { - 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), - 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), - 'channel' : self.chatCommandChannel .GetSelection(), - 'size' : self.chatCommandChatSize.GetSelection(), - 'duration' : self.chatCommandDuration.GetValue(), - 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'text' : self.chatCommandMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) - if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) - if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) - if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) - if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) - if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) - if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) - if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) - if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - - -####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): - def BuildUI(self, dialog): - chatCommandGlobalSizer = wx.GridBagSizer(5,5) - - self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") - chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) - - self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalChannel.SetHint("Channel") - chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) - - self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') - chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) - - chatCommandGlobalSizer.AddGrowableCol(1) - - return chatCommandGlobalSizer - - def MakeBindString(self): - useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() - channel = self.chatCommandGlobalChannel.GetValue() - message = self.chatCommandGlobalMessage.GetValue() - - preface = "beginchat /" if useBeginchat else "" - - return f'{preface}send "{channel}" {message}' - - def Serialize(self): - return { - 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), - 'channel' : self.chatCommandGlobalChannel.GetValue(), - 'message' : self.chatCommandGlobalMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) - if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) - if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) - -#######Costume Change -class CostumeChangeCmd(PowerBindCmd): - def BuildUI(self, dialog): - costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeCostume = wx.Choice(dialog, -1, - choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) - self.costumeChangeCostume.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeEmote = wx.Choice(dialog, -1, - choices = GameData.Emotes['costumechange']) - self.costumeChangeEmote.Insert("- None -", 0) - self.costumeChangeEmote.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return costumeChangeSizer - - def MakeBindString(self): - costumeNumber = self.costumeChangeCostume.GetSelection() - costumeEmote = self.costumeChangeEmote.GetSelection() - - if costumeEmote: # None, or 0 == "- None -" - ccCmd = 'cce' - emoteName = self.costumeChangeEmote.GetString(costumeEmote) - emoteName = " CC" + emoteName.replace(" ","") - else: - ccCmd = 'cc' - emoteName = '' - - return f"{ccCmd} {costumeNumber}{emoteName}" - - def Serialize(self): - return{ - 'costumeNumber': self.costumeChangeCostume.GetSelection(), - 'costumeEmote' : self.costumeChangeEmote.GetSelection(), - } - - def Deserialize(self, init): - if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) - if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) - -####### Movement Command -class MovementCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - self.plusbutton.SetValue(True) - - self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.commandchoice = wx.Choice(dialog, choices = [ - "forward", "left", "right", "backward", "up", "down", - "turnleft", "turnright", "first", "autorun", "clicktomove", - ],) - sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) - self.commandchoice.SetSelection(0) - - self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - pre = post = '' - if self.plusbutton.GetValue() : pre = "+" - elif self.plusplusbutton.GetValue() : pre = "++" - elif self.minusbutton.GetValue() : pre = "-" - elif self.zerobutton.GetValue() : post = " 0" - elif self.onebutton.GetValue() : post = " 1" - - command = self.commandchoice.GetString(self.commandchoice.GetSelection()) - - return f"{pre}{command}{post}" - - def Serialize(self): - mod = '' - if self.plusbutton.GetValue() : mod = "plus" - elif self.plusplusbutton.GetValue() : mod = "plusplus" - elif self.minusbutton.GetValue() : mod = "minus" - elif self.zerobutton.GetValue() : mod = "zero" - elif self.onebutton.GetValue() : mod = "one" - - return { - 'mod' : mod, - 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), - } - - def Deserialize(self, init): - mod = init.get('mod', 'plus') - - if mod == 'plus' : self.plusbutton.SetValue(True) - elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) - elif mod == 'minus' : self.minusbutton.SetValue(True) - elif mod == 'zero' : self.zerobutton.SetValue(True) - elif mod == 'one' : self.onebutton.SetValue(True) - - self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) - -####### Graphics Command -class GraphicsCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.FlexGridSizer(2) - - self.visscalecb = wx.CheckBox(dialog, label = "visscale") - sizer.Add(self.visscalecb) - self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) - sizer.Add(self.visscalesc) - - self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") - sizer.Add(self.dofweightcb) - self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) - sizer.Add(self.dofweightsc) - - self.fsaacb = wx.CheckBox(dialog, label = "fsaa") - sizer.Add(self.fsaacb) - self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) - self.fsaach.SetSelection(0) - sizer.Add(self.fsaach) - - self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") - sizer.Add(self.bloomscalecb) - self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) - self.bloomscalech.SetSelection(0) - sizer.Add(self.bloomscalech) - - self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") - sizer.Add(self.bloomweightcb) - self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) - sizer.Add(self.bloomweightsc) - - self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") - sizer.Add(self.lodbiascb) - self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) - sizer.Add(self.lodbiassc) - - self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") - sizer.Add(self.renderscalecb) - self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) - sizer.Add(self.renderscalesc) - - return sizer - - def MakeBindString(self): - # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. - bindstrings = [] - if self.visscalecb.IsChecked(): - bindstrings.append("visscale " + str(self.visscalesc.GetValue())) - if self.dofweightcb.IsChecked(): - bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) - if self.fsaacb.IsChecked(): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bindstrings.append("fsaa " + fsaavalue) - if self.bloomscalecb.IsChecked(): - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - bindstrings.append("bloomscale " + bloomscalevalue) - if self.bloomweightcb.IsChecked(): - bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) - if self.lodbiascb.IsChecked(): - bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) - if self.renderscalecb.IsChecked(): - bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) - - return '$$'.join(bindstrings) - - def Serialize(self): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - return { - 'visscalecb' : self.visscalecb.IsChecked(), - 'visscalesc' : self.visscalesc.GetValue(), - 'dofweightcb' : self.dofweightcb.IsChecked(), - 'dofweightsc' : self.dofweightsc.GetValue(), - 'fsaacb' : self.fsaacb.IsChecked(), - 'fsaach' : fsaavalue, - 'bloomscalecb' : self.bloomscalecb.IsChecked(), - 'bloomscalech' : bloomscalevalue, - 'bloomweightcb' : self.bloomweightcb.IsChecked(), - 'bloomweightsc' : self.bloomweightsc.GetValue(), - 'lodbiascb' : self.lodbiascb.IsChecked(), - 'lodbiassc' : self.lodbiassc.GetValue(), - 'renderscalecb' : self.renderscalecb.IsChecked(), - 'renderscalesc' : self.renderscalesc.GetValue(), - } - - def Deserialize(self, init): - self.visscalecb.SetValue(init.get('visscalecb', False)) - self.visscalesc.SetValue(init.get('visscalesc', 1.0)) - self.dofweightcb.SetValue(init.get('dofweightcb', False)) - self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) - self.fsaacb.SetValue(init.get('fsaacb', False)) - self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) - self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) - self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) - self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) - self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) - self.lodbiascb.SetValue(init.get('lodbiascb', False)) - self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) - self.renderscalecb.SetValue(init.get('renderscalecb', False)) - self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) - -####### Custom Bind -class CustomBindCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.customBindName = wx.TextCtrl(dialog, -1) - self.customBindName.SetHint('Custom Bind Text') - sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - return self.customBindName.GetValue() - - def Serialize(self): - return { 'customBindName': self.customBindName.GetValue() } - - def Deserialize(self,init): - if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) - -####### Emote -class EmoteCmd(PowerBindCmd): - def BuildUI(self, dialog): - emoteSizer = wx.BoxSizer(wx.HORIZONTAL) - self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") - emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - self.emoteName = wx.Button(dialog, -1, "...") - self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) - emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) - - return emoteSizer - - def MakeBindString(self): - displayedEmoteName = self.emoteName.GetLabel() - actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] - - return actualEmotePayload - - def Serialize(self): - return {'emoteName': self.emoteName.GetLabel()} - - def Deserialize(self, init): - if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) - -####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): - def BuildUI(self, dialog): - mainSizer = wx.BoxSizer(wx.VERTICAL) - - lbSizer = wx.BoxSizer(wx.HORIZONTAL) - lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") - lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - profiles = Profile.GetAllProfileBindsDirs() - - self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) - lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) - - mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") - self.lbResetCB.SetValue(True) - - mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - return mainSizer - - def MakeBindString(self): - - # If the specified binds directory disappeared between runs, we'd crash, so handle that. - if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' - - config = wx.ConfigBase.Get() - if config.Exists('GameBindPath'): - bindpath = config.Read('GameBindPath') - else: - bindpath = config.Read('BindPath') - - reset = "" - if self.lbResetCB.GetValue(): - reset = "keybind_reset$$" - - resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' - return reset + 'bindloadfile ' + str(resetfilepath) - - def Serialize(self): - return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), - 'ResetKeybinds' : self.lbResetCB.GetValue(), - } - - def Deserialize(self, init): - if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) - self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) - -####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' - -####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' - -####### SG Mode -class SGModeCmd(PowerBindCmd): - def BuildUI(self, dialog): - sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) - sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") - self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") - - sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) - - return sgmodeSizer - - def MakeBindString(self): - if self.sgmodeOnRB.GetValue(): - return 'sgmodeset 1' - elif self.sgmodeOffRB.GetValue(): - return 'sgmodeset 0' - else: - return 'sgmode' - - def Serialize(self): - if self.sgmodeOnRB.GetValue(): - val = "On" - elif self.sgmodeOffRB.GetValue(): - val = "Off" - else: - val = "Toggle" - - return {"value" : val} - - def Deserialize(self, init): - val = init.get('value', '') - if val == "On": - self.sgmodeOnRB.SetValue(True) - elif val == "Off": - self.sgmodeOffRB.SetValue(True) - else: - self.sgmodeToggleRB.SetValue(True) - -####### Target Custom -class TargetCustomCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetCustomSizer = wx.GridBagSizer(5,5) - targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), - flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) - self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetCustomModeChoice.SetSelection(0) - targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) - self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) - self.targetCustomOptionalName.SetHint("Optional name to match") - targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) - self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") - targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) - self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") - targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) - self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") - targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) - self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") - targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) - self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") - targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) - self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") - targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) - self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") - targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) - self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") - targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) - - targetCustomSizer.AddGrowableCol(2) - - return targetCustomSizer - - def MakeBindString(self): - choice = self.targetCustomModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - targetCommand = "targetcustom" + mode.lower() - - enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" - friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" - defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" - alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" - mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" - notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" - base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" - notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" - - name = self.targetCustomOptionalName.GetValue() - - return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" - - def Serialize(self): - return { - 'mode' : self.targetCustomModeChoice.GetSelection(), - 'enemy' : self.targetCustomCBEnemies. IsChecked(), - 'friend' : self.targetCustomCBFriends. IsChecked(), - 'defeated' : self.targetCustomCBDefeated. IsChecked(), - 'alive' : self.targetCustomCBAlive. IsChecked(), - 'mypet' : self.targetCustomCBMyPets. IsChecked(), - 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), - 'base' : self.targetCustomCBBaseItems. IsChecked(), - 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), - 'name' : self.targetCustomOptionalName.GetValue(), - } - - def Deserialize(self, init): - if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) - if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) - if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) - if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) - if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) - if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) - if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) - if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) - if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) - if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - - -####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) - targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetEnemyModeChoice.SetSelection(0) - targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetEnemySizer - - def MakeBindString(self): - choice = self.targetEnemyModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetenemy" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetEnemyModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) - -####### Target Friend -class TargetFriendCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) - targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetFriendModeChoice.SetSelection(0) - targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetFriendSizer - - def MakeBindString(self): - choice = self.targetFriendModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetfriend" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetFriendModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) - -####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): - def BuildUI(self, dialog): - teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], - style=wx.ALIGN_CENTER_VERTICAL) - self.teamPetSelectNumber.SetSelection(0) - teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) - - return teamPetSelectSizer - - def MakeBindString(self): - teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' - targetNumber = self.teamPetSelectNumber.GetSelection()+1 - - return f"{teamOrPet}select {targetNumber}" - - def Serialize(self): - return { - 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', - 'targetNum': self.teamPetSelectNumber.GetSelection(), - } - - def Deserialize(self, init): - ToP = init.get('teamOrPet', '') - if ToP == 'pet': - self.teamPetSelectPetRB.SetValue(True) - else: - self.teamPetSelectTeamRB.SetValue(True) - if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) - -####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' - -####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) - for _, types in GameData.Inspirations.items(): - for _, info in types.items(): - for insp in info['tiers']: - name = re.sub(' ', '', str(insp)) - icon = GetIcon(f'Inspirations/{name}') - self.useInspByNameModeChoice.Append(insp, icon) - self.useInspByNameModeChoice.SetSelection(0) - useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) - - return useInspByNameSizer - - def MakeBindString(self): - choice = self.useInspByNameModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "inspexecname " + mode.lower() - - def GetAllInsps(self): - Insplist = [] - for _, info in GameData.Inspirations.items(): - for insp in info['tiers']: - Insplist.append(insp) - Insplist.append("---") - Insplist.pop(-1) # snip the terminal "---" - - return Insplist - - def Serialize(self): - return { 'insp' : self.useInspByNameModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) +from UI.PowerBinderCommand import PowerBinderCommand ####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): +class UseInspRowColCmd(PowerBinderCommand): + Name = "Use Inspiration From Row/Column" + Menu = "Inspirations" + def BuildUI(self, dialog): useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, @@ -1347,454 +36,3 @@ def Serialize(self): def Deserialize(self, init): if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) - -####### Use Power -class UsePowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - outerSizer = wx.BoxSizer(wx.HORIZONTAL) - - usePowerSizer = wx.GridBagSizer(5,5) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBToggle, (0,1)) - self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOn, (0,2)) - self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOff, (0,3)) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerName = PowerPicker(dialog) - usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) - usePowerSizer.AddGrowableCol(3) - - outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) - - return outerSizer - - def MakeBindString(self): - if self.usePowerRBToggle.GetValue(): - method = "powexecname" - elif self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') - return '' - - return f"{method} {self.usePowerName.GetLabel()}" - - def Serialize(self): - if self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - method = "powexecname" - return { - 'method': method, - 'pname' : self.usePowerName.GetLabel(), - 'picon' : self.usePowerName.IconFilename - } - - def Deserialize(self, init): - method = init.get('method', '') - if method == 'powexectoggleon': - self.usePowerRBOn.SetValue(True) - elif method == 'powexectoggleoff': - self.usePowerRBOff.SetValue(True) - else: - self.usePowerRBToggle.SetValue(True) - if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) - -####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): - def BuildUI(self, dialog): - usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTrayTray = wx.Choice(dialog, -1, - choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', - 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) - self.usePowerFromTrayTray.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) - self.usePowerFromTraySlot.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return usePowerFromTraySizer - - def MakeBindString(self): - choice = self.usePowerFromTrayTray - tray = choice.GetSelection() - - choice = self.usePowerFromTraySlot - slot = choice.GetSelection()+1 - - mode = "slot" - mode2 = '' - if tray > 3: - mode = "tray" - mode2 = f" {tray - 3}" - elif tray == 3: - mode = "alt2slot" - elif tray == 2: - mode = "altslot" - - return f"powexec{mode} {slot}{mode2}" - - def Serialize(self): - return { - 'tray' : self.usePowerFromTrayTray.GetSelection(), - 'slot' : self.usePowerFromTraySlot.GetSelection(), - } - - def Deserialize(self, init): - if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) - if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) - -####### Window Color -class WindowColorCmd(PowerBindCmd): - def BuildUI(self, dialog): - windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) - borderSizer = wx.BoxSizer(wx.VERTICAL) - self.ColorBorder.SetSizer(borderSizer) - self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) - borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) - - windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) - - RGBASizer = wx.FlexGridSizer(3, 4, 5) - - RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) - self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) - self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - windowColorSizer.Add(RGBASizer) - - self.UpdateFromSlider() - - return windowColorSizer - - def MakeBindString(self): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - return f"windowcolor {Rval} {Gval} {Bval} {Aval}" - - def Serialize(self): - return { - 'Rval' : self.RSlider.GetValue(), - 'Gval' : self.GSlider.GetValue(), - 'Bval' : self.BSlider.GetValue(), - 'Aval' : self.ASlider.GetValue(), - } - - def Deserialize(self, init): - self.RSlider.SetValue(init['Rval']) - self.GSlider.SetValue(init['Gval']) - self.BSlider.SetValue(init['Bval']) - self.ASlider.SetValue(init['Aval']) - self.UpdateFromSlider() - - def UpdateFromSlider(self, _ = None): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RReadout.SetValue(Rval) - self.GReadout.SetValue(Gval) - self.BReadout.SetValue(Bval) - self.AReadout.SetValue(Aval) - self.ColorBorder.Refresh() - - def UpdateFromText(self, _ = None): - Rval = self.RReadout.GetValue() - Gval = self.GReadout.GetValue() - Bval = self.BReadout.GetValue() - Aval = self.AReadout.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RSlider.SetValue(Rval) - self.GSlider.SetValue(Gval) - self.BSlider.SetValue(Bval) - self.ASlider.SetValue(Aval) - self.ColorBorder.Refresh() - -####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) - self.CommandChoice.SetSelection(0) - sizer.Add(self.CommandChoice, 0, wx.ALL, 5) - - self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), - value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) - sizer.Add(self.FilePath, 0, wx.ALL, 5) - - return sizer - - def MakeBindString(self): - command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] - return f'{command} "{self.FilePath.GetValue()}"' - - def Serialize(self): - return { - 'command' : self.CommandChoice.GetSelection(), - 'filename' : self.FilePath.GetValue(), - } - - def Deserialize(self, init): - self.CommandChoice.SetSelection(init.get('command', 0)) - self.FilePath.SetValue(init.get('filename', '')) - -####### Window Toggle -class WindowToggleCmd(PowerBindCmd): - def BuildUI(self, dialog): - self.WindowNames = { - 'Actions' : 'actions', - 'Auction House' : 'ah', - 'Badge' : 'badge', - 'Channel Search' : 'chansearch', - 'Chat' : 'chat', - 'Custom Chat 1' : 'chat1', - 'Custom Chat 2' : 'chat2', - 'Custom Chat 3' : 'chat3', - 'Custom Chat 4' : 'chat4', - 'Clues' : 'clue', - 'Combat Numbers' : 'combatnumbers', - 'Contacts' : 'contact', - 'Contact Finder' : 'contactfinder', - 'Costumes' : 'costume', - 'Email' : 'email', - 'Enhancements' : 'enhancements', - 'Friends' : 'friend', - 'Group' : 'group', - 'Help' : 'helpwindow', - 'Incarnate' : 'incarnate', - 'Inspirations' : 'insp', - 'League' : 'league', - 'LFG' : 'lfg', - 'Map' : 'map', - 'Mission' : 'mission', - 'Nav / Compass' : 'nav', - 'Options' : 'options', - 'Pets' : 'pet', - 'Petition' : 'petition', - 'Power Tray' : 'powers', - 'Power List' : 'powerlist', - 'Quit' : 'quit', - 'Recipes' : 'recipe', - 'Salvage' : 'salvage', - 'Search' : 'search', - 'Supergroup' : 'sg', - 'Target' : 'target', - 'Team' : 'team', - 'Tray' : 'tray', - 'Tray1' : 'tray1', - 'Tray2' : 'tray2', - 'Tray3' : 'tray3', - 'Tray4' : 'tray4', - 'Tray5' : 'tray5', - 'Tray6' : 'tray6', - 'Tray7' : 'tray7', - 'Tray8' : 'tray8', - 'Vault' : 'vault', - } - - self.ShortToggleCommands = { - 'Auction House' : 'ah', - 'Chat' : 'chat', - 'Help' : 'helpwindow', - 'Map' : 'map', - 'Nav / Compass' : 'nav', - 'Power Tray' : 'powers', - 'Target' : 'target', - 'Tray' : 'tray', - } - - windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) - windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) - self.windowToggleTray.SetSelection(0) - windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.windowShowRB = wx.RadioButton(dialog, -1, "Show") - self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") - - windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) - - return windowToggleSizer - - def MakeBindString(self): - choice = self.windowToggleTray - index = choice.GetSelection() - windowdesc = choice.GetString(index) - windowname = self.WindowNames[windowdesc] - - if self.windowShowRB.GetValue(): - return 'show ' + windowname - elif self.windowHideRB.GetValue(): - return 'windowhide ' + windowname - else: - if shortcmd := self.ShortToggleCommands.get(windowdesc, None): - return shortcmd - else: - return 'toggle ' + windowname - - - def Serialize(self): - choice = self.windowToggleTray - if self.windowShowRB.GetValue(): - action = "Show" - elif self.windowHideRB.GetValue(): - action = "Hide" - else: - action = "Toggle" - return { - 'window': choice.GetString(choice.GetSelection()), - 'action': action, - } - - def Deserialize(self, init): - choice = self.windowToggleTray - if window := init.get('window', ''): - if isinstance(window, int): - choice.SetSelection(window) - else: - choice.SetSelection(choice.FindString(window)) - - if choice.GetSelection() == wx.NOT_FOUND: - choice.SetSelection(0) - - action = init.get('action', '') - if action == "Show": - self.windowShowRB.SetValue(True) - elif action == "Hide": - self.windowHideRB.SetValue(True) - else: - self.windowToggleRB.SetValue(True) - - -# Must always add to this list when adding a new command class above -menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], - # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, - # but I'm leaving it here to remind myself that we do that. - } - -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/UsePowerCmd.py b/UI/PowerBinderCommand/UsePowerCmd.py index 4c02ab7..4a52a13 100644 --- a/UI/PowerBinderCommand/UsePowerCmd.py +++ b/UI/PowerBinderCommand/UsePowerCmd.py @@ -1,1355 +1,13 @@ import wx -import re -import UI -import UI.EmotePicker -from UI.ControlGroup import ControlGroup from UI.PowerPicker import PowerPicker -from Help import HelpButton -import wx.adv -from wx.adv import BitmapComboBox, EditableListBox -from pathlib import PureWindowsPath -import GameData -import Profile from Icon import GetIcon - -class PowerBinderDialog(wx.Dialog): - def __init__(self, parent, button, init = {}): - wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) - - self.Page = parent.Page - self.EditDialog = PowerBinderEditDialog(self) - self.Button = button - self.AddStepMenu = self.makeAddStepMenu() - - sizer = wx.BoxSizer(wx.VERTICAL); - self.mainSizer = sizer - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) - AddStepButton = wx.Button(self, -1, 'Add Step') - AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) - AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) - choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) - choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) - sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) - - rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) - - self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) - self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) - self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) - rearrangeCtrl.Add(self.RearrangeList, 1) - - rearrangeButtons = wx.BoxSizer(wx.VERTICAL) - self.DelButton = wx.Button(self, -1, "Delete") - self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) - self.EditButton = wx.Button(self, -1, "Edit") - self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) - self.EditButton.Disable() - upButton = wx.Button(self, -1, "\u25B2") - upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) - downButton = wx.Button(self, -1, "\u25BC") - downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) - rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) - rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) - - sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.BindStringDisplay = wx.TextCtrl(self, -1) - self.BindStringDisplay.Disable() - choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, - wx.ALIGN_CENTER_VERTICAL) - choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) - - sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) - - sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) - - # need to dig around and get the OK button since we show this dialog modelessly now. - okButton = self.FindWindow(self.GetAffirmativeId()) - okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) - - # Wrap everything in a vbox to add some padding - vbox = wx.BoxSizer(wx.VERTICAL); - vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); - - self.SetSizerAndFit(vbox); - self.Layout() - self.Fit() - self.SetFocus() - - # if we are loading from profile, ie, have "init", build the list from it - if init: self.LoadFromData(init) - - def LoadFromData(self, init): - for item in init: - for type, data in item.items(): - commandClass = commandClasses.get(type, None) - if not commandClass: - commandClass = deprecatedCommandClasses.get(type, None) - if not commandClass: - wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") - continue - newCommand = commandClass(self.EditDialog, data) - index = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.SetClientData(index, newCommand) - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) - self.EditDialog.mainSizer.Hide(newCommand.UI) - self.UpdateBindStringDisplay() - - def SaveToData(self): - data = [] - index = 0 - for _ in self.RearrangeList.GetItems(): - # check whether we have an object already attached to this choice - cmdObject = self.RearrangeList.GetClientData(index) - commandClassName = commandRevClasses[type(cmdObject)] - data.append({commandClassName: cmdObject.Serialize()}) - index = index + 1 - return data - - def OnAddStepButton(self, evt): - button = evt.EventObject - if not self.AddStepMenu: - self.AddStepMenu = self.makeAddStepMenu() - button.PopupMenu(self.AddStepMenu) - - - def OnOKButton(self, _): - if self.Button.tgtTxtCtrl: - bindString = self.MakeBindString() - if bindString != self.Button.tgtTxtCtrl.GetValue(): - self.Button.tgtTxtCtrl.SetValue(bindString) - wx.App.Get().Main.Profile.SetModified() - self.Close() - - def OnRearrangeDelete(self, _): - current = self.RearrangeList.GetSelection() - if current == wx.NOT_FOUND: return - - self.RearrangeList.Delete(current) - self.UpdateBindStringDisplay() - - def OnRearrangeUp(self, _): - self.RearrangeList.MoveCurrentUp() - self.UpdateBindStringDisplay() - - def OnRearrangeDown(self, _): - self.RearrangeList.MoveCurrentDown() - self.UpdateBindStringDisplay() - - def OnRearrangeEdit(self, _): - index = self.RearrangeList.GetSelection() - - # check whether we have an object already attached to this choice - cmdObject = None - try: - cmdObject = self.RearrangeList.GetClientData(index) - except Exception: - pass - - if cmdObject: - self.ShowEditDialogFor(cmdObject) - self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) - else: - print("cmdObject was None") - self.UpdateBindStringDisplay() - - # OnAddStepMenu creates a new step and adds it to the rearrangelist - def OnAddStepMenu(self, evt): - menuitem = self.AddStepMenu.FindItemById(evt.GetId()) - chosenName = menuitem.GetItemLabel() - - # make a new command object, attached to the parent dialog - newCommandClass = commandClasses[chosenName] - newCommand = newCommandClass(self.EditDialog) - - # show the edit dialog if this command needs it - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) - if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): - self.EditDialog.mainSizer.Remove(newCommand.UI) - return - - newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.Select(newBindIndex) - self.RearrangeList.SetClientData(newBindIndex, newCommand) - - self.OnListSelect() - self.UpdateBindStringDisplay() - - def OnListSelect(self, _ = None): - selected = self.RearrangeList.GetSelection() - - if selected != wx.NOT_FOUND: - selCommand = self.RearrangeList.GetClientData(selected) - if selCommand.UI: - self.EditButton.Enable() - else: - self.EditButton.Disable() - - def UpdateBindStringDisplay(self): - self.BindStringDisplay.SetValue(self.MakeBindString()) - self.BindStringDisplay.SetToolTip(self.MakeBindString()) - - def MakeBindString(self): - cmdBindStrings = [] - for index in range(self.RearrangeList.GetCount()): - c = self.RearrangeList.GetClientData(index) - if c: cmdBindStrings.append(c.MakeBindString()) - - bindstring = ('$$'.join(cmdBindStrings)) - return bindstring - - def ShowEditDialogFor(self, command): - if not command.UI: return - - self.EditDialog.mainSizer.Show(command.UI) - - self.EditDialog.Layout() - self.EditDialog.Fit() - - self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') - returnval = self.EditDialog.ShowModal() - - self.EditDialog.mainSizer.Hide(command.UI) - - return returnval - - def makeAddStepMenu(self): - - stepMenu = wx.Menu() - - for subname in menuStructure: - submenu = wx.Menu() - stepMenu.AppendSubMenu(submenu, subname) - for classname in menuStructure[subname]: - submenu.Append(wx.ID_ANY, classname) - - stepMenu.Append(wx.ID_ANY, 'Custom Bind') - - return stepMenu - -class PowerBinderButton(wx.BitmapButton): - - def __init__(self, parent, tgtTxtCtrl, init = {}): - wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) - self.Init = init - self.Dialog = None - self.DialogParent = parent - - self.tgtTxtCtrl = tgtTxtCtrl - self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) - self.SetToolTip("Launch PowerBinder") - - def PowerBinderEventHandler(self, _): - self.PowerBinderDialog().Show() - - def LoadFromData(self, data): - self.PowerBinderDialog().LoadFromData(data) - - def SaveToData(self): - return self.PowerBinderDialog().SaveToData() - - def PowerBinderDialog(self): - if not self.Dialog: - self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) - return self.Dialog - - -class PowerBinderEditDialog(wx.Dialog): - def __init__(self, parent): - wx.Dialog.__init__(self, parent, -1, "Edit Step", - style = wx.DEFAULT_DIALOG_STYLE) - - outerSizer = wx.BoxSizer(wx.VERTICAL) - - self.mainSizer = wx.BoxSizer(wx.VERTICAL) - self.mainSizer.SetMinSize([500, 150]) - - self.Page = parent.Page - - self.mainSizer.Add( - self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), - 0, wx.EXPAND|wx.ALL, 10) - - outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) - - self.SetSizerAndFit(outerSizer) - self.Layout() - self.Fit() - -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" - - -####### Away From Keyboard -class AFKCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.Groups = {} - self.AttributeTable = { - 'Base' : { - 'Current Hit Points' : 'NT H', - 'Max Hit Points' : 'X H', - 'Current Endurance' : 'T E', - 'Max Endurance' : 'X EN', - 'Regeneration Rate' : 'N RAT', - 'Recovery Rate' : 'Y RA', - 'Endurance Consumption' : 'SU', - 'ToHit Bonus' : 'T B', - 'Accuracy Bonus' : 'CC', - 'Last Hit Chance' : 'T C', - 'Damage Bonus' : 'DA', - 'Healing Bonus' : 'NG B', - 'Recharge Time Bonus' : 'ME B', - 'Endurance Discount' : 'CE DIS', - 'Stealth Radius (PvP)' : 'PVP', - 'Stealth Radius (PvE)' : 'PVE', - 'Perception Radius' : 'RC', - 'Range Bonus' : 'GE B', - 'Threat Level' : 'AT L', - 'Experience to Next Level' : 'XT', - 'Experience Debt' : 'XP', - 'Influence / Infamy' : 'INF', - 'Inherent' : 'NH', - }, - 'Movement Speed' : { - 'Flying Speed' : 'FL', - 'Jumping Speed' : 'PI', - 'Max Jump Height' : 'X J', - 'Run Speed' : 'RU', - }, - 'Damage Resistance' : { - 'Smashing Resistance' : 'G R', - 'Lethal Resistance' : 'L R', - 'Fire Resistance' : 'RE R', - 'Cold Resistance' : 'COLD R', - 'Energy Resistance' : 'DamageType[4]', - 'Negative Energy Resistance' : 'GY R', - 'Psyonic Resistance' : 'NIC R', - 'Toxic Resistance' : 'XIC R', - }, - 'Defense' : { - 'Base Defense' : 'BAS', - 'Ranged Defense' : 'ED', - 'Melee Defense' : 'MEL', - 'AoE Defense' : '2', - 'Smashing Defense' : '3', - 'Lethal Defense' : '4', - 'Fire Defense' : '5', - 'Cold Defense' : '6', - 'Energy Defense' : '7', - 'Negative Energy Defense' : '8', - 'Psionic Defense' : '9', - 'Toxic Defense' : '1', - }, - 'Debuff Resistance' : { - 'Regeneration Resistance' : 'ON R', - 'Recovery Resistance' : 'RY R', - 'To Hit Resistance' : 'IT R', - 'Defense Resistance' : 'NSE RES', - }, - 'Status Effect Protection' : { - 'Hold Protection' : 'D P', - 'Immobilize Protection' : 'LIZE P', - 'Stun Protection' : 'N P', - 'Sleep Protection' : 'P P', - 'Knockback Protection' : 'K P', - 'Confuse Protection' : 'SE P', - 'Terrorize Protection' : 'ZE P', - 'Repel Protection' : 'EL P', - 'Teleport Protection' : 'T P', - }, - 'Status Effect Resistance' : { - 'Hold Resistance' : 'D R', - 'Immobilize Resistance' : 'LIZE R', - 'Stun Resistance' : 'N R', - 'Sleep Resistance' : 'P R', - 'Knockback Resistance' : 'K R', - 'Confuse Resistance' : 'SE R', - 'Terrorize Resistance' : 'ZE R', - 'Placate Resistance' : 'TE R', - 'Taunt Resistance' : 'NT R', - }, - 'Miscellaneous' : { - 'Level Shift' : 'L S', - }, - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.AttributeMenu = wx.Menu() - for group, controls in self.AttributeTable.items(): - submenu = wx.Menu() - self.AttributeMenu.AppendSubMenu(submenu, group) - for cb in controls: - submenu.Append(wx.ID_ANY, cb) - - self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) - - self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) - groupSizer.Add(self.editbox) - - newButton = self.editbox.GetNewButton() - newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) - - return groupSizer - - def MakeBindString(self): - map = {} - bindstrings = [] - for _, controls in self.AttributeTable.items(): - for cb, data in controls.items(): - map[cb] = data - - for string in self.editbox.GetStrings(): - if string: - bindstrings.append(f'monitorattribute {map[string]}') - - return '$$'.join(bindstrings) - - def Serialize(self): - return { - 'attributes' : self.editbox.GetStrings() - } - - def Deserialize(self, init): - self.editbox.SetStrings(init.get('attributes', [])) - - def OnNewButton(self, evt): - evt.GetEventObject().PopupMenu(self.AttributeMenu) - - def OnMenuItem(self, evt): - menuitem = evt.EventObject.FindItemById(evt.GetId()) - existingstrings = self.editbox.GetStrings() - existingstrings.append(menuitem.GetItemLabel()) - self.editbox.SetStrings(existingstrings) - -####### Auto Power -class AutoPowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) - autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.autoPowerName = PowerPicker(dialog) - autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) - - return autoPowerSizer - - def MakeBindString(self): - return f"powexecauto {self.autoPowerName.GetLabel()}" - - def Serialize(self): - return { - 'pname' : self.autoPowerName.GetLabel(), - 'picon' : self.autoPowerName.IconFilename - } - - def Deserialize(self, init): - if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.buffDisplayMap = { - 'Status Window' : { - 'Hide Auto' : 1, - 'Hide Toggles' : 2, - 'No Blinking' : 4, - 'No Stacking' : 8, - 'Numeric Stacking' : 16, - 'Hide Buff Numbers' : 32, - 'Stop Sending Buffs' : 64, - }, - 'Group Window' : { - 'Hide Auto' : 256, - 'Hide Toggles' : 512, - 'No Blinking' : 1024, - 'No Stacking' : 2048, - 'Numeric Stacking' : 4096, - 'Hide Buff Numbers' : 8192, - 'Stop Sending Buffs' : 16384, - }, - 'Pet Window' : { - 'Hide Auto' : 65536, - 'Hide Toggles' : 131072, - 'No Blinking' : 262144, - 'No Stacking' : 524288, - 'Numeric Stacking' : 1048576, - 'Hide Buff Numbers' : 2097152, - 'Stop Sending Buffs' : 4194304, - }, - } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - for group, controls in self.buffDisplayMap.items(): - self.Groups[group] = ControlGroup(dialog, self.Page, label = group) - groupid = self.Groups[group].GetStaticBox().GetId() - for cb, data in controls.items(): - self.Groups[group].AddControl( - ctlType = 'checkbox', - ctlName = f"{groupid}_{group}_{cb}", - label = cb, - data = data, - ) - - groupSizer.Add(self.Groups[group]) - - return groupSizer - - def CalculateValue(self): - page = wx.App.Get().Main.Profile.CustomBinds - - total = 0 - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] - if checkbox.IsChecked(): - total = total + checkbox.Data - return total - - def MakeBindString(self): - return f"optionset buffsettings {self.CalculateValue()}" - - def Serialize(self): - return { 'value' : self.CalculateValue() } - - def Deserialize(self, init): - value = init.get('value', 0) - - value = value or 0 # in case we had for some reason 'None' stashed in the init values - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] - checkbox.SetValue( checkbox.Data & value ) - -####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - chatCommandSizer = wx.GridBagSizer(5, 5) - self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") - chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) - # row 1 - self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) - self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) - self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) - # row 2 - self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) - self.chatCommandDuration.SetRange(1, 20) - self.chatCommandDuration.SetValue(7) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandDuration, (2,1)) - self.chatCommandChatSize = wx.Choice(dialog, -1, - choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) - self.chatCommandChatSize.SetSelection(5) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) - self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) - self.chatCommandChannel.SetSelection(0) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChannel, (2,5)) - # row 3 - self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") - chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) - self.chatCommandMessage = wx.TextCtrl(dialog, -1) - self.chatCommandMessage.SetHint('Chat Command Text') - chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) - - return chatCommandSizer - - def MakeBindString(self): - duration = self.chatCommandDuration.GetValue() - - choice = self.chatCommandChatSize - index = choice.GetSelection() - size = choice.GetString(index) - - duration = f"" if duration != 7 else "" - size = f"" if size != "1" else "" - - bdcolor = fgcolor = bgcolor = '' - if self.chatCommandUseColorsCB.IsChecked(): - bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - - bdcolor = f"" - fgcolor = f"" - bgcolor = f"" - - beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' - text = self.chatCommandMessage.GetValue() - - choice = self.chatCommandChannel - index = choice.GetSelection() - channel = choice.GetString(index) - - return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" - - def Serialize(self): - return { - 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), - 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), - 'channel' : self.chatCommandChannel .GetSelection(), - 'size' : self.chatCommandChatSize.GetSelection(), - 'duration' : self.chatCommandDuration.GetValue(), - 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'text' : self.chatCommandMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) - if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) - if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) - if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) - if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) - if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) - if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) - if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) - if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - - -####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): - def BuildUI(self, dialog): - chatCommandGlobalSizer = wx.GridBagSizer(5,5) - - self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") - chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) - - self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalChannel.SetHint("Channel") - chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) - - self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') - chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) - - chatCommandGlobalSizer.AddGrowableCol(1) - - return chatCommandGlobalSizer - - def MakeBindString(self): - useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() - channel = self.chatCommandGlobalChannel.GetValue() - message = self.chatCommandGlobalMessage.GetValue() - - preface = "beginchat /" if useBeginchat else "" - - return f'{preface}send "{channel}" {message}' - - def Serialize(self): - return { - 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), - 'channel' : self.chatCommandGlobalChannel.GetValue(), - 'message' : self.chatCommandGlobalMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) - if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) - if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) - -#######Costume Change -class CostumeChangeCmd(PowerBindCmd): - def BuildUI(self, dialog): - costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeCostume = wx.Choice(dialog, -1, - choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) - self.costumeChangeCostume.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeEmote = wx.Choice(dialog, -1, - choices = GameData.Emotes['costumechange']) - self.costumeChangeEmote.Insert("- None -", 0) - self.costumeChangeEmote.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return costumeChangeSizer - - def MakeBindString(self): - costumeNumber = self.costumeChangeCostume.GetSelection() - costumeEmote = self.costumeChangeEmote.GetSelection() - - if costumeEmote: # None, or 0 == "- None -" - ccCmd = 'cce' - emoteName = self.costumeChangeEmote.GetString(costumeEmote) - emoteName = " CC" + emoteName.replace(" ","") - else: - ccCmd = 'cc' - emoteName = '' - - return f"{ccCmd} {costumeNumber}{emoteName}" - - def Serialize(self): - return{ - 'costumeNumber': self.costumeChangeCostume.GetSelection(), - 'costumeEmote' : self.costumeChangeEmote.GetSelection(), - } - - def Deserialize(self, init): - if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) - if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) - -####### Movement Command -class MovementCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - self.plusbutton.SetValue(True) - - self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.commandchoice = wx.Choice(dialog, choices = [ - "forward", "left", "right", "backward", "up", "down", - "turnleft", "turnright", "first", "autorun", "clicktomove", - ],) - sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) - self.commandchoice.SetSelection(0) - - self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - pre = post = '' - if self.plusbutton.GetValue() : pre = "+" - elif self.plusplusbutton.GetValue() : pre = "++" - elif self.minusbutton.GetValue() : pre = "-" - elif self.zerobutton.GetValue() : post = " 0" - elif self.onebutton.GetValue() : post = " 1" - - command = self.commandchoice.GetString(self.commandchoice.GetSelection()) - - return f"{pre}{command}{post}" - - def Serialize(self): - mod = '' - if self.plusbutton.GetValue() : mod = "plus" - elif self.plusplusbutton.GetValue() : mod = "plusplus" - elif self.minusbutton.GetValue() : mod = "minus" - elif self.zerobutton.GetValue() : mod = "zero" - elif self.onebutton.GetValue() : mod = "one" - - return { - 'mod' : mod, - 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), - } - - def Deserialize(self, init): - mod = init.get('mod', 'plus') - - if mod == 'plus' : self.plusbutton.SetValue(True) - elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) - elif mod == 'minus' : self.minusbutton.SetValue(True) - elif mod == 'zero' : self.zerobutton.SetValue(True) - elif mod == 'one' : self.onebutton.SetValue(True) - - self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) - -####### Graphics Command -class GraphicsCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.FlexGridSizer(2) - - self.visscalecb = wx.CheckBox(dialog, label = "visscale") - sizer.Add(self.visscalecb) - self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) - sizer.Add(self.visscalesc) - - self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") - sizer.Add(self.dofweightcb) - self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) - sizer.Add(self.dofweightsc) - - self.fsaacb = wx.CheckBox(dialog, label = "fsaa") - sizer.Add(self.fsaacb) - self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) - self.fsaach.SetSelection(0) - sizer.Add(self.fsaach) - - self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") - sizer.Add(self.bloomscalecb) - self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) - self.bloomscalech.SetSelection(0) - sizer.Add(self.bloomscalech) - - self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") - sizer.Add(self.bloomweightcb) - self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) - sizer.Add(self.bloomweightsc) - - self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") - sizer.Add(self.lodbiascb) - self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) - sizer.Add(self.lodbiassc) - - self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") - sizer.Add(self.renderscalecb) - self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) - sizer.Add(self.renderscalesc) - - return sizer - - def MakeBindString(self): - # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. - bindstrings = [] - if self.visscalecb.IsChecked(): - bindstrings.append("visscale " + str(self.visscalesc.GetValue())) - if self.dofweightcb.IsChecked(): - bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) - if self.fsaacb.IsChecked(): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bindstrings.append("fsaa " + fsaavalue) - if self.bloomscalecb.IsChecked(): - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - bindstrings.append("bloomscale " + bloomscalevalue) - if self.bloomweightcb.IsChecked(): - bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) - if self.lodbiascb.IsChecked(): - bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) - if self.renderscalecb.IsChecked(): - bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) - - return '$$'.join(bindstrings) - - def Serialize(self): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - return { - 'visscalecb' : self.visscalecb.IsChecked(), - 'visscalesc' : self.visscalesc.GetValue(), - 'dofweightcb' : self.dofweightcb.IsChecked(), - 'dofweightsc' : self.dofweightsc.GetValue(), - 'fsaacb' : self.fsaacb.IsChecked(), - 'fsaach' : fsaavalue, - 'bloomscalecb' : self.bloomscalecb.IsChecked(), - 'bloomscalech' : bloomscalevalue, - 'bloomweightcb' : self.bloomweightcb.IsChecked(), - 'bloomweightsc' : self.bloomweightsc.GetValue(), - 'lodbiascb' : self.lodbiascb.IsChecked(), - 'lodbiassc' : self.lodbiassc.GetValue(), - 'renderscalecb' : self.renderscalecb.IsChecked(), - 'renderscalesc' : self.renderscalesc.GetValue(), - } - - def Deserialize(self, init): - self.visscalecb.SetValue(init.get('visscalecb', False)) - self.visscalesc.SetValue(init.get('visscalesc', 1.0)) - self.dofweightcb.SetValue(init.get('dofweightcb', False)) - self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) - self.fsaacb.SetValue(init.get('fsaacb', False)) - self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) - self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) - self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) - self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) - self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) - self.lodbiascb.SetValue(init.get('lodbiascb', False)) - self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) - self.renderscalecb.SetValue(init.get('renderscalecb', False)) - self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) - -####### Custom Bind -class CustomBindCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.customBindName = wx.TextCtrl(dialog, -1) - self.customBindName.SetHint('Custom Bind Text') - sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - return self.customBindName.GetValue() - - def Serialize(self): - return { 'customBindName': self.customBindName.GetValue() } - - def Deserialize(self,init): - if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) - -####### Emote -class EmoteCmd(PowerBindCmd): - def BuildUI(self, dialog): - emoteSizer = wx.BoxSizer(wx.HORIZONTAL) - self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") - emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - self.emoteName = wx.Button(dialog, -1, "...") - self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) - emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) - - return emoteSizer - - def MakeBindString(self): - displayedEmoteName = self.emoteName.GetLabel() - actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] - - return actualEmotePayload - - def Serialize(self): - return {'emoteName': self.emoteName.GetLabel()} - - def Deserialize(self, init): - if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) - -####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): - def BuildUI(self, dialog): - mainSizer = wx.BoxSizer(wx.VERTICAL) - - lbSizer = wx.BoxSizer(wx.HORIZONTAL) - lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") - lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - profiles = Profile.GetAllProfileBindsDirs() - - self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) - lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) - - mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") - self.lbResetCB.SetValue(True) - - mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - return mainSizer - - def MakeBindString(self): - - # If the specified binds directory disappeared between runs, we'd crash, so handle that. - if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' - - config = wx.ConfigBase.Get() - if config.Exists('GameBindPath'): - bindpath = config.Read('GameBindPath') - else: - bindpath = config.Read('BindPath') - - reset = "" - if self.lbResetCB.GetValue(): - reset = "keybind_reset$$" - - resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' - return reset + 'bindloadfile ' + str(resetfilepath) - - def Serialize(self): - return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), - 'ResetKeybinds' : self.lbResetCB.GetValue(), - } - - def Deserialize(self, init): - if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) - self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) - -####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' - -####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' - -####### SG Mode -class SGModeCmd(PowerBindCmd): - def BuildUI(self, dialog): - sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) - sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") - self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") - - sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) - - return sgmodeSizer - - def MakeBindString(self): - if self.sgmodeOnRB.GetValue(): - return 'sgmodeset 1' - elif self.sgmodeOffRB.GetValue(): - return 'sgmodeset 0' - else: - return 'sgmode' - - def Serialize(self): - if self.sgmodeOnRB.GetValue(): - val = "On" - elif self.sgmodeOffRB.GetValue(): - val = "Off" - else: - val = "Toggle" - - return {"value" : val} - - def Deserialize(self, init): - val = init.get('value', '') - if val == "On": - self.sgmodeOnRB.SetValue(True) - elif val == "Off": - self.sgmodeOffRB.SetValue(True) - else: - self.sgmodeToggleRB.SetValue(True) - -####### Target Custom -class TargetCustomCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetCustomSizer = wx.GridBagSizer(5,5) - targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), - flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) - self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetCustomModeChoice.SetSelection(0) - targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) - self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) - self.targetCustomOptionalName.SetHint("Optional name to match") - targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) - self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") - targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) - self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") - targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) - self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") - targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) - self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") - targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) - self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") - targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) - self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") - targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) - self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") - targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) - self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") - targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) - - targetCustomSizer.AddGrowableCol(2) - - return targetCustomSizer - - def MakeBindString(self): - choice = self.targetCustomModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - targetCommand = "targetcustom" + mode.lower() - - enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" - friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" - defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" - alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" - mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" - notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" - base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" - notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" - - name = self.targetCustomOptionalName.GetValue() - - return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" - - def Serialize(self): - return { - 'mode' : self.targetCustomModeChoice.GetSelection(), - 'enemy' : self.targetCustomCBEnemies. IsChecked(), - 'friend' : self.targetCustomCBFriends. IsChecked(), - 'defeated' : self.targetCustomCBDefeated. IsChecked(), - 'alive' : self.targetCustomCBAlive. IsChecked(), - 'mypet' : self.targetCustomCBMyPets. IsChecked(), - 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), - 'base' : self.targetCustomCBBaseItems. IsChecked(), - 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), - 'name' : self.targetCustomOptionalName.GetValue(), - } - - def Deserialize(self, init): - if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) - if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) - if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) - if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) - if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) - if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) - if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) - if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) - if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) - if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - - -####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) - targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetEnemyModeChoice.SetSelection(0) - targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetEnemySizer - - def MakeBindString(self): - choice = self.targetEnemyModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetenemy" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetEnemyModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) - -####### Target Friend -class TargetFriendCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) - targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetFriendModeChoice.SetSelection(0) - targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetFriendSizer - - def MakeBindString(self): - choice = self.targetFriendModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetfriend" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetFriendModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) - -####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): - def BuildUI(self, dialog): - teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], - style=wx.ALIGN_CENTER_VERTICAL) - self.teamPetSelectNumber.SetSelection(0) - teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) - - return teamPetSelectSizer - - def MakeBindString(self): - teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' - targetNumber = self.teamPetSelectNumber.GetSelection()+1 - - return f"{teamOrPet}select {targetNumber}" - - def Serialize(self): - return { - 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', - 'targetNum': self.teamPetSelectNumber.GetSelection(), - } - - def Deserialize(self, init): - ToP = init.get('teamOrPet', '') - if ToP == 'pet': - self.teamPetSelectPetRB.SetValue(True) - else: - self.teamPetSelectTeamRB.SetValue(True) - if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) - -####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' - -####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) - for _, types in GameData.Inspirations.items(): - for _, info in types.items(): - for insp in info['tiers']: - name = re.sub(' ', '', str(insp)) - icon = GetIcon(f'Inspirations/{name}') - self.useInspByNameModeChoice.Append(insp, icon) - self.useInspByNameModeChoice.SetSelection(0) - useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) - - return useInspByNameSizer - - def MakeBindString(self): - choice = self.useInspByNameModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "inspexecname " + mode.lower() - - def GetAllInsps(self): - Insplist = [] - for _, info in GameData.Inspirations.items(): - for insp in info['tiers']: - Insplist.append(insp) - Insplist.append("---") - Insplist.pop(-1) # snip the terminal "---" - - return Insplist - - def Serialize(self): - return { 'insp' : self.useInspByNameModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) - -####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnRow.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) - self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnCol.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) - - return useInspRowColumnSizer - - def MakeBindString(self): - row = self.useInspRowColumnRow.GetSelection()+1 - col = self.useInspRowColumnCol.GetSelection()+1 - - return f"inspexectray {col} {row}" - - def Serialize(self): - return { - 'col' : self.useInspRowColumnCol.GetSelection(), - 'row' : self.useInspRowColumnRow.GetSelection(), - } - - def Deserialize(self, init): - if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) - if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) +from UI.PowerBinderCommand import PowerBinderCommand ####### Use Power -class UsePowerCmd(PowerBindCmd): +class UsePowerCmd(PowerBinderCommand): + Name = "Use Power" + Menu = "Powers" + def BuildUI(self, dialog): outerSizer = wx.BoxSizer(wx.HORIZONTAL) @@ -1406,395 +64,3 @@ def Deserialize(self, init): self.usePowerRBToggle.SetValue(True) if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) - -####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): - def BuildUI(self, dialog): - usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTrayTray = wx.Choice(dialog, -1, - choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', - 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) - self.usePowerFromTrayTray.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) - self.usePowerFromTraySlot.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return usePowerFromTraySizer - - def MakeBindString(self): - choice = self.usePowerFromTrayTray - tray = choice.GetSelection() - - choice = self.usePowerFromTraySlot - slot = choice.GetSelection()+1 - - mode = "slot" - mode2 = '' - if tray > 3: - mode = "tray" - mode2 = f" {tray - 3}" - elif tray == 3: - mode = "alt2slot" - elif tray == 2: - mode = "altslot" - - return f"powexec{mode} {slot}{mode2}" - - def Serialize(self): - return { - 'tray' : self.usePowerFromTrayTray.GetSelection(), - 'slot' : self.usePowerFromTraySlot.GetSelection(), - } - - def Deserialize(self, init): - if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) - if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) - -####### Window Color -class WindowColorCmd(PowerBindCmd): - def BuildUI(self, dialog): - windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) - borderSizer = wx.BoxSizer(wx.VERTICAL) - self.ColorBorder.SetSizer(borderSizer) - self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) - borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) - - windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) - - RGBASizer = wx.FlexGridSizer(3, 4, 5) - - RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) - self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) - self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - windowColorSizer.Add(RGBASizer) - - self.UpdateFromSlider() - - return windowColorSizer - - def MakeBindString(self): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - return f"windowcolor {Rval} {Gval} {Bval} {Aval}" - - def Serialize(self): - return { - 'Rval' : self.RSlider.GetValue(), - 'Gval' : self.GSlider.GetValue(), - 'Bval' : self.BSlider.GetValue(), - 'Aval' : self.ASlider.GetValue(), - } - - def Deserialize(self, init): - self.RSlider.SetValue(init['Rval']) - self.GSlider.SetValue(init['Gval']) - self.BSlider.SetValue(init['Bval']) - self.ASlider.SetValue(init['Aval']) - self.UpdateFromSlider() - - def UpdateFromSlider(self, _ = None): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RReadout.SetValue(Rval) - self.GReadout.SetValue(Gval) - self.BReadout.SetValue(Bval) - self.AReadout.SetValue(Aval) - self.ColorBorder.Refresh() - - def UpdateFromText(self, _ = None): - Rval = self.RReadout.GetValue() - Gval = self.GReadout.GetValue() - Bval = self.BReadout.GetValue() - Aval = self.AReadout.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RSlider.SetValue(Rval) - self.GSlider.SetValue(Gval) - self.BSlider.SetValue(Bval) - self.ASlider.SetValue(Aval) - self.ColorBorder.Refresh() - -####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) - self.CommandChoice.SetSelection(0) - sizer.Add(self.CommandChoice, 0, wx.ALL, 5) - - self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), - value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) - sizer.Add(self.FilePath, 0, wx.ALL, 5) - - return sizer - - def MakeBindString(self): - command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] - return f'{command} "{self.FilePath.GetValue()}"' - - def Serialize(self): - return { - 'command' : self.CommandChoice.GetSelection(), - 'filename' : self.FilePath.GetValue(), - } - - def Deserialize(self, init): - self.CommandChoice.SetSelection(init.get('command', 0)) - self.FilePath.SetValue(init.get('filename', '')) - -####### Window Toggle -class WindowToggleCmd(PowerBindCmd): - def BuildUI(self, dialog): - self.WindowNames = { - 'Actions' : 'actions', - 'Auction House' : 'ah', - 'Badge' : 'badge', - 'Channel Search' : 'chansearch', - 'Chat' : 'chat', - 'Custom Chat 1' : 'chat1', - 'Custom Chat 2' : 'chat2', - 'Custom Chat 3' : 'chat3', - 'Custom Chat 4' : 'chat4', - 'Clues' : 'clue', - 'Combat Numbers' : 'combatnumbers', - 'Contacts' : 'contact', - 'Contact Finder' : 'contactfinder', - 'Costumes' : 'costume', - 'Email' : 'email', - 'Enhancements' : 'enhancements', - 'Friends' : 'friend', - 'Group' : 'group', - 'Help' : 'helpwindow', - 'Incarnate' : 'incarnate', - 'Inspirations' : 'insp', - 'League' : 'league', - 'LFG' : 'lfg', - 'Map' : 'map', - 'Mission' : 'mission', - 'Nav / Compass' : 'nav', - 'Options' : 'options', - 'Pets' : 'pet', - 'Petition' : 'petition', - 'Power Tray' : 'powers', - 'Power List' : 'powerlist', - 'Quit' : 'quit', - 'Recipes' : 'recipe', - 'Salvage' : 'salvage', - 'Search' : 'search', - 'Supergroup' : 'sg', - 'Target' : 'target', - 'Team' : 'team', - 'Tray' : 'tray', - 'Tray1' : 'tray1', - 'Tray2' : 'tray2', - 'Tray3' : 'tray3', - 'Tray4' : 'tray4', - 'Tray5' : 'tray5', - 'Tray6' : 'tray6', - 'Tray7' : 'tray7', - 'Tray8' : 'tray8', - 'Vault' : 'vault', - } - - self.ShortToggleCommands = { - 'Auction House' : 'ah', - 'Chat' : 'chat', - 'Help' : 'helpwindow', - 'Map' : 'map', - 'Nav / Compass' : 'nav', - 'Power Tray' : 'powers', - 'Target' : 'target', - 'Tray' : 'tray', - } - - windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) - windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) - self.windowToggleTray.SetSelection(0) - windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.windowShowRB = wx.RadioButton(dialog, -1, "Show") - self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") - - windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) - - return windowToggleSizer - - def MakeBindString(self): - choice = self.windowToggleTray - index = choice.GetSelection() - windowdesc = choice.GetString(index) - windowname = self.WindowNames[windowdesc] - - if self.windowShowRB.GetValue(): - return 'show ' + windowname - elif self.windowHideRB.GetValue(): - return 'windowhide ' + windowname - else: - if shortcmd := self.ShortToggleCommands.get(windowdesc, None): - return shortcmd - else: - return 'toggle ' + windowname - - - def Serialize(self): - choice = self.windowToggleTray - if self.windowShowRB.GetValue(): - action = "Show" - elif self.windowHideRB.GetValue(): - action = "Hide" - else: - action = "Toggle" - return { - 'window': choice.GetString(choice.GetSelection()), - 'action': action, - } - - def Deserialize(self, init): - choice = self.windowToggleTray - if window := init.get('window', ''): - if isinstance(window, int): - choice.SetSelection(window) - else: - choice.SetSelection(choice.FindString(window)) - - if choice.GetSelection() == wx.NOT_FOUND: - choice.SetSelection(0) - - action = init.get('action', '') - if action == "Show": - self.windowShowRB.SetValue(True) - elif action == "Hide": - self.windowHideRB.SetValue(True) - else: - self.windowToggleRB.SetValue(True) - - -# Must always add to this list when adding a new command class above -menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], - # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, - # but I'm leaving it here to remind myself that we do that. - } - -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/UsePowerFromTrayCmd.py b/UI/PowerBinderCommand/UsePowerFromTrayCmd.py index 4c02ab7..69c749c 100644 --- a/UI/PowerBinderCommand/UsePowerFromTrayCmd.py +++ b/UI/PowerBinderCommand/UsePowerFromTrayCmd.py @@ -1,1414 +1,11 @@ import wx -import re -import UI -import UI.EmotePicker -from UI.ControlGroup import ControlGroup -from UI.PowerPicker import PowerPicker -from Help import HelpButton -import wx.adv -from wx.adv import BitmapComboBox, EditableListBox -from pathlib import PureWindowsPath -import GameData -import Profile -from Icon import GetIcon - -class PowerBinderDialog(wx.Dialog): - def __init__(self, parent, button, init = {}): - wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) - - self.Page = parent.Page - self.EditDialog = PowerBinderEditDialog(self) - self.Button = button - self.AddStepMenu = self.makeAddStepMenu() - - sizer = wx.BoxSizer(wx.VERTICAL); - self.mainSizer = sizer - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) - AddStepButton = wx.Button(self, -1, 'Add Step') - AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) - AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) - choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) - choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) - sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) - - rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) - - self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) - self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) - self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) - rearrangeCtrl.Add(self.RearrangeList, 1) - - rearrangeButtons = wx.BoxSizer(wx.VERTICAL) - self.DelButton = wx.Button(self, -1, "Delete") - self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) - self.EditButton = wx.Button(self, -1, "Edit") - self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) - self.EditButton.Disable() - upButton = wx.Button(self, -1, "\u25B2") - upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) - downButton = wx.Button(self, -1, "\u25BC") - downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) - rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) - rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) - - sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.BindStringDisplay = wx.TextCtrl(self, -1) - self.BindStringDisplay.Disable() - choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, - wx.ALIGN_CENTER_VERTICAL) - choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) - - sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) - - sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) - - # need to dig around and get the OK button since we show this dialog modelessly now. - okButton = self.FindWindow(self.GetAffirmativeId()) - okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) - - # Wrap everything in a vbox to add some padding - vbox = wx.BoxSizer(wx.VERTICAL); - vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); - - self.SetSizerAndFit(vbox); - self.Layout() - self.Fit() - self.SetFocus() - - # if we are loading from profile, ie, have "init", build the list from it - if init: self.LoadFromData(init) - - def LoadFromData(self, init): - for item in init: - for type, data in item.items(): - commandClass = commandClasses.get(type, None) - if not commandClass: - commandClass = deprecatedCommandClasses.get(type, None) - if not commandClass: - wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") - continue - newCommand = commandClass(self.EditDialog, data) - index = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.SetClientData(index, newCommand) - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) - self.EditDialog.mainSizer.Hide(newCommand.UI) - self.UpdateBindStringDisplay() - - def SaveToData(self): - data = [] - index = 0 - for _ in self.RearrangeList.GetItems(): - # check whether we have an object already attached to this choice - cmdObject = self.RearrangeList.GetClientData(index) - commandClassName = commandRevClasses[type(cmdObject)] - data.append({commandClassName: cmdObject.Serialize()}) - index = index + 1 - return data - - def OnAddStepButton(self, evt): - button = evt.EventObject - if not self.AddStepMenu: - self.AddStepMenu = self.makeAddStepMenu() - button.PopupMenu(self.AddStepMenu) - - - def OnOKButton(self, _): - if self.Button.tgtTxtCtrl: - bindString = self.MakeBindString() - if bindString != self.Button.tgtTxtCtrl.GetValue(): - self.Button.tgtTxtCtrl.SetValue(bindString) - wx.App.Get().Main.Profile.SetModified() - self.Close() - - def OnRearrangeDelete(self, _): - current = self.RearrangeList.GetSelection() - if current == wx.NOT_FOUND: return - - self.RearrangeList.Delete(current) - self.UpdateBindStringDisplay() - - def OnRearrangeUp(self, _): - self.RearrangeList.MoveCurrentUp() - self.UpdateBindStringDisplay() - - def OnRearrangeDown(self, _): - self.RearrangeList.MoveCurrentDown() - self.UpdateBindStringDisplay() - - def OnRearrangeEdit(self, _): - index = self.RearrangeList.GetSelection() - - # check whether we have an object already attached to this choice - cmdObject = None - try: - cmdObject = self.RearrangeList.GetClientData(index) - except Exception: - pass - - if cmdObject: - self.ShowEditDialogFor(cmdObject) - self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) - else: - print("cmdObject was None") - self.UpdateBindStringDisplay() - - # OnAddStepMenu creates a new step and adds it to the rearrangelist - def OnAddStepMenu(self, evt): - menuitem = self.AddStepMenu.FindItemById(evt.GetId()) - chosenName = menuitem.GetItemLabel() - - # make a new command object, attached to the parent dialog - newCommandClass = commandClasses[chosenName] - newCommand = newCommandClass(self.EditDialog) - - # show the edit dialog if this command needs it - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) - if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): - self.EditDialog.mainSizer.Remove(newCommand.UI) - return - - newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.Select(newBindIndex) - self.RearrangeList.SetClientData(newBindIndex, newCommand) - - self.OnListSelect() - self.UpdateBindStringDisplay() - - def OnListSelect(self, _ = None): - selected = self.RearrangeList.GetSelection() - - if selected != wx.NOT_FOUND: - selCommand = self.RearrangeList.GetClientData(selected) - if selCommand.UI: - self.EditButton.Enable() - else: - self.EditButton.Disable() - - def UpdateBindStringDisplay(self): - self.BindStringDisplay.SetValue(self.MakeBindString()) - self.BindStringDisplay.SetToolTip(self.MakeBindString()) - - def MakeBindString(self): - cmdBindStrings = [] - for index in range(self.RearrangeList.GetCount()): - c = self.RearrangeList.GetClientData(index) - if c: cmdBindStrings.append(c.MakeBindString()) - - bindstring = ('$$'.join(cmdBindStrings)) - return bindstring - - def ShowEditDialogFor(self, command): - if not command.UI: return - - self.EditDialog.mainSizer.Show(command.UI) - - self.EditDialog.Layout() - self.EditDialog.Fit() - - self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') - returnval = self.EditDialog.ShowModal() - - self.EditDialog.mainSizer.Hide(command.UI) - - return returnval - - def makeAddStepMenu(self): - - stepMenu = wx.Menu() - - for subname in menuStructure: - submenu = wx.Menu() - stepMenu.AppendSubMenu(submenu, subname) - for classname in menuStructure[subname]: - submenu.Append(wx.ID_ANY, classname) - - stepMenu.Append(wx.ID_ANY, 'Custom Bind') - - return stepMenu - -class PowerBinderButton(wx.BitmapButton): - - def __init__(self, parent, tgtTxtCtrl, init = {}): - wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) - self.Init = init - self.Dialog = None - self.DialogParent = parent - - self.tgtTxtCtrl = tgtTxtCtrl - self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) - self.SetToolTip("Launch PowerBinder") - - def PowerBinderEventHandler(self, _): - self.PowerBinderDialog().Show() - - def LoadFromData(self, data): - self.PowerBinderDialog().LoadFromData(data) - - def SaveToData(self): - return self.PowerBinderDialog().SaveToData() - - def PowerBinderDialog(self): - if not self.Dialog: - self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) - return self.Dialog - - -class PowerBinderEditDialog(wx.Dialog): - def __init__(self, parent): - wx.Dialog.__init__(self, parent, -1, "Edit Step", - style = wx.DEFAULT_DIALOG_STYLE) - - outerSizer = wx.BoxSizer(wx.VERTICAL) - - self.mainSizer = wx.BoxSizer(wx.VERTICAL) - self.mainSizer.SetMinSize([500, 150]) - - self.Page = parent.Page - - self.mainSizer.Add( - self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), - 0, wx.EXPAND|wx.ALL, 10) - - outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) - - self.SetSizerAndFit(outerSizer) - self.Layout() - self.Fit() - -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" - - -####### Away From Keyboard -class AFKCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.Groups = {} - self.AttributeTable = { - 'Base' : { - 'Current Hit Points' : 'NT H', - 'Max Hit Points' : 'X H', - 'Current Endurance' : 'T E', - 'Max Endurance' : 'X EN', - 'Regeneration Rate' : 'N RAT', - 'Recovery Rate' : 'Y RA', - 'Endurance Consumption' : 'SU', - 'ToHit Bonus' : 'T B', - 'Accuracy Bonus' : 'CC', - 'Last Hit Chance' : 'T C', - 'Damage Bonus' : 'DA', - 'Healing Bonus' : 'NG B', - 'Recharge Time Bonus' : 'ME B', - 'Endurance Discount' : 'CE DIS', - 'Stealth Radius (PvP)' : 'PVP', - 'Stealth Radius (PvE)' : 'PVE', - 'Perception Radius' : 'RC', - 'Range Bonus' : 'GE B', - 'Threat Level' : 'AT L', - 'Experience to Next Level' : 'XT', - 'Experience Debt' : 'XP', - 'Influence / Infamy' : 'INF', - 'Inherent' : 'NH', - }, - 'Movement Speed' : { - 'Flying Speed' : 'FL', - 'Jumping Speed' : 'PI', - 'Max Jump Height' : 'X J', - 'Run Speed' : 'RU', - }, - 'Damage Resistance' : { - 'Smashing Resistance' : 'G R', - 'Lethal Resistance' : 'L R', - 'Fire Resistance' : 'RE R', - 'Cold Resistance' : 'COLD R', - 'Energy Resistance' : 'DamageType[4]', - 'Negative Energy Resistance' : 'GY R', - 'Psyonic Resistance' : 'NIC R', - 'Toxic Resistance' : 'XIC R', - }, - 'Defense' : { - 'Base Defense' : 'BAS', - 'Ranged Defense' : 'ED', - 'Melee Defense' : 'MEL', - 'AoE Defense' : '2', - 'Smashing Defense' : '3', - 'Lethal Defense' : '4', - 'Fire Defense' : '5', - 'Cold Defense' : '6', - 'Energy Defense' : '7', - 'Negative Energy Defense' : '8', - 'Psionic Defense' : '9', - 'Toxic Defense' : '1', - }, - 'Debuff Resistance' : { - 'Regeneration Resistance' : 'ON R', - 'Recovery Resistance' : 'RY R', - 'To Hit Resistance' : 'IT R', - 'Defense Resistance' : 'NSE RES', - }, - 'Status Effect Protection' : { - 'Hold Protection' : 'D P', - 'Immobilize Protection' : 'LIZE P', - 'Stun Protection' : 'N P', - 'Sleep Protection' : 'P P', - 'Knockback Protection' : 'K P', - 'Confuse Protection' : 'SE P', - 'Terrorize Protection' : 'ZE P', - 'Repel Protection' : 'EL P', - 'Teleport Protection' : 'T P', - }, - 'Status Effect Resistance' : { - 'Hold Resistance' : 'D R', - 'Immobilize Resistance' : 'LIZE R', - 'Stun Resistance' : 'N R', - 'Sleep Resistance' : 'P R', - 'Knockback Resistance' : 'K R', - 'Confuse Resistance' : 'SE R', - 'Terrorize Resistance' : 'ZE R', - 'Placate Resistance' : 'TE R', - 'Taunt Resistance' : 'NT R', - }, - 'Miscellaneous' : { - 'Level Shift' : 'L S', - }, - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.AttributeMenu = wx.Menu() - for group, controls in self.AttributeTable.items(): - submenu = wx.Menu() - self.AttributeMenu.AppendSubMenu(submenu, group) - for cb in controls: - submenu.Append(wx.ID_ANY, cb) - - self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) - - self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) - groupSizer.Add(self.editbox) - - newButton = self.editbox.GetNewButton() - newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) - - return groupSizer - - def MakeBindString(self): - map = {} - bindstrings = [] - for _, controls in self.AttributeTable.items(): - for cb, data in controls.items(): - map[cb] = data - - for string in self.editbox.GetStrings(): - if string: - bindstrings.append(f'monitorattribute {map[string]}') - - return '$$'.join(bindstrings) - - def Serialize(self): - return { - 'attributes' : self.editbox.GetStrings() - } - - def Deserialize(self, init): - self.editbox.SetStrings(init.get('attributes', [])) - - def OnNewButton(self, evt): - evt.GetEventObject().PopupMenu(self.AttributeMenu) - - def OnMenuItem(self, evt): - menuitem = evt.EventObject.FindItemById(evt.GetId()) - existingstrings = self.editbox.GetStrings() - existingstrings.append(menuitem.GetItemLabel()) - self.editbox.SetStrings(existingstrings) - -####### Auto Power -class AutoPowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) - autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.autoPowerName = PowerPicker(dialog) - autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) - - return autoPowerSizer - - def MakeBindString(self): - return f"powexecauto {self.autoPowerName.GetLabel()}" - - def Serialize(self): - return { - 'pname' : self.autoPowerName.GetLabel(), - 'picon' : self.autoPowerName.IconFilename - } - - def Deserialize(self, init): - if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.buffDisplayMap = { - 'Status Window' : { - 'Hide Auto' : 1, - 'Hide Toggles' : 2, - 'No Blinking' : 4, - 'No Stacking' : 8, - 'Numeric Stacking' : 16, - 'Hide Buff Numbers' : 32, - 'Stop Sending Buffs' : 64, - }, - 'Group Window' : { - 'Hide Auto' : 256, - 'Hide Toggles' : 512, - 'No Blinking' : 1024, - 'No Stacking' : 2048, - 'Numeric Stacking' : 4096, - 'Hide Buff Numbers' : 8192, - 'Stop Sending Buffs' : 16384, - }, - 'Pet Window' : { - 'Hide Auto' : 65536, - 'Hide Toggles' : 131072, - 'No Blinking' : 262144, - 'No Stacking' : 524288, - 'Numeric Stacking' : 1048576, - 'Hide Buff Numbers' : 2097152, - 'Stop Sending Buffs' : 4194304, - }, - } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - for group, controls in self.buffDisplayMap.items(): - self.Groups[group] = ControlGroup(dialog, self.Page, label = group) - groupid = self.Groups[group].GetStaticBox().GetId() - for cb, data in controls.items(): - self.Groups[group].AddControl( - ctlType = 'checkbox', - ctlName = f"{groupid}_{group}_{cb}", - label = cb, - data = data, - ) - - groupSizer.Add(self.Groups[group]) - - return groupSizer - - def CalculateValue(self): - page = wx.App.Get().Main.Profile.CustomBinds - - total = 0 - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] - if checkbox.IsChecked(): - total = total + checkbox.Data - return total - - def MakeBindString(self): - return f"optionset buffsettings {self.CalculateValue()}" - - def Serialize(self): - return { 'value' : self.CalculateValue() } - - def Deserialize(self, init): - value = init.get('value', 0) - - value = value or 0 # in case we had for some reason 'None' stashed in the init values - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] - checkbox.SetValue( checkbox.Data & value ) - -####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - chatCommandSizer = wx.GridBagSizer(5, 5) - self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") - chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) - # row 1 - self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) - self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) - self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) - # row 2 - self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) - self.chatCommandDuration.SetRange(1, 20) - self.chatCommandDuration.SetValue(7) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandDuration, (2,1)) - self.chatCommandChatSize = wx.Choice(dialog, -1, - choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) - self.chatCommandChatSize.SetSelection(5) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) - self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) - self.chatCommandChannel.SetSelection(0) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChannel, (2,5)) - # row 3 - self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") - chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) - self.chatCommandMessage = wx.TextCtrl(dialog, -1) - self.chatCommandMessage.SetHint('Chat Command Text') - chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) - - return chatCommandSizer - - def MakeBindString(self): - duration = self.chatCommandDuration.GetValue() - - choice = self.chatCommandChatSize - index = choice.GetSelection() - size = choice.GetString(index) - - duration = f"" if duration != 7 else "" - size = f"" if size != "1" else "" - - bdcolor = fgcolor = bgcolor = '' - if self.chatCommandUseColorsCB.IsChecked(): - bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - - bdcolor = f"" - fgcolor = f"" - bgcolor = f"" - - beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' - text = self.chatCommandMessage.GetValue() - - choice = self.chatCommandChannel - index = choice.GetSelection() - channel = choice.GetString(index) - - return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" - - def Serialize(self): - return { - 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), - 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), - 'channel' : self.chatCommandChannel .GetSelection(), - 'size' : self.chatCommandChatSize.GetSelection(), - 'duration' : self.chatCommandDuration.GetValue(), - 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'text' : self.chatCommandMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) - if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) - if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) - if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) - if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) - if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) - if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) - if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) - if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - - -####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): - def BuildUI(self, dialog): - chatCommandGlobalSizer = wx.GridBagSizer(5,5) - - self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") - chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) - - self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalChannel.SetHint("Channel") - chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) - - self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') - chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) - - chatCommandGlobalSizer.AddGrowableCol(1) - - return chatCommandGlobalSizer - - def MakeBindString(self): - useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() - channel = self.chatCommandGlobalChannel.GetValue() - message = self.chatCommandGlobalMessage.GetValue() - - preface = "beginchat /" if useBeginchat else "" - - return f'{preface}send "{channel}" {message}' - - def Serialize(self): - return { - 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), - 'channel' : self.chatCommandGlobalChannel.GetValue(), - 'message' : self.chatCommandGlobalMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) - if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) - if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) - -#######Costume Change -class CostumeChangeCmd(PowerBindCmd): - def BuildUI(self, dialog): - costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeCostume = wx.Choice(dialog, -1, - choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) - self.costumeChangeCostume.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeEmote = wx.Choice(dialog, -1, - choices = GameData.Emotes['costumechange']) - self.costumeChangeEmote.Insert("- None -", 0) - self.costumeChangeEmote.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return costumeChangeSizer - - def MakeBindString(self): - costumeNumber = self.costumeChangeCostume.GetSelection() - costumeEmote = self.costumeChangeEmote.GetSelection() - - if costumeEmote: # None, or 0 == "- None -" - ccCmd = 'cce' - emoteName = self.costumeChangeEmote.GetString(costumeEmote) - emoteName = " CC" + emoteName.replace(" ","") - else: - ccCmd = 'cc' - emoteName = '' - - return f"{ccCmd} {costumeNumber}{emoteName}" - - def Serialize(self): - return{ - 'costumeNumber': self.costumeChangeCostume.GetSelection(), - 'costumeEmote' : self.costumeChangeEmote.GetSelection(), - } - - def Deserialize(self, init): - if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) - if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) - -####### Movement Command -class MovementCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - self.plusbutton.SetValue(True) - - self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.commandchoice = wx.Choice(dialog, choices = [ - "forward", "left", "right", "backward", "up", "down", - "turnleft", "turnright", "first", "autorun", "clicktomove", - ],) - sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) - self.commandchoice.SetSelection(0) - - self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - pre = post = '' - if self.plusbutton.GetValue() : pre = "+" - elif self.plusplusbutton.GetValue() : pre = "++" - elif self.minusbutton.GetValue() : pre = "-" - elif self.zerobutton.GetValue() : post = " 0" - elif self.onebutton.GetValue() : post = " 1" - - command = self.commandchoice.GetString(self.commandchoice.GetSelection()) - - return f"{pre}{command}{post}" - - def Serialize(self): - mod = '' - if self.plusbutton.GetValue() : mod = "plus" - elif self.plusplusbutton.GetValue() : mod = "plusplus" - elif self.minusbutton.GetValue() : mod = "minus" - elif self.zerobutton.GetValue() : mod = "zero" - elif self.onebutton.GetValue() : mod = "one" - - return { - 'mod' : mod, - 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), - } - - def Deserialize(self, init): - mod = init.get('mod', 'plus') - - if mod == 'plus' : self.plusbutton.SetValue(True) - elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) - elif mod == 'minus' : self.minusbutton.SetValue(True) - elif mod == 'zero' : self.zerobutton.SetValue(True) - elif mod == 'one' : self.onebutton.SetValue(True) - - self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) - -####### Graphics Command -class GraphicsCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.FlexGridSizer(2) - - self.visscalecb = wx.CheckBox(dialog, label = "visscale") - sizer.Add(self.visscalecb) - self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) - sizer.Add(self.visscalesc) - - self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") - sizer.Add(self.dofweightcb) - self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) - sizer.Add(self.dofweightsc) - - self.fsaacb = wx.CheckBox(dialog, label = "fsaa") - sizer.Add(self.fsaacb) - self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) - self.fsaach.SetSelection(0) - sizer.Add(self.fsaach) - - self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") - sizer.Add(self.bloomscalecb) - self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) - self.bloomscalech.SetSelection(0) - sizer.Add(self.bloomscalech) - - self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") - sizer.Add(self.bloomweightcb) - self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) - sizer.Add(self.bloomweightsc) - - self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") - sizer.Add(self.lodbiascb) - self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) - sizer.Add(self.lodbiassc) - - self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") - sizer.Add(self.renderscalecb) - self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) - sizer.Add(self.renderscalesc) - - return sizer - - def MakeBindString(self): - # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. - bindstrings = [] - if self.visscalecb.IsChecked(): - bindstrings.append("visscale " + str(self.visscalesc.GetValue())) - if self.dofweightcb.IsChecked(): - bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) - if self.fsaacb.IsChecked(): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bindstrings.append("fsaa " + fsaavalue) - if self.bloomscalecb.IsChecked(): - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - bindstrings.append("bloomscale " + bloomscalevalue) - if self.bloomweightcb.IsChecked(): - bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) - if self.lodbiascb.IsChecked(): - bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) - if self.renderscalecb.IsChecked(): - bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) - - return '$$'.join(bindstrings) - - def Serialize(self): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - return { - 'visscalecb' : self.visscalecb.IsChecked(), - 'visscalesc' : self.visscalesc.GetValue(), - 'dofweightcb' : self.dofweightcb.IsChecked(), - 'dofweightsc' : self.dofweightsc.GetValue(), - 'fsaacb' : self.fsaacb.IsChecked(), - 'fsaach' : fsaavalue, - 'bloomscalecb' : self.bloomscalecb.IsChecked(), - 'bloomscalech' : bloomscalevalue, - 'bloomweightcb' : self.bloomweightcb.IsChecked(), - 'bloomweightsc' : self.bloomweightsc.GetValue(), - 'lodbiascb' : self.lodbiascb.IsChecked(), - 'lodbiassc' : self.lodbiassc.GetValue(), - 'renderscalecb' : self.renderscalecb.IsChecked(), - 'renderscalesc' : self.renderscalesc.GetValue(), - } - - def Deserialize(self, init): - self.visscalecb.SetValue(init.get('visscalecb', False)) - self.visscalesc.SetValue(init.get('visscalesc', 1.0)) - self.dofweightcb.SetValue(init.get('dofweightcb', False)) - self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) - self.fsaacb.SetValue(init.get('fsaacb', False)) - self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) - self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) - self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) - self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) - self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) - self.lodbiascb.SetValue(init.get('lodbiascb', False)) - self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) - self.renderscalecb.SetValue(init.get('renderscalecb', False)) - self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) - -####### Custom Bind -class CustomBindCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.customBindName = wx.TextCtrl(dialog, -1) - self.customBindName.SetHint('Custom Bind Text') - sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - return self.customBindName.GetValue() - - def Serialize(self): - return { 'customBindName': self.customBindName.GetValue() } - - def Deserialize(self,init): - if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) - -####### Emote -class EmoteCmd(PowerBindCmd): - def BuildUI(self, dialog): - emoteSizer = wx.BoxSizer(wx.HORIZONTAL) - self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") - emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - self.emoteName = wx.Button(dialog, -1, "...") - self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) - emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) - - return emoteSizer - - def MakeBindString(self): - displayedEmoteName = self.emoteName.GetLabel() - actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] - - return actualEmotePayload - - def Serialize(self): - return {'emoteName': self.emoteName.GetLabel()} - - def Deserialize(self, init): - if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) - -####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): - def BuildUI(self, dialog): - mainSizer = wx.BoxSizer(wx.VERTICAL) - - lbSizer = wx.BoxSizer(wx.HORIZONTAL) - lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") - lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - profiles = Profile.GetAllProfileBindsDirs() - - self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) - lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) - - mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") - self.lbResetCB.SetValue(True) - - mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - return mainSizer - - def MakeBindString(self): - - # If the specified binds directory disappeared between runs, we'd crash, so handle that. - if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' - - config = wx.ConfigBase.Get() - if config.Exists('GameBindPath'): - bindpath = config.Read('GameBindPath') - else: - bindpath = config.Read('BindPath') - - reset = "" - if self.lbResetCB.GetValue(): - reset = "keybind_reset$$" - - resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' - return reset + 'bindloadfile ' + str(resetfilepath) - - def Serialize(self): - return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), - 'ResetKeybinds' : self.lbResetCB.GetValue(), - } - - def Deserialize(self, init): - if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) - self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) - -####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' - -####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' - -####### SG Mode -class SGModeCmd(PowerBindCmd): - def BuildUI(self, dialog): - sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) - sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") - self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") - - sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) - - return sgmodeSizer - - def MakeBindString(self): - if self.sgmodeOnRB.GetValue(): - return 'sgmodeset 1' - elif self.sgmodeOffRB.GetValue(): - return 'sgmodeset 0' - else: - return 'sgmode' - - def Serialize(self): - if self.sgmodeOnRB.GetValue(): - val = "On" - elif self.sgmodeOffRB.GetValue(): - val = "Off" - else: - val = "Toggle" - - return {"value" : val} - - def Deserialize(self, init): - val = init.get('value', '') - if val == "On": - self.sgmodeOnRB.SetValue(True) - elif val == "Off": - self.sgmodeOffRB.SetValue(True) - else: - self.sgmodeToggleRB.SetValue(True) - -####### Target Custom -class TargetCustomCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetCustomSizer = wx.GridBagSizer(5,5) - targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), - flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) - self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetCustomModeChoice.SetSelection(0) - targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) - self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) - self.targetCustomOptionalName.SetHint("Optional name to match") - targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) - self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") - targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) - self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") - targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) - self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") - targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) - self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") - targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) - self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") - targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) - self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") - targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) - self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") - targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) - self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") - targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) - - targetCustomSizer.AddGrowableCol(2) - - return targetCustomSizer - - def MakeBindString(self): - choice = self.targetCustomModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - targetCommand = "targetcustom" + mode.lower() - - enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" - friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" - defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" - alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" - mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" - notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" - base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" - notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" - - name = self.targetCustomOptionalName.GetValue() - - return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" - - def Serialize(self): - return { - 'mode' : self.targetCustomModeChoice.GetSelection(), - 'enemy' : self.targetCustomCBEnemies. IsChecked(), - 'friend' : self.targetCustomCBFriends. IsChecked(), - 'defeated' : self.targetCustomCBDefeated. IsChecked(), - 'alive' : self.targetCustomCBAlive. IsChecked(), - 'mypet' : self.targetCustomCBMyPets. IsChecked(), - 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), - 'base' : self.targetCustomCBBaseItems. IsChecked(), - 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), - 'name' : self.targetCustomOptionalName.GetValue(), - } - - def Deserialize(self, init): - if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) - if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) - if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) - if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) - if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) - if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) - if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) - if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) - if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) - if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - - -####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) - targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetEnemyModeChoice.SetSelection(0) - targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetEnemySizer - - def MakeBindString(self): - choice = self.targetEnemyModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetenemy" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetEnemyModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) - -####### Target Friend -class TargetFriendCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) - targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetFriendModeChoice.SetSelection(0) - targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetFriendSizer - - def MakeBindString(self): - choice = self.targetFriendModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetfriend" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetFriendModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) - -####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): - def BuildUI(self, dialog): - teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], - style=wx.ALIGN_CENTER_VERTICAL) - self.teamPetSelectNumber.SetSelection(0) - teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) - - return teamPetSelectSizer - - def MakeBindString(self): - teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' - targetNumber = self.teamPetSelectNumber.GetSelection()+1 - - return f"{teamOrPet}select {targetNumber}" - - def Serialize(self): - return { - 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', - 'targetNum': self.teamPetSelectNumber.GetSelection(), - } - - def Deserialize(self, init): - ToP = init.get('teamOrPet', '') - if ToP == 'pet': - self.teamPetSelectPetRB.SetValue(True) - else: - self.teamPetSelectTeamRB.SetValue(True) - if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) - -####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' - -####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) - for _, types in GameData.Inspirations.items(): - for _, info in types.items(): - for insp in info['tiers']: - name = re.sub(' ', '', str(insp)) - icon = GetIcon(f'Inspirations/{name}') - self.useInspByNameModeChoice.Append(insp, icon) - self.useInspByNameModeChoice.SetSelection(0) - useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) - - return useInspByNameSizer - - def MakeBindString(self): - choice = self.useInspByNameModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "inspexecname " + mode.lower() - - def GetAllInsps(self): - Insplist = [] - for _, info in GameData.Inspirations.items(): - for insp in info['tiers']: - Insplist.append(insp) - Insplist.append("---") - Insplist.pop(-1) # snip the terminal "---" - - return Insplist - - def Serialize(self): - return { 'insp' : self.useInspByNameModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) - -####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnRow.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) - self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnCol.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) - - return useInspRowColumnSizer - - def MakeBindString(self): - row = self.useInspRowColumnRow.GetSelection()+1 - col = self.useInspRowColumnCol.GetSelection()+1 - - return f"inspexectray {col} {row}" - - def Serialize(self): - return { - 'col' : self.useInspRowColumnCol.GetSelection(), - 'row' : self.useInspRowColumnRow.GetSelection(), - } - - def Deserialize(self, init): - if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) - if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) - -####### Use Power -class UsePowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - outerSizer = wx.BoxSizer(wx.HORIZONTAL) - - usePowerSizer = wx.GridBagSizer(5,5) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBToggle, (0,1)) - self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOn, (0,2)) - self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOff, (0,3)) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerName = PowerPicker(dialog) - usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) - usePowerSizer.AddGrowableCol(3) - - outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) - - return outerSizer - - def MakeBindString(self): - if self.usePowerRBToggle.GetValue(): - method = "powexecname" - elif self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') - return '' - - return f"{method} {self.usePowerName.GetLabel()}" - - def Serialize(self): - if self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - method = "powexecname" - return { - 'method': method, - 'pname' : self.usePowerName.GetLabel(), - 'picon' : self.usePowerName.IconFilename - } - - def Deserialize(self, init): - method = init.get('method', '') - if method == 'powexectoggleon': - self.usePowerRBOn.SetValue(True) - elif method == 'powexectoggleoff': - self.usePowerRBOff.SetValue(True) - else: - self.usePowerRBToggle.SetValue(True) - if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) +from UI.PowerBinderCommand import PowerBinderCommand ####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): +class UsePowerFromTrayCmd(PowerBinderCommand): + Name = "Use Power From Tray" + Menu = "Powers" + def BuildUI(self, dialog): usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) @@ -1453,348 +50,3 @@ def Serialize(self): def Deserialize(self, init): if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) - -####### Window Color -class WindowColorCmd(PowerBindCmd): - def BuildUI(self, dialog): - windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) - borderSizer = wx.BoxSizer(wx.VERTICAL) - self.ColorBorder.SetSizer(borderSizer) - self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) - borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) - - windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) - - RGBASizer = wx.FlexGridSizer(3, 4, 5) - - RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) - self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) - self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - windowColorSizer.Add(RGBASizer) - - self.UpdateFromSlider() - - return windowColorSizer - - def MakeBindString(self): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - return f"windowcolor {Rval} {Gval} {Bval} {Aval}" - - def Serialize(self): - return { - 'Rval' : self.RSlider.GetValue(), - 'Gval' : self.GSlider.GetValue(), - 'Bval' : self.BSlider.GetValue(), - 'Aval' : self.ASlider.GetValue(), - } - - def Deserialize(self, init): - self.RSlider.SetValue(init['Rval']) - self.GSlider.SetValue(init['Gval']) - self.BSlider.SetValue(init['Bval']) - self.ASlider.SetValue(init['Aval']) - self.UpdateFromSlider() - - def UpdateFromSlider(self, _ = None): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RReadout.SetValue(Rval) - self.GReadout.SetValue(Gval) - self.BReadout.SetValue(Bval) - self.AReadout.SetValue(Aval) - self.ColorBorder.Refresh() - - def UpdateFromText(self, _ = None): - Rval = self.RReadout.GetValue() - Gval = self.GReadout.GetValue() - Bval = self.BReadout.GetValue() - Aval = self.AReadout.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RSlider.SetValue(Rval) - self.GSlider.SetValue(Gval) - self.BSlider.SetValue(Bval) - self.ASlider.SetValue(Aval) - self.ColorBorder.Refresh() - -####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) - self.CommandChoice.SetSelection(0) - sizer.Add(self.CommandChoice, 0, wx.ALL, 5) - - self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), - value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) - sizer.Add(self.FilePath, 0, wx.ALL, 5) - - return sizer - - def MakeBindString(self): - command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] - return f'{command} "{self.FilePath.GetValue()}"' - - def Serialize(self): - return { - 'command' : self.CommandChoice.GetSelection(), - 'filename' : self.FilePath.GetValue(), - } - - def Deserialize(self, init): - self.CommandChoice.SetSelection(init.get('command', 0)) - self.FilePath.SetValue(init.get('filename', '')) - -####### Window Toggle -class WindowToggleCmd(PowerBindCmd): - def BuildUI(self, dialog): - self.WindowNames = { - 'Actions' : 'actions', - 'Auction House' : 'ah', - 'Badge' : 'badge', - 'Channel Search' : 'chansearch', - 'Chat' : 'chat', - 'Custom Chat 1' : 'chat1', - 'Custom Chat 2' : 'chat2', - 'Custom Chat 3' : 'chat3', - 'Custom Chat 4' : 'chat4', - 'Clues' : 'clue', - 'Combat Numbers' : 'combatnumbers', - 'Contacts' : 'contact', - 'Contact Finder' : 'contactfinder', - 'Costumes' : 'costume', - 'Email' : 'email', - 'Enhancements' : 'enhancements', - 'Friends' : 'friend', - 'Group' : 'group', - 'Help' : 'helpwindow', - 'Incarnate' : 'incarnate', - 'Inspirations' : 'insp', - 'League' : 'league', - 'LFG' : 'lfg', - 'Map' : 'map', - 'Mission' : 'mission', - 'Nav / Compass' : 'nav', - 'Options' : 'options', - 'Pets' : 'pet', - 'Petition' : 'petition', - 'Power Tray' : 'powers', - 'Power List' : 'powerlist', - 'Quit' : 'quit', - 'Recipes' : 'recipe', - 'Salvage' : 'salvage', - 'Search' : 'search', - 'Supergroup' : 'sg', - 'Target' : 'target', - 'Team' : 'team', - 'Tray' : 'tray', - 'Tray1' : 'tray1', - 'Tray2' : 'tray2', - 'Tray3' : 'tray3', - 'Tray4' : 'tray4', - 'Tray5' : 'tray5', - 'Tray6' : 'tray6', - 'Tray7' : 'tray7', - 'Tray8' : 'tray8', - 'Vault' : 'vault', - } - - self.ShortToggleCommands = { - 'Auction House' : 'ah', - 'Chat' : 'chat', - 'Help' : 'helpwindow', - 'Map' : 'map', - 'Nav / Compass' : 'nav', - 'Power Tray' : 'powers', - 'Target' : 'target', - 'Tray' : 'tray', - } - - windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) - windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) - self.windowToggleTray.SetSelection(0) - windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.windowShowRB = wx.RadioButton(dialog, -1, "Show") - self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") - - windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) - - return windowToggleSizer - - def MakeBindString(self): - choice = self.windowToggleTray - index = choice.GetSelection() - windowdesc = choice.GetString(index) - windowname = self.WindowNames[windowdesc] - - if self.windowShowRB.GetValue(): - return 'show ' + windowname - elif self.windowHideRB.GetValue(): - return 'windowhide ' + windowname - else: - if shortcmd := self.ShortToggleCommands.get(windowdesc, None): - return shortcmd - else: - return 'toggle ' + windowname - - - def Serialize(self): - choice = self.windowToggleTray - if self.windowShowRB.GetValue(): - action = "Show" - elif self.windowHideRB.GetValue(): - action = "Hide" - else: - action = "Toggle" - return { - 'window': choice.GetString(choice.GetSelection()), - 'action': action, - } - - def Deserialize(self, init): - choice = self.windowToggleTray - if window := init.get('window', ''): - if isinstance(window, int): - choice.SetSelection(window) - else: - choice.SetSelection(choice.FindString(window)) - - if choice.GetSelection() == wx.NOT_FOUND: - choice.SetSelection(0) - - action = init.get('action', '') - if action == "Show": - self.windowShowRB.SetValue(True) - elif action == "Hide": - self.windowHideRB.SetValue(True) - else: - self.windowToggleRB.SetValue(True) - - -# Must always add to this list when adding a new command class above -menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], - # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, - # but I'm leaving it here to remind myself that we do that. - } - -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/WindowColorCmd.py b/UI/PowerBinderCommand/WindowColorCmd.py index 4c02ab7..6785efb 100644 --- a/UI/PowerBinderCommand/WindowColorCmd.py +++ b/UI/PowerBinderCommand/WindowColorCmd.py @@ -1,1461 +1,11 @@ import wx -import re -import UI -import UI.EmotePicker -from UI.ControlGroup import ControlGroup -from UI.PowerPicker import PowerPicker -from Help import HelpButton -import wx.adv -from wx.adv import BitmapComboBox, EditableListBox -from pathlib import PureWindowsPath -import GameData -import Profile -from Icon import GetIcon - -class PowerBinderDialog(wx.Dialog): - def __init__(self, parent, button, init = {}): - wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) - - self.Page = parent.Page - self.EditDialog = PowerBinderEditDialog(self) - self.Button = button - self.AddStepMenu = self.makeAddStepMenu() - - sizer = wx.BoxSizer(wx.VERTICAL); - self.mainSizer = sizer - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) - AddStepButton = wx.Button(self, -1, 'Add Step') - AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) - AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) - choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) - choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) - sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) - - rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) - - self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) - self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) - self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) - rearrangeCtrl.Add(self.RearrangeList, 1) - - rearrangeButtons = wx.BoxSizer(wx.VERTICAL) - self.DelButton = wx.Button(self, -1, "Delete") - self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) - self.EditButton = wx.Button(self, -1, "Edit") - self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) - self.EditButton.Disable() - upButton = wx.Button(self, -1, "\u25B2") - upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) - downButton = wx.Button(self, -1, "\u25BC") - downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) - rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) - rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) - - sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.BindStringDisplay = wx.TextCtrl(self, -1) - self.BindStringDisplay.Disable() - choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, - wx.ALIGN_CENTER_VERTICAL) - choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) - - sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) - - sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) - - # need to dig around and get the OK button since we show this dialog modelessly now. - okButton = self.FindWindow(self.GetAffirmativeId()) - okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) - - # Wrap everything in a vbox to add some padding - vbox = wx.BoxSizer(wx.VERTICAL); - vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); - - self.SetSizerAndFit(vbox); - self.Layout() - self.Fit() - self.SetFocus() - - # if we are loading from profile, ie, have "init", build the list from it - if init: self.LoadFromData(init) - - def LoadFromData(self, init): - for item in init: - for type, data in item.items(): - commandClass = commandClasses.get(type, None) - if not commandClass: - commandClass = deprecatedCommandClasses.get(type, None) - if not commandClass: - wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") - continue - newCommand = commandClass(self.EditDialog, data) - index = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.SetClientData(index, newCommand) - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) - self.EditDialog.mainSizer.Hide(newCommand.UI) - self.UpdateBindStringDisplay() - - def SaveToData(self): - data = [] - index = 0 - for _ in self.RearrangeList.GetItems(): - # check whether we have an object already attached to this choice - cmdObject = self.RearrangeList.GetClientData(index) - commandClassName = commandRevClasses[type(cmdObject)] - data.append({commandClassName: cmdObject.Serialize()}) - index = index + 1 - return data - - def OnAddStepButton(self, evt): - button = evt.EventObject - if not self.AddStepMenu: - self.AddStepMenu = self.makeAddStepMenu() - button.PopupMenu(self.AddStepMenu) - - - def OnOKButton(self, _): - if self.Button.tgtTxtCtrl: - bindString = self.MakeBindString() - if bindString != self.Button.tgtTxtCtrl.GetValue(): - self.Button.tgtTxtCtrl.SetValue(bindString) - wx.App.Get().Main.Profile.SetModified() - self.Close() - - def OnRearrangeDelete(self, _): - current = self.RearrangeList.GetSelection() - if current == wx.NOT_FOUND: return - - self.RearrangeList.Delete(current) - self.UpdateBindStringDisplay() - - def OnRearrangeUp(self, _): - self.RearrangeList.MoveCurrentUp() - self.UpdateBindStringDisplay() - - def OnRearrangeDown(self, _): - self.RearrangeList.MoveCurrentDown() - self.UpdateBindStringDisplay() - - def OnRearrangeEdit(self, _): - index = self.RearrangeList.GetSelection() - - # check whether we have an object already attached to this choice - cmdObject = None - try: - cmdObject = self.RearrangeList.GetClientData(index) - except Exception: - pass - - if cmdObject: - self.ShowEditDialogFor(cmdObject) - self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) - else: - print("cmdObject was None") - self.UpdateBindStringDisplay() - - # OnAddStepMenu creates a new step and adds it to the rearrangelist - def OnAddStepMenu(self, evt): - menuitem = self.AddStepMenu.FindItemById(evt.GetId()) - chosenName = menuitem.GetItemLabel() - - # make a new command object, attached to the parent dialog - newCommandClass = commandClasses[chosenName] - newCommand = newCommandClass(self.EditDialog) - - # show the edit dialog if this command needs it - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) - if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): - self.EditDialog.mainSizer.Remove(newCommand.UI) - return - - newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.Select(newBindIndex) - self.RearrangeList.SetClientData(newBindIndex, newCommand) - - self.OnListSelect() - self.UpdateBindStringDisplay() - - def OnListSelect(self, _ = None): - selected = self.RearrangeList.GetSelection() - - if selected != wx.NOT_FOUND: - selCommand = self.RearrangeList.GetClientData(selected) - if selCommand.UI: - self.EditButton.Enable() - else: - self.EditButton.Disable() - - def UpdateBindStringDisplay(self): - self.BindStringDisplay.SetValue(self.MakeBindString()) - self.BindStringDisplay.SetToolTip(self.MakeBindString()) - - def MakeBindString(self): - cmdBindStrings = [] - for index in range(self.RearrangeList.GetCount()): - c = self.RearrangeList.GetClientData(index) - if c: cmdBindStrings.append(c.MakeBindString()) - - bindstring = ('$$'.join(cmdBindStrings)) - return bindstring - - def ShowEditDialogFor(self, command): - if not command.UI: return - - self.EditDialog.mainSizer.Show(command.UI) - - self.EditDialog.Layout() - self.EditDialog.Fit() - - self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') - returnval = self.EditDialog.ShowModal() - - self.EditDialog.mainSizer.Hide(command.UI) - - return returnval - - def makeAddStepMenu(self): - - stepMenu = wx.Menu() - - for subname in menuStructure: - submenu = wx.Menu() - stepMenu.AppendSubMenu(submenu, subname) - for classname in menuStructure[subname]: - submenu.Append(wx.ID_ANY, classname) - - stepMenu.Append(wx.ID_ANY, 'Custom Bind') - - return stepMenu - -class PowerBinderButton(wx.BitmapButton): - - def __init__(self, parent, tgtTxtCtrl, init = {}): - wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) - self.Init = init - self.Dialog = None - self.DialogParent = parent - - self.tgtTxtCtrl = tgtTxtCtrl - self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) - self.SetToolTip("Launch PowerBinder") - - def PowerBinderEventHandler(self, _): - self.PowerBinderDialog().Show() - - def LoadFromData(self, data): - self.PowerBinderDialog().LoadFromData(data) - - def SaveToData(self): - return self.PowerBinderDialog().SaveToData() - - def PowerBinderDialog(self): - if not self.Dialog: - self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) - return self.Dialog - - -class PowerBinderEditDialog(wx.Dialog): - def __init__(self, parent): - wx.Dialog.__init__(self, parent, -1, "Edit Step", - style = wx.DEFAULT_DIALOG_STYLE) - - outerSizer = wx.BoxSizer(wx.VERTICAL) - - self.mainSizer = wx.BoxSizer(wx.VERTICAL) - self.mainSizer.SetMinSize([500, 150]) - - self.Page = parent.Page - - self.mainSizer.Add( - self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), - 0, wx.EXPAND|wx.ALL, 10) - - outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) - - self.SetSizerAndFit(outerSizer) - self.Layout() - self.Fit() - -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" - - -####### Away From Keyboard -class AFKCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.Groups = {} - self.AttributeTable = { - 'Base' : { - 'Current Hit Points' : 'NT H', - 'Max Hit Points' : 'X H', - 'Current Endurance' : 'T E', - 'Max Endurance' : 'X EN', - 'Regeneration Rate' : 'N RAT', - 'Recovery Rate' : 'Y RA', - 'Endurance Consumption' : 'SU', - 'ToHit Bonus' : 'T B', - 'Accuracy Bonus' : 'CC', - 'Last Hit Chance' : 'T C', - 'Damage Bonus' : 'DA', - 'Healing Bonus' : 'NG B', - 'Recharge Time Bonus' : 'ME B', - 'Endurance Discount' : 'CE DIS', - 'Stealth Radius (PvP)' : 'PVP', - 'Stealth Radius (PvE)' : 'PVE', - 'Perception Radius' : 'RC', - 'Range Bonus' : 'GE B', - 'Threat Level' : 'AT L', - 'Experience to Next Level' : 'XT', - 'Experience Debt' : 'XP', - 'Influence / Infamy' : 'INF', - 'Inherent' : 'NH', - }, - 'Movement Speed' : { - 'Flying Speed' : 'FL', - 'Jumping Speed' : 'PI', - 'Max Jump Height' : 'X J', - 'Run Speed' : 'RU', - }, - 'Damage Resistance' : { - 'Smashing Resistance' : 'G R', - 'Lethal Resistance' : 'L R', - 'Fire Resistance' : 'RE R', - 'Cold Resistance' : 'COLD R', - 'Energy Resistance' : 'DamageType[4]', - 'Negative Energy Resistance' : 'GY R', - 'Psyonic Resistance' : 'NIC R', - 'Toxic Resistance' : 'XIC R', - }, - 'Defense' : { - 'Base Defense' : 'BAS', - 'Ranged Defense' : 'ED', - 'Melee Defense' : 'MEL', - 'AoE Defense' : '2', - 'Smashing Defense' : '3', - 'Lethal Defense' : '4', - 'Fire Defense' : '5', - 'Cold Defense' : '6', - 'Energy Defense' : '7', - 'Negative Energy Defense' : '8', - 'Psionic Defense' : '9', - 'Toxic Defense' : '1', - }, - 'Debuff Resistance' : { - 'Regeneration Resistance' : 'ON R', - 'Recovery Resistance' : 'RY R', - 'To Hit Resistance' : 'IT R', - 'Defense Resistance' : 'NSE RES', - }, - 'Status Effect Protection' : { - 'Hold Protection' : 'D P', - 'Immobilize Protection' : 'LIZE P', - 'Stun Protection' : 'N P', - 'Sleep Protection' : 'P P', - 'Knockback Protection' : 'K P', - 'Confuse Protection' : 'SE P', - 'Terrorize Protection' : 'ZE P', - 'Repel Protection' : 'EL P', - 'Teleport Protection' : 'T P', - }, - 'Status Effect Resistance' : { - 'Hold Resistance' : 'D R', - 'Immobilize Resistance' : 'LIZE R', - 'Stun Resistance' : 'N R', - 'Sleep Resistance' : 'P R', - 'Knockback Resistance' : 'K R', - 'Confuse Resistance' : 'SE R', - 'Terrorize Resistance' : 'ZE R', - 'Placate Resistance' : 'TE R', - 'Taunt Resistance' : 'NT R', - }, - 'Miscellaneous' : { - 'Level Shift' : 'L S', - }, - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.AttributeMenu = wx.Menu() - for group, controls in self.AttributeTable.items(): - submenu = wx.Menu() - self.AttributeMenu.AppendSubMenu(submenu, group) - for cb in controls: - submenu.Append(wx.ID_ANY, cb) - - self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) - - self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) - groupSizer.Add(self.editbox) - - newButton = self.editbox.GetNewButton() - newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) - - return groupSizer - - def MakeBindString(self): - map = {} - bindstrings = [] - for _, controls in self.AttributeTable.items(): - for cb, data in controls.items(): - map[cb] = data - - for string in self.editbox.GetStrings(): - if string: - bindstrings.append(f'monitorattribute {map[string]}') - - return '$$'.join(bindstrings) - - def Serialize(self): - return { - 'attributes' : self.editbox.GetStrings() - } - - def Deserialize(self, init): - self.editbox.SetStrings(init.get('attributes', [])) - - def OnNewButton(self, evt): - evt.GetEventObject().PopupMenu(self.AttributeMenu) - - def OnMenuItem(self, evt): - menuitem = evt.EventObject.FindItemById(evt.GetId()) - existingstrings = self.editbox.GetStrings() - existingstrings.append(menuitem.GetItemLabel()) - self.editbox.SetStrings(existingstrings) - -####### Auto Power -class AutoPowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) - autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.autoPowerName = PowerPicker(dialog) - autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) - - return autoPowerSizer - - def MakeBindString(self): - return f"powexecauto {self.autoPowerName.GetLabel()}" - - def Serialize(self): - return { - 'pname' : self.autoPowerName.GetLabel(), - 'picon' : self.autoPowerName.IconFilename - } - - def Deserialize(self, init): - if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.buffDisplayMap = { - 'Status Window' : { - 'Hide Auto' : 1, - 'Hide Toggles' : 2, - 'No Blinking' : 4, - 'No Stacking' : 8, - 'Numeric Stacking' : 16, - 'Hide Buff Numbers' : 32, - 'Stop Sending Buffs' : 64, - }, - 'Group Window' : { - 'Hide Auto' : 256, - 'Hide Toggles' : 512, - 'No Blinking' : 1024, - 'No Stacking' : 2048, - 'Numeric Stacking' : 4096, - 'Hide Buff Numbers' : 8192, - 'Stop Sending Buffs' : 16384, - }, - 'Pet Window' : { - 'Hide Auto' : 65536, - 'Hide Toggles' : 131072, - 'No Blinking' : 262144, - 'No Stacking' : 524288, - 'Numeric Stacking' : 1048576, - 'Hide Buff Numbers' : 2097152, - 'Stop Sending Buffs' : 4194304, - }, - } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - for group, controls in self.buffDisplayMap.items(): - self.Groups[group] = ControlGroup(dialog, self.Page, label = group) - groupid = self.Groups[group].GetStaticBox().GetId() - for cb, data in controls.items(): - self.Groups[group].AddControl( - ctlType = 'checkbox', - ctlName = f"{groupid}_{group}_{cb}", - label = cb, - data = data, - ) - - groupSizer.Add(self.Groups[group]) - - return groupSizer - - def CalculateValue(self): - page = wx.App.Get().Main.Profile.CustomBinds - - total = 0 - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] - if checkbox.IsChecked(): - total = total + checkbox.Data - return total - - def MakeBindString(self): - return f"optionset buffsettings {self.CalculateValue()}" - - def Serialize(self): - return { 'value' : self.CalculateValue() } - - def Deserialize(self, init): - value = init.get('value', 0) - - value = value or 0 # in case we had for some reason 'None' stashed in the init values - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] - checkbox.SetValue( checkbox.Data & value ) - -####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - chatCommandSizer = wx.GridBagSizer(5, 5) - self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") - chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) - # row 1 - self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) - self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) - self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) - # row 2 - self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) - self.chatCommandDuration.SetRange(1, 20) - self.chatCommandDuration.SetValue(7) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandDuration, (2,1)) - self.chatCommandChatSize = wx.Choice(dialog, -1, - choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) - self.chatCommandChatSize.SetSelection(5) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) - self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) - self.chatCommandChannel.SetSelection(0) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChannel, (2,5)) - # row 3 - self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") - chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) - self.chatCommandMessage = wx.TextCtrl(dialog, -1) - self.chatCommandMessage.SetHint('Chat Command Text') - chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) - - return chatCommandSizer - - def MakeBindString(self): - duration = self.chatCommandDuration.GetValue() - - choice = self.chatCommandChatSize - index = choice.GetSelection() - size = choice.GetString(index) - - duration = f"" if duration != 7 else "" - size = f"" if size != "1" else "" - - bdcolor = fgcolor = bgcolor = '' - if self.chatCommandUseColorsCB.IsChecked(): - bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - - bdcolor = f"" - fgcolor = f"" - bgcolor = f"" - - beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' - text = self.chatCommandMessage.GetValue() - - choice = self.chatCommandChannel - index = choice.GetSelection() - channel = choice.GetString(index) - - return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" - - def Serialize(self): - return { - 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), - 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), - 'channel' : self.chatCommandChannel .GetSelection(), - 'size' : self.chatCommandChatSize.GetSelection(), - 'duration' : self.chatCommandDuration.GetValue(), - 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'text' : self.chatCommandMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) - if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) - if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) - if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) - if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) - if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) - if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) - if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) - if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - - -####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): - def BuildUI(self, dialog): - chatCommandGlobalSizer = wx.GridBagSizer(5,5) - - self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") - chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) - - self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalChannel.SetHint("Channel") - chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) - - self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') - chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) - - chatCommandGlobalSizer.AddGrowableCol(1) - - return chatCommandGlobalSizer - - def MakeBindString(self): - useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() - channel = self.chatCommandGlobalChannel.GetValue() - message = self.chatCommandGlobalMessage.GetValue() - - preface = "beginchat /" if useBeginchat else "" - - return f'{preface}send "{channel}" {message}' - - def Serialize(self): - return { - 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), - 'channel' : self.chatCommandGlobalChannel.GetValue(), - 'message' : self.chatCommandGlobalMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) - if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) - if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) - -#######Costume Change -class CostumeChangeCmd(PowerBindCmd): - def BuildUI(self, dialog): - costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeCostume = wx.Choice(dialog, -1, - choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) - self.costumeChangeCostume.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeEmote = wx.Choice(dialog, -1, - choices = GameData.Emotes['costumechange']) - self.costumeChangeEmote.Insert("- None -", 0) - self.costumeChangeEmote.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return costumeChangeSizer - - def MakeBindString(self): - costumeNumber = self.costumeChangeCostume.GetSelection() - costumeEmote = self.costumeChangeEmote.GetSelection() - - if costumeEmote: # None, or 0 == "- None -" - ccCmd = 'cce' - emoteName = self.costumeChangeEmote.GetString(costumeEmote) - emoteName = " CC" + emoteName.replace(" ","") - else: - ccCmd = 'cc' - emoteName = '' - - return f"{ccCmd} {costumeNumber}{emoteName}" - - def Serialize(self): - return{ - 'costumeNumber': self.costumeChangeCostume.GetSelection(), - 'costumeEmote' : self.costumeChangeEmote.GetSelection(), - } - - def Deserialize(self, init): - if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) - if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) - -####### Movement Command -class MovementCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - self.plusbutton.SetValue(True) - - self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.commandchoice = wx.Choice(dialog, choices = [ - "forward", "left", "right", "backward", "up", "down", - "turnleft", "turnright", "first", "autorun", "clicktomove", - ],) - sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) - self.commandchoice.SetSelection(0) - - self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - pre = post = '' - if self.plusbutton.GetValue() : pre = "+" - elif self.plusplusbutton.GetValue() : pre = "++" - elif self.minusbutton.GetValue() : pre = "-" - elif self.zerobutton.GetValue() : post = " 0" - elif self.onebutton.GetValue() : post = " 1" - - command = self.commandchoice.GetString(self.commandchoice.GetSelection()) - - return f"{pre}{command}{post}" - - def Serialize(self): - mod = '' - if self.plusbutton.GetValue() : mod = "plus" - elif self.plusplusbutton.GetValue() : mod = "plusplus" - elif self.minusbutton.GetValue() : mod = "minus" - elif self.zerobutton.GetValue() : mod = "zero" - elif self.onebutton.GetValue() : mod = "one" - - return { - 'mod' : mod, - 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), - } - - def Deserialize(self, init): - mod = init.get('mod', 'plus') - - if mod == 'plus' : self.plusbutton.SetValue(True) - elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) - elif mod == 'minus' : self.minusbutton.SetValue(True) - elif mod == 'zero' : self.zerobutton.SetValue(True) - elif mod == 'one' : self.onebutton.SetValue(True) - - self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) - -####### Graphics Command -class GraphicsCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.FlexGridSizer(2) - - self.visscalecb = wx.CheckBox(dialog, label = "visscale") - sizer.Add(self.visscalecb) - self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) - sizer.Add(self.visscalesc) - - self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") - sizer.Add(self.dofweightcb) - self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) - sizer.Add(self.dofweightsc) - - self.fsaacb = wx.CheckBox(dialog, label = "fsaa") - sizer.Add(self.fsaacb) - self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) - self.fsaach.SetSelection(0) - sizer.Add(self.fsaach) - - self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") - sizer.Add(self.bloomscalecb) - self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) - self.bloomscalech.SetSelection(0) - sizer.Add(self.bloomscalech) - - self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") - sizer.Add(self.bloomweightcb) - self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) - sizer.Add(self.bloomweightsc) - - self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") - sizer.Add(self.lodbiascb) - self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) - sizer.Add(self.lodbiassc) - - self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") - sizer.Add(self.renderscalecb) - self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) - sizer.Add(self.renderscalesc) - - return sizer - - def MakeBindString(self): - # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. - bindstrings = [] - if self.visscalecb.IsChecked(): - bindstrings.append("visscale " + str(self.visscalesc.GetValue())) - if self.dofweightcb.IsChecked(): - bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) - if self.fsaacb.IsChecked(): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bindstrings.append("fsaa " + fsaavalue) - if self.bloomscalecb.IsChecked(): - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - bindstrings.append("bloomscale " + bloomscalevalue) - if self.bloomweightcb.IsChecked(): - bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) - if self.lodbiascb.IsChecked(): - bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) - if self.renderscalecb.IsChecked(): - bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) - - return '$$'.join(bindstrings) - - def Serialize(self): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - return { - 'visscalecb' : self.visscalecb.IsChecked(), - 'visscalesc' : self.visscalesc.GetValue(), - 'dofweightcb' : self.dofweightcb.IsChecked(), - 'dofweightsc' : self.dofweightsc.GetValue(), - 'fsaacb' : self.fsaacb.IsChecked(), - 'fsaach' : fsaavalue, - 'bloomscalecb' : self.bloomscalecb.IsChecked(), - 'bloomscalech' : bloomscalevalue, - 'bloomweightcb' : self.bloomweightcb.IsChecked(), - 'bloomweightsc' : self.bloomweightsc.GetValue(), - 'lodbiascb' : self.lodbiascb.IsChecked(), - 'lodbiassc' : self.lodbiassc.GetValue(), - 'renderscalecb' : self.renderscalecb.IsChecked(), - 'renderscalesc' : self.renderscalesc.GetValue(), - } - - def Deserialize(self, init): - self.visscalecb.SetValue(init.get('visscalecb', False)) - self.visscalesc.SetValue(init.get('visscalesc', 1.0)) - self.dofweightcb.SetValue(init.get('dofweightcb', False)) - self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) - self.fsaacb.SetValue(init.get('fsaacb', False)) - self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) - self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) - self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) - self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) - self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) - self.lodbiascb.SetValue(init.get('lodbiascb', False)) - self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) - self.renderscalecb.SetValue(init.get('renderscalecb', False)) - self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) - -####### Custom Bind -class CustomBindCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.customBindName = wx.TextCtrl(dialog, -1) - self.customBindName.SetHint('Custom Bind Text') - sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - return self.customBindName.GetValue() - - def Serialize(self): - return { 'customBindName': self.customBindName.GetValue() } - - def Deserialize(self,init): - if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) - -####### Emote -class EmoteCmd(PowerBindCmd): - def BuildUI(self, dialog): - emoteSizer = wx.BoxSizer(wx.HORIZONTAL) - self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") - emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - self.emoteName = wx.Button(dialog, -1, "...") - self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) - emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) - - return emoteSizer - - def MakeBindString(self): - displayedEmoteName = self.emoteName.GetLabel() - actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] - - return actualEmotePayload - - def Serialize(self): - return {'emoteName': self.emoteName.GetLabel()} - - def Deserialize(self, init): - if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) - -####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): - def BuildUI(self, dialog): - mainSizer = wx.BoxSizer(wx.VERTICAL) - - lbSizer = wx.BoxSizer(wx.HORIZONTAL) - lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") - lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - profiles = Profile.GetAllProfileBindsDirs() - - self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) - lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) - - mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") - self.lbResetCB.SetValue(True) - - mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - return mainSizer - - def MakeBindString(self): - - # If the specified binds directory disappeared between runs, we'd crash, so handle that. - if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' - - config = wx.ConfigBase.Get() - if config.Exists('GameBindPath'): - bindpath = config.Read('GameBindPath') - else: - bindpath = config.Read('BindPath') - - reset = "" - if self.lbResetCB.GetValue(): - reset = "keybind_reset$$" - - resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' - return reset + 'bindloadfile ' + str(resetfilepath) - - def Serialize(self): - return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), - 'ResetKeybinds' : self.lbResetCB.GetValue(), - } - - def Deserialize(self, init): - if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) - self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) - -####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' - -####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' - -####### SG Mode -class SGModeCmd(PowerBindCmd): - def BuildUI(self, dialog): - sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) - sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") - self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") - - sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) - - return sgmodeSizer - - def MakeBindString(self): - if self.sgmodeOnRB.GetValue(): - return 'sgmodeset 1' - elif self.sgmodeOffRB.GetValue(): - return 'sgmodeset 0' - else: - return 'sgmode' - - def Serialize(self): - if self.sgmodeOnRB.GetValue(): - val = "On" - elif self.sgmodeOffRB.GetValue(): - val = "Off" - else: - val = "Toggle" - - return {"value" : val} - - def Deserialize(self, init): - val = init.get('value', '') - if val == "On": - self.sgmodeOnRB.SetValue(True) - elif val == "Off": - self.sgmodeOffRB.SetValue(True) - else: - self.sgmodeToggleRB.SetValue(True) - -####### Target Custom -class TargetCustomCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetCustomSizer = wx.GridBagSizer(5,5) - targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), - flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) - self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetCustomModeChoice.SetSelection(0) - targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) - self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) - self.targetCustomOptionalName.SetHint("Optional name to match") - targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) - self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") - targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) - self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") - targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) - self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") - targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) - self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") - targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) - self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") - targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) - self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") - targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) - self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") - targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) - self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") - targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) - - targetCustomSizer.AddGrowableCol(2) - - return targetCustomSizer - - def MakeBindString(self): - choice = self.targetCustomModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - targetCommand = "targetcustom" + mode.lower() - - enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" - friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" - defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" - alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" - mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" - notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" - base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" - notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" - - name = self.targetCustomOptionalName.GetValue() - - return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" - - def Serialize(self): - return { - 'mode' : self.targetCustomModeChoice.GetSelection(), - 'enemy' : self.targetCustomCBEnemies. IsChecked(), - 'friend' : self.targetCustomCBFriends. IsChecked(), - 'defeated' : self.targetCustomCBDefeated. IsChecked(), - 'alive' : self.targetCustomCBAlive. IsChecked(), - 'mypet' : self.targetCustomCBMyPets. IsChecked(), - 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), - 'base' : self.targetCustomCBBaseItems. IsChecked(), - 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), - 'name' : self.targetCustomOptionalName.GetValue(), - } - - def Deserialize(self, init): - if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) - if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) - if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) - if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) - if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) - if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) - if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) - if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) - if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) - if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - - -####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) - targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetEnemyModeChoice.SetSelection(0) - targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetEnemySizer - - def MakeBindString(self): - choice = self.targetEnemyModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetenemy" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetEnemyModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) - -####### Target Friend -class TargetFriendCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) - targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetFriendModeChoice.SetSelection(0) - targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetFriendSizer - - def MakeBindString(self): - choice = self.targetFriendModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetfriend" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetFriendModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) - -####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): - def BuildUI(self, dialog): - teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], - style=wx.ALIGN_CENTER_VERTICAL) - self.teamPetSelectNumber.SetSelection(0) - teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) - - return teamPetSelectSizer - - def MakeBindString(self): - teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' - targetNumber = self.teamPetSelectNumber.GetSelection()+1 - - return f"{teamOrPet}select {targetNumber}" - - def Serialize(self): - return { - 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', - 'targetNum': self.teamPetSelectNumber.GetSelection(), - } - - def Deserialize(self, init): - ToP = init.get('teamOrPet', '') - if ToP == 'pet': - self.teamPetSelectPetRB.SetValue(True) - else: - self.teamPetSelectTeamRB.SetValue(True) - if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) - -####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' - -####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) - for _, types in GameData.Inspirations.items(): - for _, info in types.items(): - for insp in info['tiers']: - name = re.sub(' ', '', str(insp)) - icon = GetIcon(f'Inspirations/{name}') - self.useInspByNameModeChoice.Append(insp, icon) - self.useInspByNameModeChoice.SetSelection(0) - useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) - - return useInspByNameSizer - - def MakeBindString(self): - choice = self.useInspByNameModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "inspexecname " + mode.lower() - - def GetAllInsps(self): - Insplist = [] - for _, info in GameData.Inspirations.items(): - for insp in info['tiers']: - Insplist.append(insp) - Insplist.append("---") - Insplist.pop(-1) # snip the terminal "---" - - return Insplist - - def Serialize(self): - return { 'insp' : self.useInspByNameModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) - -####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnRow.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) - self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnCol.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) - - return useInspRowColumnSizer - - def MakeBindString(self): - row = self.useInspRowColumnRow.GetSelection()+1 - col = self.useInspRowColumnCol.GetSelection()+1 - - return f"inspexectray {col} {row}" - - def Serialize(self): - return { - 'col' : self.useInspRowColumnCol.GetSelection(), - 'row' : self.useInspRowColumnRow.GetSelection(), - } - - def Deserialize(self, init): - if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) - if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) - -####### Use Power -class UsePowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - outerSizer = wx.BoxSizer(wx.HORIZONTAL) - - usePowerSizer = wx.GridBagSizer(5,5) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBToggle, (0,1)) - self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOn, (0,2)) - self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOff, (0,3)) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerName = PowerPicker(dialog) - usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) - usePowerSizer.AddGrowableCol(3) - - outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) - - return outerSizer - - def MakeBindString(self): - if self.usePowerRBToggle.GetValue(): - method = "powexecname" - elif self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') - return '' - - return f"{method} {self.usePowerName.GetLabel()}" - - def Serialize(self): - if self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - method = "powexecname" - return { - 'method': method, - 'pname' : self.usePowerName.GetLabel(), - 'picon' : self.usePowerName.IconFilename - } - - def Deserialize(self, init): - method = init.get('method', '') - if method == 'powexectoggleon': - self.usePowerRBOn.SetValue(True) - elif method == 'powexectoggleoff': - self.usePowerRBOff.SetValue(True) - else: - self.usePowerRBToggle.SetValue(True) - if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) - -####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): - def BuildUI(self, dialog): - usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTrayTray = wx.Choice(dialog, -1, - choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', - 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) - self.usePowerFromTrayTray.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) - self.usePowerFromTraySlot.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return usePowerFromTraySizer - - def MakeBindString(self): - choice = self.usePowerFromTrayTray - tray = choice.GetSelection() - - choice = self.usePowerFromTraySlot - slot = choice.GetSelection()+1 - - mode = "slot" - mode2 = '' - if tray > 3: - mode = "tray" - mode2 = f" {tray - 3}" - elif tray == 3: - mode = "alt2slot" - elif tray == 2: - mode = "altslot" - - return f"powexec{mode} {slot}{mode2}" - - def Serialize(self): - return { - 'tray' : self.usePowerFromTrayTray.GetSelection(), - 'slot' : self.usePowerFromTraySlot.GetSelection(), - } - - def Deserialize(self, init): - if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) - if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) +from UI.PowerBinderCommand import PowerBinderCommand ####### Window Color -class WindowColorCmd(PowerBindCmd): +class WindowColorCmd(PowerBinderCommand): + Name = "Window Color" + Menu = "Graphics / UI" + def BuildUI(self, dialog): windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) @@ -1554,247 +104,3 @@ def UpdateFromText(self, _ = None): self.BSlider.SetValue(Bval) self.ASlider.SetValue(Aval) self.ColorBorder.Refresh() - -####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) - self.CommandChoice.SetSelection(0) - sizer.Add(self.CommandChoice, 0, wx.ALL, 5) - - self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), - value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) - sizer.Add(self.FilePath, 0, wx.ALL, 5) - - return sizer - - def MakeBindString(self): - command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] - return f'{command} "{self.FilePath.GetValue()}"' - - def Serialize(self): - return { - 'command' : self.CommandChoice.GetSelection(), - 'filename' : self.FilePath.GetValue(), - } - - def Deserialize(self, init): - self.CommandChoice.SetSelection(init.get('command', 0)) - self.FilePath.SetValue(init.get('filename', '')) - -####### Window Toggle -class WindowToggleCmd(PowerBindCmd): - def BuildUI(self, dialog): - self.WindowNames = { - 'Actions' : 'actions', - 'Auction House' : 'ah', - 'Badge' : 'badge', - 'Channel Search' : 'chansearch', - 'Chat' : 'chat', - 'Custom Chat 1' : 'chat1', - 'Custom Chat 2' : 'chat2', - 'Custom Chat 3' : 'chat3', - 'Custom Chat 4' : 'chat4', - 'Clues' : 'clue', - 'Combat Numbers' : 'combatnumbers', - 'Contacts' : 'contact', - 'Contact Finder' : 'contactfinder', - 'Costumes' : 'costume', - 'Email' : 'email', - 'Enhancements' : 'enhancements', - 'Friends' : 'friend', - 'Group' : 'group', - 'Help' : 'helpwindow', - 'Incarnate' : 'incarnate', - 'Inspirations' : 'insp', - 'League' : 'league', - 'LFG' : 'lfg', - 'Map' : 'map', - 'Mission' : 'mission', - 'Nav / Compass' : 'nav', - 'Options' : 'options', - 'Pets' : 'pet', - 'Petition' : 'petition', - 'Power Tray' : 'powers', - 'Power List' : 'powerlist', - 'Quit' : 'quit', - 'Recipes' : 'recipe', - 'Salvage' : 'salvage', - 'Search' : 'search', - 'Supergroup' : 'sg', - 'Target' : 'target', - 'Team' : 'team', - 'Tray' : 'tray', - 'Tray1' : 'tray1', - 'Tray2' : 'tray2', - 'Tray3' : 'tray3', - 'Tray4' : 'tray4', - 'Tray5' : 'tray5', - 'Tray6' : 'tray6', - 'Tray7' : 'tray7', - 'Tray8' : 'tray8', - 'Vault' : 'vault', - } - - self.ShortToggleCommands = { - 'Auction House' : 'ah', - 'Chat' : 'chat', - 'Help' : 'helpwindow', - 'Map' : 'map', - 'Nav / Compass' : 'nav', - 'Power Tray' : 'powers', - 'Target' : 'target', - 'Tray' : 'tray', - } - - windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) - windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) - self.windowToggleTray.SetSelection(0) - windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.windowShowRB = wx.RadioButton(dialog, -1, "Show") - self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") - - windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) - - return windowToggleSizer - - def MakeBindString(self): - choice = self.windowToggleTray - index = choice.GetSelection() - windowdesc = choice.GetString(index) - windowname = self.WindowNames[windowdesc] - - if self.windowShowRB.GetValue(): - return 'show ' + windowname - elif self.windowHideRB.GetValue(): - return 'windowhide ' + windowname - else: - if shortcmd := self.ShortToggleCommands.get(windowdesc, None): - return shortcmd - else: - return 'toggle ' + windowname - - - def Serialize(self): - choice = self.windowToggleTray - if self.windowShowRB.GetValue(): - action = "Show" - elif self.windowHideRB.GetValue(): - action = "Hide" - else: - action = "Toggle" - return { - 'window': choice.GetString(choice.GetSelection()), - 'action': action, - } - - def Deserialize(self, init): - choice = self.windowToggleTray - if window := init.get('window', ''): - if isinstance(window, int): - choice.SetSelection(window) - else: - choice.SetSelection(choice.FindString(window)) - - if choice.GetSelection() == wx.NOT_FOUND: - choice.SetSelection(0) - - action = init.get('action', '') - if action == "Show": - self.windowShowRB.SetValue(True) - elif action == "Hide": - self.windowHideRB.SetValue(True) - else: - self.windowToggleRB.SetValue(True) - - -# Must always add to this list when adding a new command class above -menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], - # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, - # but I'm leaving it here to remind myself that we do that. - } - -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/WindowSaveLoadCmd.py b/UI/PowerBinderCommand/WindowSaveLoadCmd.py index 4c02ab7..55102c5 100644 --- a/UI/PowerBinderCommand/WindowSaveLoadCmd.py +++ b/UI/PowerBinderCommand/WindowSaveLoadCmd.py @@ -1,1562 +1,11 @@ import wx -import re -import UI -import UI.EmotePicker -from UI.ControlGroup import ControlGroup -from UI.PowerPicker import PowerPicker -from Help import HelpButton -import wx.adv -from wx.adv import BitmapComboBox, EditableListBox -from pathlib import PureWindowsPath -import GameData -import Profile -from Icon import GetIcon - -class PowerBinderDialog(wx.Dialog): - def __init__(self, parent, button, init = {}): - wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) - - self.Page = parent.Page - self.EditDialog = PowerBinderEditDialog(self) - self.Button = button - self.AddStepMenu = self.makeAddStepMenu() - - sizer = wx.BoxSizer(wx.VERTICAL); - self.mainSizer = sizer - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) - AddStepButton = wx.Button(self, -1, 'Add Step') - AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) - AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) - choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) - choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) - sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) - - rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) - - self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) - self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) - self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) - rearrangeCtrl.Add(self.RearrangeList, 1) - - rearrangeButtons = wx.BoxSizer(wx.VERTICAL) - self.DelButton = wx.Button(self, -1, "Delete") - self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) - self.EditButton = wx.Button(self, -1, "Edit") - self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) - self.EditButton.Disable() - upButton = wx.Button(self, -1, "\u25B2") - upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) - downButton = wx.Button(self, -1, "\u25BC") - downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) - rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) - rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) - - sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.BindStringDisplay = wx.TextCtrl(self, -1) - self.BindStringDisplay.Disable() - choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, - wx.ALIGN_CENTER_VERTICAL) - choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) - - sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) - - sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) - - # need to dig around and get the OK button since we show this dialog modelessly now. - okButton = self.FindWindow(self.GetAffirmativeId()) - okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) - - # Wrap everything in a vbox to add some padding - vbox = wx.BoxSizer(wx.VERTICAL); - vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); - - self.SetSizerAndFit(vbox); - self.Layout() - self.Fit() - self.SetFocus() - - # if we are loading from profile, ie, have "init", build the list from it - if init: self.LoadFromData(init) - - def LoadFromData(self, init): - for item in init: - for type, data in item.items(): - commandClass = commandClasses.get(type, None) - if not commandClass: - commandClass = deprecatedCommandClasses.get(type, None) - if not commandClass: - wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") - continue - newCommand = commandClass(self.EditDialog, data) - index = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.SetClientData(index, newCommand) - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) - self.EditDialog.mainSizer.Hide(newCommand.UI) - self.UpdateBindStringDisplay() - - def SaveToData(self): - data = [] - index = 0 - for _ in self.RearrangeList.GetItems(): - # check whether we have an object already attached to this choice - cmdObject = self.RearrangeList.GetClientData(index) - commandClassName = commandRevClasses[type(cmdObject)] - data.append({commandClassName: cmdObject.Serialize()}) - index = index + 1 - return data - - def OnAddStepButton(self, evt): - button = evt.EventObject - if not self.AddStepMenu: - self.AddStepMenu = self.makeAddStepMenu() - button.PopupMenu(self.AddStepMenu) - - - def OnOKButton(self, _): - if self.Button.tgtTxtCtrl: - bindString = self.MakeBindString() - if bindString != self.Button.tgtTxtCtrl.GetValue(): - self.Button.tgtTxtCtrl.SetValue(bindString) - wx.App.Get().Main.Profile.SetModified() - self.Close() - - def OnRearrangeDelete(self, _): - current = self.RearrangeList.GetSelection() - if current == wx.NOT_FOUND: return - - self.RearrangeList.Delete(current) - self.UpdateBindStringDisplay() - - def OnRearrangeUp(self, _): - self.RearrangeList.MoveCurrentUp() - self.UpdateBindStringDisplay() - - def OnRearrangeDown(self, _): - self.RearrangeList.MoveCurrentDown() - self.UpdateBindStringDisplay() - - def OnRearrangeEdit(self, _): - index = self.RearrangeList.GetSelection() - - # check whether we have an object already attached to this choice - cmdObject = None - try: - cmdObject = self.RearrangeList.GetClientData(index) - except Exception: - pass - - if cmdObject: - self.ShowEditDialogFor(cmdObject) - self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) - else: - print("cmdObject was None") - self.UpdateBindStringDisplay() - - # OnAddStepMenu creates a new step and adds it to the rearrangelist - def OnAddStepMenu(self, evt): - menuitem = self.AddStepMenu.FindItemById(evt.GetId()) - chosenName = menuitem.GetItemLabel() - - # make a new command object, attached to the parent dialog - newCommandClass = commandClasses[chosenName] - newCommand = newCommandClass(self.EditDialog) - - # show the edit dialog if this command needs it - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) - if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): - self.EditDialog.mainSizer.Remove(newCommand.UI) - return - - newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.Select(newBindIndex) - self.RearrangeList.SetClientData(newBindIndex, newCommand) - - self.OnListSelect() - self.UpdateBindStringDisplay() - - def OnListSelect(self, _ = None): - selected = self.RearrangeList.GetSelection() - - if selected != wx.NOT_FOUND: - selCommand = self.RearrangeList.GetClientData(selected) - if selCommand.UI: - self.EditButton.Enable() - else: - self.EditButton.Disable() - - def UpdateBindStringDisplay(self): - self.BindStringDisplay.SetValue(self.MakeBindString()) - self.BindStringDisplay.SetToolTip(self.MakeBindString()) - - def MakeBindString(self): - cmdBindStrings = [] - for index in range(self.RearrangeList.GetCount()): - c = self.RearrangeList.GetClientData(index) - if c: cmdBindStrings.append(c.MakeBindString()) - - bindstring = ('$$'.join(cmdBindStrings)) - return bindstring - - def ShowEditDialogFor(self, command): - if not command.UI: return - - self.EditDialog.mainSizer.Show(command.UI) - - self.EditDialog.Layout() - self.EditDialog.Fit() - - self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') - returnval = self.EditDialog.ShowModal() - - self.EditDialog.mainSizer.Hide(command.UI) - - return returnval - - def makeAddStepMenu(self): - - stepMenu = wx.Menu() - - for subname in menuStructure: - submenu = wx.Menu() - stepMenu.AppendSubMenu(submenu, subname) - for classname in menuStructure[subname]: - submenu.Append(wx.ID_ANY, classname) - - stepMenu.Append(wx.ID_ANY, 'Custom Bind') - - return stepMenu - -class PowerBinderButton(wx.BitmapButton): - - def __init__(self, parent, tgtTxtCtrl, init = {}): - wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) - self.Init = init - self.Dialog = None - self.DialogParent = parent - - self.tgtTxtCtrl = tgtTxtCtrl - self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) - self.SetToolTip("Launch PowerBinder") - - def PowerBinderEventHandler(self, _): - self.PowerBinderDialog().Show() - - def LoadFromData(self, data): - self.PowerBinderDialog().LoadFromData(data) - - def SaveToData(self): - return self.PowerBinderDialog().SaveToData() - - def PowerBinderDialog(self): - if not self.Dialog: - self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) - return self.Dialog - - -class PowerBinderEditDialog(wx.Dialog): - def __init__(self, parent): - wx.Dialog.__init__(self, parent, -1, "Edit Step", - style = wx.DEFAULT_DIALOG_STYLE) - - outerSizer = wx.BoxSizer(wx.VERTICAL) - - self.mainSizer = wx.BoxSizer(wx.VERTICAL) - self.mainSizer.SetMinSize([500, 150]) - - self.Page = parent.Page - - self.mainSizer.Add( - self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), - 0, wx.EXPAND|wx.ALL, 10) - - outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) - - self.SetSizerAndFit(outerSizer) - self.Layout() - self.Fit() - -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" - - -####### Away From Keyboard -class AFKCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.Groups = {} - self.AttributeTable = { - 'Base' : { - 'Current Hit Points' : 'NT H', - 'Max Hit Points' : 'X H', - 'Current Endurance' : 'T E', - 'Max Endurance' : 'X EN', - 'Regeneration Rate' : 'N RAT', - 'Recovery Rate' : 'Y RA', - 'Endurance Consumption' : 'SU', - 'ToHit Bonus' : 'T B', - 'Accuracy Bonus' : 'CC', - 'Last Hit Chance' : 'T C', - 'Damage Bonus' : 'DA', - 'Healing Bonus' : 'NG B', - 'Recharge Time Bonus' : 'ME B', - 'Endurance Discount' : 'CE DIS', - 'Stealth Radius (PvP)' : 'PVP', - 'Stealth Radius (PvE)' : 'PVE', - 'Perception Radius' : 'RC', - 'Range Bonus' : 'GE B', - 'Threat Level' : 'AT L', - 'Experience to Next Level' : 'XT', - 'Experience Debt' : 'XP', - 'Influence / Infamy' : 'INF', - 'Inherent' : 'NH', - }, - 'Movement Speed' : { - 'Flying Speed' : 'FL', - 'Jumping Speed' : 'PI', - 'Max Jump Height' : 'X J', - 'Run Speed' : 'RU', - }, - 'Damage Resistance' : { - 'Smashing Resistance' : 'G R', - 'Lethal Resistance' : 'L R', - 'Fire Resistance' : 'RE R', - 'Cold Resistance' : 'COLD R', - 'Energy Resistance' : 'DamageType[4]', - 'Negative Energy Resistance' : 'GY R', - 'Psyonic Resistance' : 'NIC R', - 'Toxic Resistance' : 'XIC R', - }, - 'Defense' : { - 'Base Defense' : 'BAS', - 'Ranged Defense' : 'ED', - 'Melee Defense' : 'MEL', - 'AoE Defense' : '2', - 'Smashing Defense' : '3', - 'Lethal Defense' : '4', - 'Fire Defense' : '5', - 'Cold Defense' : '6', - 'Energy Defense' : '7', - 'Negative Energy Defense' : '8', - 'Psionic Defense' : '9', - 'Toxic Defense' : '1', - }, - 'Debuff Resistance' : { - 'Regeneration Resistance' : 'ON R', - 'Recovery Resistance' : 'RY R', - 'To Hit Resistance' : 'IT R', - 'Defense Resistance' : 'NSE RES', - }, - 'Status Effect Protection' : { - 'Hold Protection' : 'D P', - 'Immobilize Protection' : 'LIZE P', - 'Stun Protection' : 'N P', - 'Sleep Protection' : 'P P', - 'Knockback Protection' : 'K P', - 'Confuse Protection' : 'SE P', - 'Terrorize Protection' : 'ZE P', - 'Repel Protection' : 'EL P', - 'Teleport Protection' : 'T P', - }, - 'Status Effect Resistance' : { - 'Hold Resistance' : 'D R', - 'Immobilize Resistance' : 'LIZE R', - 'Stun Resistance' : 'N R', - 'Sleep Resistance' : 'P R', - 'Knockback Resistance' : 'K R', - 'Confuse Resistance' : 'SE R', - 'Terrorize Resistance' : 'ZE R', - 'Placate Resistance' : 'TE R', - 'Taunt Resistance' : 'NT R', - }, - 'Miscellaneous' : { - 'Level Shift' : 'L S', - }, - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.AttributeMenu = wx.Menu() - for group, controls in self.AttributeTable.items(): - submenu = wx.Menu() - self.AttributeMenu.AppendSubMenu(submenu, group) - for cb in controls: - submenu.Append(wx.ID_ANY, cb) - - self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) - - self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) - groupSizer.Add(self.editbox) - - newButton = self.editbox.GetNewButton() - newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) - - return groupSizer - - def MakeBindString(self): - map = {} - bindstrings = [] - for _, controls in self.AttributeTable.items(): - for cb, data in controls.items(): - map[cb] = data - - for string in self.editbox.GetStrings(): - if string: - bindstrings.append(f'monitorattribute {map[string]}') - - return '$$'.join(bindstrings) - - def Serialize(self): - return { - 'attributes' : self.editbox.GetStrings() - } - - def Deserialize(self, init): - self.editbox.SetStrings(init.get('attributes', [])) - - def OnNewButton(self, evt): - evt.GetEventObject().PopupMenu(self.AttributeMenu) - - def OnMenuItem(self, evt): - menuitem = evt.EventObject.FindItemById(evt.GetId()) - existingstrings = self.editbox.GetStrings() - existingstrings.append(menuitem.GetItemLabel()) - self.editbox.SetStrings(existingstrings) - -####### Auto Power -class AutoPowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) - autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.autoPowerName = PowerPicker(dialog) - autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) - - return autoPowerSizer - - def MakeBindString(self): - return f"powexecauto {self.autoPowerName.GetLabel()}" - - def Serialize(self): - return { - 'pname' : self.autoPowerName.GetLabel(), - 'picon' : self.autoPowerName.IconFilename - } - - def Deserialize(self, init): - if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.buffDisplayMap = { - 'Status Window' : { - 'Hide Auto' : 1, - 'Hide Toggles' : 2, - 'No Blinking' : 4, - 'No Stacking' : 8, - 'Numeric Stacking' : 16, - 'Hide Buff Numbers' : 32, - 'Stop Sending Buffs' : 64, - }, - 'Group Window' : { - 'Hide Auto' : 256, - 'Hide Toggles' : 512, - 'No Blinking' : 1024, - 'No Stacking' : 2048, - 'Numeric Stacking' : 4096, - 'Hide Buff Numbers' : 8192, - 'Stop Sending Buffs' : 16384, - }, - 'Pet Window' : { - 'Hide Auto' : 65536, - 'Hide Toggles' : 131072, - 'No Blinking' : 262144, - 'No Stacking' : 524288, - 'Numeric Stacking' : 1048576, - 'Hide Buff Numbers' : 2097152, - 'Stop Sending Buffs' : 4194304, - }, - } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - for group, controls in self.buffDisplayMap.items(): - self.Groups[group] = ControlGroup(dialog, self.Page, label = group) - groupid = self.Groups[group].GetStaticBox().GetId() - for cb, data in controls.items(): - self.Groups[group].AddControl( - ctlType = 'checkbox', - ctlName = f"{groupid}_{group}_{cb}", - label = cb, - data = data, - ) - - groupSizer.Add(self.Groups[group]) - - return groupSizer - - def CalculateValue(self): - page = wx.App.Get().Main.Profile.CustomBinds - - total = 0 - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] - if checkbox.IsChecked(): - total = total + checkbox.Data - return total - - def MakeBindString(self): - return f"optionset buffsettings {self.CalculateValue()}" - - def Serialize(self): - return { 'value' : self.CalculateValue() } - - def Deserialize(self, init): - value = init.get('value', 0) - - value = value or 0 # in case we had for some reason 'None' stashed in the init values - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] - checkbox.SetValue( checkbox.Data & value ) - -####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - chatCommandSizer = wx.GridBagSizer(5, 5) - self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") - chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) - # row 1 - self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) - self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) - self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) - # row 2 - self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) - self.chatCommandDuration.SetRange(1, 20) - self.chatCommandDuration.SetValue(7) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandDuration, (2,1)) - self.chatCommandChatSize = wx.Choice(dialog, -1, - choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) - self.chatCommandChatSize.SetSelection(5) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) - self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) - self.chatCommandChannel.SetSelection(0) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChannel, (2,5)) - # row 3 - self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") - chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) - self.chatCommandMessage = wx.TextCtrl(dialog, -1) - self.chatCommandMessage.SetHint('Chat Command Text') - chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) - - return chatCommandSizer - - def MakeBindString(self): - duration = self.chatCommandDuration.GetValue() - - choice = self.chatCommandChatSize - index = choice.GetSelection() - size = choice.GetString(index) - - duration = f"" if duration != 7 else "" - size = f"" if size != "1" else "" - - bdcolor = fgcolor = bgcolor = '' - if self.chatCommandUseColorsCB.IsChecked(): - bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - - bdcolor = f"" - fgcolor = f"" - bgcolor = f"" - - beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' - text = self.chatCommandMessage.GetValue() - - choice = self.chatCommandChannel - index = choice.GetSelection() - channel = choice.GetString(index) - - return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" - - def Serialize(self): - return { - 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), - 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), - 'channel' : self.chatCommandChannel .GetSelection(), - 'size' : self.chatCommandChatSize.GetSelection(), - 'duration' : self.chatCommandDuration.GetValue(), - 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'text' : self.chatCommandMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) - if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) - if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) - if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) - if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) - if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) - if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) - if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) - if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - - -####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): - def BuildUI(self, dialog): - chatCommandGlobalSizer = wx.GridBagSizer(5,5) - - self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") - chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) - - self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalChannel.SetHint("Channel") - chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) - - self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') - chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) - - chatCommandGlobalSizer.AddGrowableCol(1) - - return chatCommandGlobalSizer - - def MakeBindString(self): - useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() - channel = self.chatCommandGlobalChannel.GetValue() - message = self.chatCommandGlobalMessage.GetValue() - - preface = "beginchat /" if useBeginchat else "" - - return f'{preface}send "{channel}" {message}' - - def Serialize(self): - return { - 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), - 'channel' : self.chatCommandGlobalChannel.GetValue(), - 'message' : self.chatCommandGlobalMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) - if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) - if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) - -#######Costume Change -class CostumeChangeCmd(PowerBindCmd): - def BuildUI(self, dialog): - costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeCostume = wx.Choice(dialog, -1, - choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) - self.costumeChangeCostume.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeEmote = wx.Choice(dialog, -1, - choices = GameData.Emotes['costumechange']) - self.costumeChangeEmote.Insert("- None -", 0) - self.costumeChangeEmote.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return costumeChangeSizer - - def MakeBindString(self): - costumeNumber = self.costumeChangeCostume.GetSelection() - costumeEmote = self.costumeChangeEmote.GetSelection() - - if costumeEmote: # None, or 0 == "- None -" - ccCmd = 'cce' - emoteName = self.costumeChangeEmote.GetString(costumeEmote) - emoteName = " CC" + emoteName.replace(" ","") - else: - ccCmd = 'cc' - emoteName = '' - - return f"{ccCmd} {costumeNumber}{emoteName}" - - def Serialize(self): - return{ - 'costumeNumber': self.costumeChangeCostume.GetSelection(), - 'costumeEmote' : self.costumeChangeEmote.GetSelection(), - } - - def Deserialize(self, init): - if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) - if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) - -####### Movement Command -class MovementCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - self.plusbutton.SetValue(True) - - self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.commandchoice = wx.Choice(dialog, choices = [ - "forward", "left", "right", "backward", "up", "down", - "turnleft", "turnright", "first", "autorun", "clicktomove", - ],) - sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) - self.commandchoice.SetSelection(0) - - self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - pre = post = '' - if self.plusbutton.GetValue() : pre = "+" - elif self.plusplusbutton.GetValue() : pre = "++" - elif self.minusbutton.GetValue() : pre = "-" - elif self.zerobutton.GetValue() : post = " 0" - elif self.onebutton.GetValue() : post = " 1" - - command = self.commandchoice.GetString(self.commandchoice.GetSelection()) - - return f"{pre}{command}{post}" - - def Serialize(self): - mod = '' - if self.plusbutton.GetValue() : mod = "plus" - elif self.plusplusbutton.GetValue() : mod = "plusplus" - elif self.minusbutton.GetValue() : mod = "minus" - elif self.zerobutton.GetValue() : mod = "zero" - elif self.onebutton.GetValue() : mod = "one" - - return { - 'mod' : mod, - 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), - } - - def Deserialize(self, init): - mod = init.get('mod', 'plus') - - if mod == 'plus' : self.plusbutton.SetValue(True) - elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) - elif mod == 'minus' : self.minusbutton.SetValue(True) - elif mod == 'zero' : self.zerobutton.SetValue(True) - elif mod == 'one' : self.onebutton.SetValue(True) - - self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) - -####### Graphics Command -class GraphicsCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.FlexGridSizer(2) - - self.visscalecb = wx.CheckBox(dialog, label = "visscale") - sizer.Add(self.visscalecb) - self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) - sizer.Add(self.visscalesc) - - self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") - sizer.Add(self.dofweightcb) - self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) - sizer.Add(self.dofweightsc) - - self.fsaacb = wx.CheckBox(dialog, label = "fsaa") - sizer.Add(self.fsaacb) - self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) - self.fsaach.SetSelection(0) - sizer.Add(self.fsaach) - - self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") - sizer.Add(self.bloomscalecb) - self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) - self.bloomscalech.SetSelection(0) - sizer.Add(self.bloomscalech) - - self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") - sizer.Add(self.bloomweightcb) - self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) - sizer.Add(self.bloomweightsc) - - self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") - sizer.Add(self.lodbiascb) - self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) - sizer.Add(self.lodbiassc) - - self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") - sizer.Add(self.renderscalecb) - self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) - sizer.Add(self.renderscalesc) - - return sizer - - def MakeBindString(self): - # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. - bindstrings = [] - if self.visscalecb.IsChecked(): - bindstrings.append("visscale " + str(self.visscalesc.GetValue())) - if self.dofweightcb.IsChecked(): - bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) - if self.fsaacb.IsChecked(): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bindstrings.append("fsaa " + fsaavalue) - if self.bloomscalecb.IsChecked(): - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - bindstrings.append("bloomscale " + bloomscalevalue) - if self.bloomweightcb.IsChecked(): - bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) - if self.lodbiascb.IsChecked(): - bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) - if self.renderscalecb.IsChecked(): - bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) - - return '$$'.join(bindstrings) - - def Serialize(self): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - return { - 'visscalecb' : self.visscalecb.IsChecked(), - 'visscalesc' : self.visscalesc.GetValue(), - 'dofweightcb' : self.dofweightcb.IsChecked(), - 'dofweightsc' : self.dofweightsc.GetValue(), - 'fsaacb' : self.fsaacb.IsChecked(), - 'fsaach' : fsaavalue, - 'bloomscalecb' : self.bloomscalecb.IsChecked(), - 'bloomscalech' : bloomscalevalue, - 'bloomweightcb' : self.bloomweightcb.IsChecked(), - 'bloomweightsc' : self.bloomweightsc.GetValue(), - 'lodbiascb' : self.lodbiascb.IsChecked(), - 'lodbiassc' : self.lodbiassc.GetValue(), - 'renderscalecb' : self.renderscalecb.IsChecked(), - 'renderscalesc' : self.renderscalesc.GetValue(), - } - - def Deserialize(self, init): - self.visscalecb.SetValue(init.get('visscalecb', False)) - self.visscalesc.SetValue(init.get('visscalesc', 1.0)) - self.dofweightcb.SetValue(init.get('dofweightcb', False)) - self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) - self.fsaacb.SetValue(init.get('fsaacb', False)) - self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) - self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) - self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) - self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) - self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) - self.lodbiascb.SetValue(init.get('lodbiascb', False)) - self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) - self.renderscalecb.SetValue(init.get('renderscalecb', False)) - self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) - -####### Custom Bind -class CustomBindCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.customBindName = wx.TextCtrl(dialog, -1) - self.customBindName.SetHint('Custom Bind Text') - sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - return self.customBindName.GetValue() - - def Serialize(self): - return { 'customBindName': self.customBindName.GetValue() } - - def Deserialize(self,init): - if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) - -####### Emote -class EmoteCmd(PowerBindCmd): - def BuildUI(self, dialog): - emoteSizer = wx.BoxSizer(wx.HORIZONTAL) - self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") - emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - self.emoteName = wx.Button(dialog, -1, "...") - self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) - emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) - - return emoteSizer - - def MakeBindString(self): - displayedEmoteName = self.emoteName.GetLabel() - actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] - - return actualEmotePayload - - def Serialize(self): - return {'emoteName': self.emoteName.GetLabel()} - - def Deserialize(self, init): - if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) - -####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): - def BuildUI(self, dialog): - mainSizer = wx.BoxSizer(wx.VERTICAL) - - lbSizer = wx.BoxSizer(wx.HORIZONTAL) - lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") - lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - profiles = Profile.GetAllProfileBindsDirs() - - self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) - lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) - - mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") - self.lbResetCB.SetValue(True) - - mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - return mainSizer - - def MakeBindString(self): - - # If the specified binds directory disappeared between runs, we'd crash, so handle that. - if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' - - config = wx.ConfigBase.Get() - if config.Exists('GameBindPath'): - bindpath = config.Read('GameBindPath') - else: - bindpath = config.Read('BindPath') - - reset = "" - if self.lbResetCB.GetValue(): - reset = "keybind_reset$$" - - resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' - return reset + 'bindloadfile ' + str(resetfilepath) - - def Serialize(self): - return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), - 'ResetKeybinds' : self.lbResetCB.GetValue(), - } - - def Deserialize(self, init): - if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) - self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) - -####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' - -####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' - -####### SG Mode -class SGModeCmd(PowerBindCmd): - def BuildUI(self, dialog): - sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) - sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") - self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") - - sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) - - return sgmodeSizer - - def MakeBindString(self): - if self.sgmodeOnRB.GetValue(): - return 'sgmodeset 1' - elif self.sgmodeOffRB.GetValue(): - return 'sgmodeset 0' - else: - return 'sgmode' - - def Serialize(self): - if self.sgmodeOnRB.GetValue(): - val = "On" - elif self.sgmodeOffRB.GetValue(): - val = "Off" - else: - val = "Toggle" - - return {"value" : val} - - def Deserialize(self, init): - val = init.get('value', '') - if val == "On": - self.sgmodeOnRB.SetValue(True) - elif val == "Off": - self.sgmodeOffRB.SetValue(True) - else: - self.sgmodeToggleRB.SetValue(True) - -####### Target Custom -class TargetCustomCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetCustomSizer = wx.GridBagSizer(5,5) - targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), - flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) - self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetCustomModeChoice.SetSelection(0) - targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) - self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) - self.targetCustomOptionalName.SetHint("Optional name to match") - targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) - self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") - targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) - self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") - targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) - self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") - targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) - self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") - targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) - self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") - targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) - self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") - targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) - self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") - targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) - self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") - targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) - - targetCustomSizer.AddGrowableCol(2) - - return targetCustomSizer - - def MakeBindString(self): - choice = self.targetCustomModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - targetCommand = "targetcustom" + mode.lower() - - enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" - friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" - defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" - alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" - mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" - notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" - base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" - notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" - - name = self.targetCustomOptionalName.GetValue() - - return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" - - def Serialize(self): - return { - 'mode' : self.targetCustomModeChoice.GetSelection(), - 'enemy' : self.targetCustomCBEnemies. IsChecked(), - 'friend' : self.targetCustomCBFriends. IsChecked(), - 'defeated' : self.targetCustomCBDefeated. IsChecked(), - 'alive' : self.targetCustomCBAlive. IsChecked(), - 'mypet' : self.targetCustomCBMyPets. IsChecked(), - 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), - 'base' : self.targetCustomCBBaseItems. IsChecked(), - 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), - 'name' : self.targetCustomOptionalName.GetValue(), - } - - def Deserialize(self, init): - if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) - if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) - if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) - if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) - if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) - if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) - if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) - if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) - if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) - if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - - -####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) - targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetEnemyModeChoice.SetSelection(0) - targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetEnemySizer - - def MakeBindString(self): - choice = self.targetEnemyModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetenemy" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetEnemyModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) - -####### Target Friend -class TargetFriendCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) - targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetFriendModeChoice.SetSelection(0) - targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetFriendSizer - - def MakeBindString(self): - choice = self.targetFriendModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetfriend" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetFriendModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) - -####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): - def BuildUI(self, dialog): - teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], - style=wx.ALIGN_CENTER_VERTICAL) - self.teamPetSelectNumber.SetSelection(0) - teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) - - return teamPetSelectSizer - - def MakeBindString(self): - teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' - targetNumber = self.teamPetSelectNumber.GetSelection()+1 - - return f"{teamOrPet}select {targetNumber}" - - def Serialize(self): - return { - 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', - 'targetNum': self.teamPetSelectNumber.GetSelection(), - } - - def Deserialize(self, init): - ToP = init.get('teamOrPet', '') - if ToP == 'pet': - self.teamPetSelectPetRB.SetValue(True) - else: - self.teamPetSelectTeamRB.SetValue(True) - if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) - -####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' - -####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) - for _, types in GameData.Inspirations.items(): - for _, info in types.items(): - for insp in info['tiers']: - name = re.sub(' ', '', str(insp)) - icon = GetIcon(f'Inspirations/{name}') - self.useInspByNameModeChoice.Append(insp, icon) - self.useInspByNameModeChoice.SetSelection(0) - useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) - - return useInspByNameSizer - - def MakeBindString(self): - choice = self.useInspByNameModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "inspexecname " + mode.lower() - - def GetAllInsps(self): - Insplist = [] - for _, info in GameData.Inspirations.items(): - for insp in info['tiers']: - Insplist.append(insp) - Insplist.append("---") - Insplist.pop(-1) # snip the terminal "---" - - return Insplist - - def Serialize(self): - return { 'insp' : self.useInspByNameModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) - -####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnRow.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) - self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnCol.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) - - return useInspRowColumnSizer - - def MakeBindString(self): - row = self.useInspRowColumnRow.GetSelection()+1 - col = self.useInspRowColumnCol.GetSelection()+1 - - return f"inspexectray {col} {row}" - - def Serialize(self): - return { - 'col' : self.useInspRowColumnCol.GetSelection(), - 'row' : self.useInspRowColumnRow.GetSelection(), - } - - def Deserialize(self, init): - if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) - if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) - -####### Use Power -class UsePowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - outerSizer = wx.BoxSizer(wx.HORIZONTAL) - - usePowerSizer = wx.GridBagSizer(5,5) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBToggle, (0,1)) - self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOn, (0,2)) - self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOff, (0,3)) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerName = PowerPicker(dialog) - usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) - usePowerSizer.AddGrowableCol(3) - - outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) - - return outerSizer - - def MakeBindString(self): - if self.usePowerRBToggle.GetValue(): - method = "powexecname" - elif self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') - return '' - - return f"{method} {self.usePowerName.GetLabel()}" - - def Serialize(self): - if self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - method = "powexecname" - return { - 'method': method, - 'pname' : self.usePowerName.GetLabel(), - 'picon' : self.usePowerName.IconFilename - } - - def Deserialize(self, init): - method = init.get('method', '') - if method == 'powexectoggleon': - self.usePowerRBOn.SetValue(True) - elif method == 'powexectoggleoff': - self.usePowerRBOff.SetValue(True) - else: - self.usePowerRBToggle.SetValue(True) - if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) - -####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): - def BuildUI(self, dialog): - usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTrayTray = wx.Choice(dialog, -1, - choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', - 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) - self.usePowerFromTrayTray.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) - self.usePowerFromTraySlot.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return usePowerFromTraySizer - - def MakeBindString(self): - choice = self.usePowerFromTrayTray - tray = choice.GetSelection() - - choice = self.usePowerFromTraySlot - slot = choice.GetSelection()+1 - - mode = "slot" - mode2 = '' - if tray > 3: - mode = "tray" - mode2 = f" {tray - 3}" - elif tray == 3: - mode = "alt2slot" - elif tray == 2: - mode = "altslot" - - return f"powexec{mode} {slot}{mode2}" - - def Serialize(self): - return { - 'tray' : self.usePowerFromTrayTray.GetSelection(), - 'slot' : self.usePowerFromTraySlot.GetSelection(), - } - - def Deserialize(self, init): - if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) - if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) - -####### Window Color -class WindowColorCmd(PowerBindCmd): - def BuildUI(self, dialog): - windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) - borderSizer = wx.BoxSizer(wx.VERTICAL) - self.ColorBorder.SetSizer(borderSizer) - self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) - borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) - - windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) - - RGBASizer = wx.FlexGridSizer(3, 4, 5) - - RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) - self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) - self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - windowColorSizer.Add(RGBASizer) - - self.UpdateFromSlider() - - return windowColorSizer - - def MakeBindString(self): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - return f"windowcolor {Rval} {Gval} {Bval} {Aval}" - - def Serialize(self): - return { - 'Rval' : self.RSlider.GetValue(), - 'Gval' : self.GSlider.GetValue(), - 'Bval' : self.BSlider.GetValue(), - 'Aval' : self.ASlider.GetValue(), - } - - def Deserialize(self, init): - self.RSlider.SetValue(init['Rval']) - self.GSlider.SetValue(init['Gval']) - self.BSlider.SetValue(init['Bval']) - self.ASlider.SetValue(init['Aval']) - self.UpdateFromSlider() - - def UpdateFromSlider(self, _ = None): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RReadout.SetValue(Rval) - self.GReadout.SetValue(Gval) - self.BReadout.SetValue(Bval) - self.AReadout.SetValue(Aval) - self.ColorBorder.Refresh() - - def UpdateFromText(self, _ = None): - Rval = self.RReadout.GetValue() - Gval = self.GReadout.GetValue() - Bval = self.BReadout.GetValue() - Aval = self.AReadout.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RSlider.SetValue(Rval) - self.GSlider.SetValue(Gval) - self.BSlider.SetValue(Bval) - self.ASlider.SetValue(Aval) - self.ColorBorder.Refresh() +from UI.PowerBinderCommand import PowerBinderCommand ####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): +class WindowSaveLoadCmd(PowerBinderCommand): + Name = "Window Save / Load" + Menu = "Graphics / UI" + def BuildUI(self, dialog): sizer = wx.BoxSizer(wx.HORIZONTAL) @@ -1583,218 +32,3 @@ def Serialize(self): def Deserialize(self, init): self.CommandChoice.SetSelection(init.get('command', 0)) self.FilePath.SetValue(init.get('filename', '')) - -####### Window Toggle -class WindowToggleCmd(PowerBindCmd): - def BuildUI(self, dialog): - self.WindowNames = { - 'Actions' : 'actions', - 'Auction House' : 'ah', - 'Badge' : 'badge', - 'Channel Search' : 'chansearch', - 'Chat' : 'chat', - 'Custom Chat 1' : 'chat1', - 'Custom Chat 2' : 'chat2', - 'Custom Chat 3' : 'chat3', - 'Custom Chat 4' : 'chat4', - 'Clues' : 'clue', - 'Combat Numbers' : 'combatnumbers', - 'Contacts' : 'contact', - 'Contact Finder' : 'contactfinder', - 'Costumes' : 'costume', - 'Email' : 'email', - 'Enhancements' : 'enhancements', - 'Friends' : 'friend', - 'Group' : 'group', - 'Help' : 'helpwindow', - 'Incarnate' : 'incarnate', - 'Inspirations' : 'insp', - 'League' : 'league', - 'LFG' : 'lfg', - 'Map' : 'map', - 'Mission' : 'mission', - 'Nav / Compass' : 'nav', - 'Options' : 'options', - 'Pets' : 'pet', - 'Petition' : 'petition', - 'Power Tray' : 'powers', - 'Power List' : 'powerlist', - 'Quit' : 'quit', - 'Recipes' : 'recipe', - 'Salvage' : 'salvage', - 'Search' : 'search', - 'Supergroup' : 'sg', - 'Target' : 'target', - 'Team' : 'team', - 'Tray' : 'tray', - 'Tray1' : 'tray1', - 'Tray2' : 'tray2', - 'Tray3' : 'tray3', - 'Tray4' : 'tray4', - 'Tray5' : 'tray5', - 'Tray6' : 'tray6', - 'Tray7' : 'tray7', - 'Tray8' : 'tray8', - 'Vault' : 'vault', - } - - self.ShortToggleCommands = { - 'Auction House' : 'ah', - 'Chat' : 'chat', - 'Help' : 'helpwindow', - 'Map' : 'map', - 'Nav / Compass' : 'nav', - 'Power Tray' : 'powers', - 'Target' : 'target', - 'Tray' : 'tray', - } - - windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) - windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) - self.windowToggleTray.SetSelection(0) - windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.windowShowRB = wx.RadioButton(dialog, -1, "Show") - self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") - - windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) - - return windowToggleSizer - - def MakeBindString(self): - choice = self.windowToggleTray - index = choice.GetSelection() - windowdesc = choice.GetString(index) - windowname = self.WindowNames[windowdesc] - - if self.windowShowRB.GetValue(): - return 'show ' + windowname - elif self.windowHideRB.GetValue(): - return 'windowhide ' + windowname - else: - if shortcmd := self.ShortToggleCommands.get(windowdesc, None): - return shortcmd - else: - return 'toggle ' + windowname - - - def Serialize(self): - choice = self.windowToggleTray - if self.windowShowRB.GetValue(): - action = "Show" - elif self.windowHideRB.GetValue(): - action = "Hide" - else: - action = "Toggle" - return { - 'window': choice.GetString(choice.GetSelection()), - 'action': action, - } - - def Deserialize(self, init): - choice = self.windowToggleTray - if window := init.get('window', ''): - if isinstance(window, int): - choice.SetSelection(window) - else: - choice.SetSelection(choice.FindString(window)) - - if choice.GetSelection() == wx.NOT_FOUND: - choice.SetSelection(0) - - action = init.get('action', '') - if action == "Show": - self.windowShowRB.SetValue(True) - elif action == "Hide": - self.windowHideRB.SetValue(True) - else: - self.windowToggleRB.SetValue(True) - - -# Must always add to this list when adding a new command class above -menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], - # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, - # but I'm leaving it here to remind myself that we do that. - } - -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderCommand/WindowToggleCmd.py b/UI/PowerBinderCommand/WindowToggleCmd.py index 4c02ab7..5711038 100644 --- a/UI/PowerBinderCommand/WindowToggleCmd.py +++ b/UI/PowerBinderCommand/WindowToggleCmd.py @@ -1,1591 +1,11 @@ import wx -import re -import UI -import UI.EmotePicker -from UI.ControlGroup import ControlGroup -from UI.PowerPicker import PowerPicker -from Help import HelpButton -import wx.adv -from wx.adv import BitmapComboBox, EditableListBox -from pathlib import PureWindowsPath -import GameData -import Profile -from Icon import GetIcon - -class PowerBinderDialog(wx.Dialog): - def __init__(self, parent, button, init = {}): - wx.Dialog.__init__(self, parent, -1, "PowerBinder", style = wx.DEFAULT_DIALOG_STYLE) - - self.Page = parent.Page - self.EditDialog = PowerBinderEditDialog(self) - self.Button = button - self.AddStepMenu = self.makeAddStepMenu() - - sizer = wx.BoxSizer(wx.VERTICAL); - self.mainSizer = sizer - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - # choiceSizer.Add(wx.StaticText(self, -1, "Add Step:"), 0, wx.ALIGN_CENTER_VERTICAL) - # self.bindChoice = wx.Choice(self, -1, choices = [cmd for cmd in commandClasses]) - # self.bindChoice.Bind(wx.EVT_CHOICE, self.OnBindChoice) - #choiceSizer.Add(self.bindChoice, 1, wx.LEFT, 10) - AddStepButton = wx.Button(self, -1, 'Add Step') - AddStepButton.Bind(wx.EVT_BUTTON, self.OnAddStepButton) - AddStepButton.Bind(wx.EVT_MENU, self.OnAddStepMenu) - choiceSizer.Add(AddStepButton, 1, wx.LEFT, 10) - choiceSizer.Add(HelpButton(self, "PowerBinder.html", type="window"), 0, wx.LEFT, 10) - sizer.Add(choiceSizer, 1, wx.EXPAND|wx.BOTTOM, 10) - - rearrangeCtrl = wx.BoxSizer(wx.HORIZONTAL) - - self.RearrangeList = wx.RearrangeList(self, -1, size=(550,400)) - self.RearrangeList.Bind(wx.EVT_LISTBOX, self.OnListSelect) - self.RearrangeList.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRearrangeEdit) - rearrangeCtrl.Add(self.RearrangeList, 1) - - rearrangeButtons = wx.BoxSizer(wx.VERTICAL) - self.DelButton = wx.Button(self, -1, "Delete") - self.DelButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDelete) - self.EditButton = wx.Button(self, -1, "Edit") - self.EditButton.Bind(wx.EVT_BUTTON, self.OnRearrangeEdit) - self.EditButton.Disable() - upButton = wx.Button(self, -1, "\u25B2") - upButton.Bind(wx.EVT_BUTTON, self.OnRearrangeUp) - downButton = wx.Button(self, -1, "\u25BC") - downButton.Bind(wx.EVT_BUTTON, self.OnRearrangeDown) - rearrangeButtons.Add(upButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(downButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.EditButton, 1, wx.BOTTOM, 10) - rearrangeButtons.Add(self.DelButton, 1, wx.BOTTOM, 10) - rearrangeCtrl.Add(rearrangeButtons, 0, wx.LEFT, 10) - - sizer.Add(rearrangeCtrl, 0, wx.EXPAND|wx.TOP|wx.BOTTOM) - - choiceSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.BindStringDisplay = wx.TextCtrl(self, -1) - self.BindStringDisplay.Disable() - choiceSizer.Add(wx.StaticText(self, -1, "Bind String:"), 0, - wx.ALIGN_CENTER_VERTICAL) - choiceSizer.Add(self.BindStringDisplay, 1, wx.LEFT, 10) - - sizer.Add(choiceSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 16) - - sizer.Add(self.CreateStdDialogButtonSizer(wx.OK|wx.CANCEL), 0, wx.EXPAND) - - # need to dig around and get the OK button since we show this dialog modelessly now. - okButton = self.FindWindow(self.GetAffirmativeId()) - okButton.Bind(wx.EVT_BUTTON, self.OnOKButton) - - # Wrap everything in a vbox to add some padding - vbox = wx.BoxSizer(wx.VERTICAL); - vbox.Add(sizer, 0, wx.EXPAND|wx.ALL, 10); - - self.SetSizerAndFit(vbox); - self.Layout() - self.Fit() - self.SetFocus() - - # if we are loading from profile, ie, have "init", build the list from it - if init: self.LoadFromData(init) - - def LoadFromData(self, init): - for item in init: - for type, data in item.items(): - commandClass = commandClasses.get(type, None) - if not commandClass: - commandClass = deprecatedCommandClasses.get(type, None) - if not commandClass: - wx.LogError(f"Profile contained unknown custom bind command class {type}; ignoring it and continuing.") - continue - newCommand = commandClass(self.EditDialog, data) - index = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.SetClientData(index, newCommand) - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10) - self.EditDialog.mainSizer.Hide(newCommand.UI) - self.UpdateBindStringDisplay() - - def SaveToData(self): - data = [] - index = 0 - for _ in self.RearrangeList.GetItems(): - # check whether we have an object already attached to this choice - cmdObject = self.RearrangeList.GetClientData(index) - commandClassName = commandRevClasses[type(cmdObject)] - data.append({commandClassName: cmdObject.Serialize()}) - index = index + 1 - return data - - def OnAddStepButton(self, evt): - button = evt.EventObject - if not self.AddStepMenu: - self.AddStepMenu = self.makeAddStepMenu() - button.PopupMenu(self.AddStepMenu) - - - def OnOKButton(self, _): - if self.Button.tgtTxtCtrl: - bindString = self.MakeBindString() - if bindString != self.Button.tgtTxtCtrl.GetValue(): - self.Button.tgtTxtCtrl.SetValue(bindString) - wx.App.Get().Main.Profile.SetModified() - self.Close() - - def OnRearrangeDelete(self, _): - current = self.RearrangeList.GetSelection() - if current == wx.NOT_FOUND: return - - self.RearrangeList.Delete(current) - self.UpdateBindStringDisplay() - - def OnRearrangeUp(self, _): - self.RearrangeList.MoveCurrentUp() - self.UpdateBindStringDisplay() - - def OnRearrangeDown(self, _): - self.RearrangeList.MoveCurrentDown() - self.UpdateBindStringDisplay() - - def OnRearrangeEdit(self, _): - index = self.RearrangeList.GetSelection() - - # check whether we have an object already attached to this choice - cmdObject = None - try: - cmdObject = self.RearrangeList.GetClientData(index) - except Exception: - pass - - if cmdObject: - self.ShowEditDialogFor(cmdObject) - self.RearrangeList.SetString(index, cmdObject.MakeListEntryString()) - else: - print("cmdObject was None") - self.UpdateBindStringDisplay() - - # OnAddStepMenu creates a new step and adds it to the rearrangelist - def OnAddStepMenu(self, evt): - menuitem = self.AddStepMenu.FindItemById(evt.GetId()) - chosenName = menuitem.GetItemLabel() - - # make a new command object, attached to the parent dialog - newCommandClass = commandClasses[chosenName] - newCommand = newCommandClass(self.EditDialog) - - # show the edit dialog if this command needs it - if newCommand.UI: - self.EditDialog.mainSizer.Insert(0, newCommand.UI, 1, wx.ALL|wx.EXPAND, 10) - if (self.ShowEditDialogFor(newCommand) == wx.ID_CANCEL): - self.EditDialog.mainSizer.Remove(newCommand.UI) - return - - newBindIndex = self.RearrangeList.Append(newCommand.MakeListEntryString()) - self.RearrangeList.Select(newBindIndex) - self.RearrangeList.SetClientData(newBindIndex, newCommand) - - self.OnListSelect() - self.UpdateBindStringDisplay() - - def OnListSelect(self, _ = None): - selected = self.RearrangeList.GetSelection() - - if selected != wx.NOT_FOUND: - selCommand = self.RearrangeList.GetClientData(selected) - if selCommand.UI: - self.EditButton.Enable() - else: - self.EditButton.Disable() - - def UpdateBindStringDisplay(self): - self.BindStringDisplay.SetValue(self.MakeBindString()) - self.BindStringDisplay.SetToolTip(self.MakeBindString()) - - def MakeBindString(self): - cmdBindStrings = [] - for index in range(self.RearrangeList.GetCount()): - c = self.RearrangeList.GetClientData(index) - if c: cmdBindStrings.append(c.MakeBindString()) - - bindstring = ('$$'.join(cmdBindStrings)) - return bindstring - - def ShowEditDialogFor(self, command): - if not command.UI: return - - self.EditDialog.mainSizer.Show(command.UI) - - self.EditDialog.Layout() - self.EditDialog.Fit() - - self.EditDialog.SetTitle(f'Editing Step "{commandRevClasses[type(command)]}"') - returnval = self.EditDialog.ShowModal() - - self.EditDialog.mainSizer.Hide(command.UI) - - return returnval - - def makeAddStepMenu(self): - - stepMenu = wx.Menu() - - for subname in menuStructure: - submenu = wx.Menu() - stepMenu.AppendSubMenu(submenu, subname) - for classname in menuStructure[subname]: - submenu.Append(wx.ID_ANY, classname) - - stepMenu.Append(wx.ID_ANY, 'Custom Bind') - - return stepMenu - -class PowerBinderButton(wx.BitmapButton): - - def __init__(self, parent, tgtTxtCtrl, init = {}): - wx.BitmapButton.__init__(self, parent, -1, bitmap = GetIcon('UI/gear')) - self.Init = init - self.Dialog = None - self.DialogParent = parent - - self.tgtTxtCtrl = tgtTxtCtrl - self.Bind(wx.EVT_BUTTON, self.PowerBinderEventHandler) - self.SetToolTip("Launch PowerBinder") - - def PowerBinderEventHandler(self, _): - self.PowerBinderDialog().Show() - - def LoadFromData(self, data): - self.PowerBinderDialog().LoadFromData(data) - - def SaveToData(self): - return self.PowerBinderDialog().SaveToData() - - def PowerBinderDialog(self): - if not self.Dialog: - self.Dialog = PowerBinderDialog(self.DialogParent, self, self.Init) - return self.Dialog - - -class PowerBinderEditDialog(wx.Dialog): - def __init__(self, parent): - wx.Dialog.__init__(self, parent, -1, "Edit Step", - style = wx.DEFAULT_DIALOG_STYLE) - - outerSizer = wx.BoxSizer(wx.VERTICAL) - - self.mainSizer = wx.BoxSizer(wx.VERTICAL) - self.mainSizer.SetMinSize([500, 150]) - - self.Page = parent.Page - - self.mainSizer.Add( - self.CreateSeparatedButtonSizer(wx.OK|wx.CANCEL), - 0, wx.EXPAND|wx.ALL, 10) - - outerSizer.Add(self.mainSizer, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 3) - - self.SetSizerAndFit(outerSizer) - self.Layout() - self.Fit() - -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" - - -####### Away From Keyboard -class AFKCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.Groups = {} - self.AttributeTable = { - 'Base' : { - 'Current Hit Points' : 'NT H', - 'Max Hit Points' : 'X H', - 'Current Endurance' : 'T E', - 'Max Endurance' : 'X EN', - 'Regeneration Rate' : 'N RAT', - 'Recovery Rate' : 'Y RA', - 'Endurance Consumption' : 'SU', - 'ToHit Bonus' : 'T B', - 'Accuracy Bonus' : 'CC', - 'Last Hit Chance' : 'T C', - 'Damage Bonus' : 'DA', - 'Healing Bonus' : 'NG B', - 'Recharge Time Bonus' : 'ME B', - 'Endurance Discount' : 'CE DIS', - 'Stealth Radius (PvP)' : 'PVP', - 'Stealth Radius (PvE)' : 'PVE', - 'Perception Radius' : 'RC', - 'Range Bonus' : 'GE B', - 'Threat Level' : 'AT L', - 'Experience to Next Level' : 'XT', - 'Experience Debt' : 'XP', - 'Influence / Infamy' : 'INF', - 'Inherent' : 'NH', - }, - 'Movement Speed' : { - 'Flying Speed' : 'FL', - 'Jumping Speed' : 'PI', - 'Max Jump Height' : 'X J', - 'Run Speed' : 'RU', - }, - 'Damage Resistance' : { - 'Smashing Resistance' : 'G R', - 'Lethal Resistance' : 'L R', - 'Fire Resistance' : 'RE R', - 'Cold Resistance' : 'COLD R', - 'Energy Resistance' : 'DamageType[4]', - 'Negative Energy Resistance' : 'GY R', - 'Psyonic Resistance' : 'NIC R', - 'Toxic Resistance' : 'XIC R', - }, - 'Defense' : { - 'Base Defense' : 'BAS', - 'Ranged Defense' : 'ED', - 'Melee Defense' : 'MEL', - 'AoE Defense' : '2', - 'Smashing Defense' : '3', - 'Lethal Defense' : '4', - 'Fire Defense' : '5', - 'Cold Defense' : '6', - 'Energy Defense' : '7', - 'Negative Energy Defense' : '8', - 'Psionic Defense' : '9', - 'Toxic Defense' : '1', - }, - 'Debuff Resistance' : { - 'Regeneration Resistance' : 'ON R', - 'Recovery Resistance' : 'RY R', - 'To Hit Resistance' : 'IT R', - 'Defense Resistance' : 'NSE RES', - }, - 'Status Effect Protection' : { - 'Hold Protection' : 'D P', - 'Immobilize Protection' : 'LIZE P', - 'Stun Protection' : 'N P', - 'Sleep Protection' : 'P P', - 'Knockback Protection' : 'K P', - 'Confuse Protection' : 'SE P', - 'Terrorize Protection' : 'ZE P', - 'Repel Protection' : 'EL P', - 'Teleport Protection' : 'T P', - }, - 'Status Effect Resistance' : { - 'Hold Resistance' : 'D R', - 'Immobilize Resistance' : 'LIZE R', - 'Stun Resistance' : 'N R', - 'Sleep Resistance' : 'P R', - 'Knockback Resistance' : 'K R', - 'Confuse Resistance' : 'SE R', - 'Terrorize Resistance' : 'ZE R', - 'Placate Resistance' : 'TE R', - 'Taunt Resistance' : 'NT R', - }, - 'Miscellaneous' : { - 'Level Shift' : 'L S', - }, - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.AttributeMenu = wx.Menu() - for group, controls in self.AttributeTable.items(): - submenu = wx.Menu() - self.AttributeMenu.AppendSubMenu(submenu, group) - for cb in controls: - submenu.Append(wx.ID_ANY, cb) - - self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) - - self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) - groupSizer.Add(self.editbox) - - newButton = self.editbox.GetNewButton() - newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) - - return groupSizer - - def MakeBindString(self): - map = {} - bindstrings = [] - for _, controls in self.AttributeTable.items(): - for cb, data in controls.items(): - map[cb] = data - - for string in self.editbox.GetStrings(): - if string: - bindstrings.append(f'monitorattribute {map[string]}') - - return '$$'.join(bindstrings) - - def Serialize(self): - return { - 'attributes' : self.editbox.GetStrings() - } - - def Deserialize(self, init): - self.editbox.SetStrings(init.get('attributes', [])) - - def OnNewButton(self, evt): - evt.GetEventObject().PopupMenu(self.AttributeMenu) - - def OnMenuItem(self, evt): - menuitem = evt.EventObject.FindItemById(evt.GetId()) - existingstrings = self.editbox.GetStrings() - existingstrings.append(menuitem.GetItemLabel()) - self.editbox.SetStrings(existingstrings) - -####### Auto Power -class AutoPowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) - autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.autoPowerName = PowerPicker(dialog) - autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) - - return autoPowerSizer - - def MakeBindString(self): - return f"powexecauto {self.autoPowerName.GetLabel()}" - - def Serialize(self): - return { - 'pname' : self.autoPowerName.GetLabel(), - 'picon' : self.autoPowerName.IconFilename - } - - def Deserialize(self, init): - if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.buffDisplayMap = { - 'Status Window' : { - 'Hide Auto' : 1, - 'Hide Toggles' : 2, - 'No Blinking' : 4, - 'No Stacking' : 8, - 'Numeric Stacking' : 16, - 'Hide Buff Numbers' : 32, - 'Stop Sending Buffs' : 64, - }, - 'Group Window' : { - 'Hide Auto' : 256, - 'Hide Toggles' : 512, - 'No Blinking' : 1024, - 'No Stacking' : 2048, - 'Numeric Stacking' : 4096, - 'Hide Buff Numbers' : 8192, - 'Stop Sending Buffs' : 16384, - }, - 'Pet Window' : { - 'Hide Auto' : 65536, - 'Hide Toggles' : 131072, - 'No Blinking' : 262144, - 'No Stacking' : 524288, - 'Numeric Stacking' : 1048576, - 'Hide Buff Numbers' : 2097152, - 'Stop Sending Buffs' : 4194304, - }, - } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - for group, controls in self.buffDisplayMap.items(): - self.Groups[group] = ControlGroup(dialog, self.Page, label = group) - groupid = self.Groups[group].GetStaticBox().GetId() - for cb, data in controls.items(): - self.Groups[group].AddControl( - ctlType = 'checkbox', - ctlName = f"{groupid}_{group}_{cb}", - label = cb, - data = data, - ) - - groupSizer.Add(self.Groups[group]) - - return groupSizer - - def CalculateValue(self): - page = wx.App.Get().Main.Profile.CustomBinds - - total = 0 - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] - if checkbox.IsChecked(): - total = total + checkbox.Data - return total - - def MakeBindString(self): - return f"optionset buffsettings {self.CalculateValue()}" - - def Serialize(self): - return { 'value' : self.CalculateValue() } - - def Deserialize(self, init): - value = init.get('value', 0) - - value = value or 0 # in case we had for some reason 'None' stashed in the init values - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] - checkbox.SetValue( checkbox.Data & value ) - -####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - chatCommandSizer = wx.GridBagSizer(5, 5) - self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") - chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) - # row 1 - self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) - self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) - self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) - # row 2 - self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) - self.chatCommandDuration.SetRange(1, 20) - self.chatCommandDuration.SetValue(7) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandDuration, (2,1)) - self.chatCommandChatSize = wx.Choice(dialog, -1, - choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) - self.chatCommandChatSize.SetSelection(5) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) - self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) - self.chatCommandChannel.SetSelection(0) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChannel, (2,5)) - # row 3 - self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") - chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) - self.chatCommandMessage = wx.TextCtrl(dialog, -1) - self.chatCommandMessage.SetHint('Chat Command Text') - chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) - - return chatCommandSizer - - def MakeBindString(self): - duration = self.chatCommandDuration.GetValue() - - choice = self.chatCommandChatSize - index = choice.GetSelection() - size = choice.GetString(index) - - duration = f"" if duration != 7 else "" - size = f"" if size != "1" else "" - - bdcolor = fgcolor = bgcolor = '' - if self.chatCommandUseColorsCB.IsChecked(): - bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - - bdcolor = f"" - fgcolor = f"" - bgcolor = f"" - - beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' - text = self.chatCommandMessage.GetValue() - - choice = self.chatCommandChannel - index = choice.GetSelection() - channel = choice.GetString(index) - - return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" - - def Serialize(self): - return { - 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), - 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), - 'channel' : self.chatCommandChannel .GetSelection(), - 'size' : self.chatCommandChatSize.GetSelection(), - 'duration' : self.chatCommandDuration.GetValue(), - 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'text' : self.chatCommandMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) - if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) - if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) - if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) - if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) - if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) - if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) - if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) - if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - - -####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): - def BuildUI(self, dialog): - chatCommandGlobalSizer = wx.GridBagSizer(5,5) - - self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") - chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) - - self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalChannel.SetHint("Channel") - chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) - - self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') - chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) - - chatCommandGlobalSizer.AddGrowableCol(1) - - return chatCommandGlobalSizer - - def MakeBindString(self): - useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() - channel = self.chatCommandGlobalChannel.GetValue() - message = self.chatCommandGlobalMessage.GetValue() - - preface = "beginchat /" if useBeginchat else "" - - return f'{preface}send "{channel}" {message}' - - def Serialize(self): - return { - 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), - 'channel' : self.chatCommandGlobalChannel.GetValue(), - 'message' : self.chatCommandGlobalMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) - if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) - if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) - -#######Costume Change -class CostumeChangeCmd(PowerBindCmd): - def BuildUI(self, dialog): - costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeCostume = wx.Choice(dialog, -1, - choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) - self.costumeChangeCostume.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeEmote = wx.Choice(dialog, -1, - choices = GameData.Emotes['costumechange']) - self.costumeChangeEmote.Insert("- None -", 0) - self.costumeChangeEmote.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return costumeChangeSizer - - def MakeBindString(self): - costumeNumber = self.costumeChangeCostume.GetSelection() - costumeEmote = self.costumeChangeEmote.GetSelection() - - if costumeEmote: # None, or 0 == "- None -" - ccCmd = 'cce' - emoteName = self.costumeChangeEmote.GetString(costumeEmote) - emoteName = " CC" + emoteName.replace(" ","") - else: - ccCmd = 'cc' - emoteName = '' - - return f"{ccCmd} {costumeNumber}{emoteName}" - - def Serialize(self): - return{ - 'costumeNumber': self.costumeChangeCostume.GetSelection(), - 'costumeEmote' : self.costumeChangeEmote.GetSelection(), - } - - def Deserialize(self, init): - if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) - if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) - -####### Movement Command -class MovementCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - self.plusbutton.SetValue(True) - - self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.commandchoice = wx.Choice(dialog, choices = [ - "forward", "left", "right", "backward", "up", "down", - "turnleft", "turnright", "first", "autorun", "clicktomove", - ],) - sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) - self.commandchoice.SetSelection(0) - - self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - pre = post = '' - if self.plusbutton.GetValue() : pre = "+" - elif self.plusplusbutton.GetValue() : pre = "++" - elif self.minusbutton.GetValue() : pre = "-" - elif self.zerobutton.GetValue() : post = " 0" - elif self.onebutton.GetValue() : post = " 1" - - command = self.commandchoice.GetString(self.commandchoice.GetSelection()) - - return f"{pre}{command}{post}" - - def Serialize(self): - mod = '' - if self.plusbutton.GetValue() : mod = "plus" - elif self.plusplusbutton.GetValue() : mod = "plusplus" - elif self.minusbutton.GetValue() : mod = "minus" - elif self.zerobutton.GetValue() : mod = "zero" - elif self.onebutton.GetValue() : mod = "one" - - return { - 'mod' : mod, - 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), - } - - def Deserialize(self, init): - mod = init.get('mod', 'plus') - - if mod == 'plus' : self.plusbutton.SetValue(True) - elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) - elif mod == 'minus' : self.minusbutton.SetValue(True) - elif mod == 'zero' : self.zerobutton.SetValue(True) - elif mod == 'one' : self.onebutton.SetValue(True) - - self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) - -####### Graphics Command -class GraphicsCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.FlexGridSizer(2) - - self.visscalecb = wx.CheckBox(dialog, label = "visscale") - sizer.Add(self.visscalecb) - self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) - sizer.Add(self.visscalesc) - - self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") - sizer.Add(self.dofweightcb) - self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) - sizer.Add(self.dofweightsc) - - self.fsaacb = wx.CheckBox(dialog, label = "fsaa") - sizer.Add(self.fsaacb) - self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) - self.fsaach.SetSelection(0) - sizer.Add(self.fsaach) - - self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") - sizer.Add(self.bloomscalecb) - self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) - self.bloomscalech.SetSelection(0) - sizer.Add(self.bloomscalech) - - self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") - sizer.Add(self.bloomweightcb) - self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) - sizer.Add(self.bloomweightsc) - - self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") - sizer.Add(self.lodbiascb) - self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) - sizer.Add(self.lodbiassc) - - self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") - sizer.Add(self.renderscalecb) - self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) - sizer.Add(self.renderscalesc) - - return sizer - - def MakeBindString(self): - # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. - bindstrings = [] - if self.visscalecb.IsChecked(): - bindstrings.append("visscale " + str(self.visscalesc.GetValue())) - if self.dofweightcb.IsChecked(): - bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) - if self.fsaacb.IsChecked(): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bindstrings.append("fsaa " + fsaavalue) - if self.bloomscalecb.IsChecked(): - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - bindstrings.append("bloomscale " + bloomscalevalue) - if self.bloomweightcb.IsChecked(): - bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) - if self.lodbiascb.IsChecked(): - bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) - if self.renderscalecb.IsChecked(): - bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) - - return '$$'.join(bindstrings) - - def Serialize(self): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - return { - 'visscalecb' : self.visscalecb.IsChecked(), - 'visscalesc' : self.visscalesc.GetValue(), - 'dofweightcb' : self.dofweightcb.IsChecked(), - 'dofweightsc' : self.dofweightsc.GetValue(), - 'fsaacb' : self.fsaacb.IsChecked(), - 'fsaach' : fsaavalue, - 'bloomscalecb' : self.bloomscalecb.IsChecked(), - 'bloomscalech' : bloomscalevalue, - 'bloomweightcb' : self.bloomweightcb.IsChecked(), - 'bloomweightsc' : self.bloomweightsc.GetValue(), - 'lodbiascb' : self.lodbiascb.IsChecked(), - 'lodbiassc' : self.lodbiassc.GetValue(), - 'renderscalecb' : self.renderscalecb.IsChecked(), - 'renderscalesc' : self.renderscalesc.GetValue(), - } - - def Deserialize(self, init): - self.visscalecb.SetValue(init.get('visscalecb', False)) - self.visscalesc.SetValue(init.get('visscalesc', 1.0)) - self.dofweightcb.SetValue(init.get('dofweightcb', False)) - self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) - self.fsaacb.SetValue(init.get('fsaacb', False)) - self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) - self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) - self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) - self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) - self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) - self.lodbiascb.SetValue(init.get('lodbiascb', False)) - self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) - self.renderscalecb.SetValue(init.get('renderscalecb', False)) - self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) - -####### Custom Bind -class CustomBindCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.customBindName = wx.TextCtrl(dialog, -1) - self.customBindName.SetHint('Custom Bind Text') - sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - return self.customBindName.GetValue() - - def Serialize(self): - return { 'customBindName': self.customBindName.GetValue() } - - def Deserialize(self,init): - if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) - -####### Emote -class EmoteCmd(PowerBindCmd): - def BuildUI(self, dialog): - emoteSizer = wx.BoxSizer(wx.HORIZONTAL) - self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") - emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - self.emoteName = wx.Button(dialog, -1, "...") - self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) - emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) - - return emoteSizer - - def MakeBindString(self): - displayedEmoteName = self.emoteName.GetLabel() - actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] - - return actualEmotePayload - - def Serialize(self): - return {'emoteName': self.emoteName.GetLabel()} - - def Deserialize(self, init): - if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) - -####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): - def BuildUI(self, dialog): - mainSizer = wx.BoxSizer(wx.VERTICAL) - - lbSizer = wx.BoxSizer(wx.HORIZONTAL) - lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") - lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - profiles = Profile.GetAllProfileBindsDirs() - - self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) - lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) - - mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") - self.lbResetCB.SetValue(True) - - mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - return mainSizer - - def MakeBindString(self): - - # If the specified binds directory disappeared between runs, we'd crash, so handle that. - if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' - - config = wx.ConfigBase.Get() - if config.Exists('GameBindPath'): - bindpath = config.Read('GameBindPath') - else: - bindpath = config.Read('BindPath') - - reset = "" - if self.lbResetCB.GetValue(): - reset = "keybind_reset$$" - - resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' - return reset + 'bindloadfile ' + str(resetfilepath) - - def Serialize(self): - return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), - 'ResetKeybinds' : self.lbResetCB.GetValue(), - } - - def Deserialize(self, init): - if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) - self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) - -####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' - -####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' - -####### SG Mode -class SGModeCmd(PowerBindCmd): - def BuildUI(self, dialog): - sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) - sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") - self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") - - sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) - - return sgmodeSizer - - def MakeBindString(self): - if self.sgmodeOnRB.GetValue(): - return 'sgmodeset 1' - elif self.sgmodeOffRB.GetValue(): - return 'sgmodeset 0' - else: - return 'sgmode' - - def Serialize(self): - if self.sgmodeOnRB.GetValue(): - val = "On" - elif self.sgmodeOffRB.GetValue(): - val = "Off" - else: - val = "Toggle" - - return {"value" : val} - - def Deserialize(self, init): - val = init.get('value', '') - if val == "On": - self.sgmodeOnRB.SetValue(True) - elif val == "Off": - self.sgmodeOffRB.SetValue(True) - else: - self.sgmodeToggleRB.SetValue(True) - -####### Target Custom -class TargetCustomCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetCustomSizer = wx.GridBagSizer(5,5) - targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), - flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) - self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetCustomModeChoice.SetSelection(0) - targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) - self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) - self.targetCustomOptionalName.SetHint("Optional name to match") - targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) - self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") - targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) - self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") - targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) - self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") - targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) - self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") - targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) - self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") - targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) - self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") - targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) - self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") - targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) - self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") - targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) - - targetCustomSizer.AddGrowableCol(2) - - return targetCustomSizer - - def MakeBindString(self): - choice = self.targetCustomModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - targetCommand = "targetcustom" + mode.lower() - - enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" - friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" - defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" - alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" - mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" - notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" - base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" - notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" - - name = self.targetCustomOptionalName.GetValue() - - return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" - - def Serialize(self): - return { - 'mode' : self.targetCustomModeChoice.GetSelection(), - 'enemy' : self.targetCustomCBEnemies. IsChecked(), - 'friend' : self.targetCustomCBFriends. IsChecked(), - 'defeated' : self.targetCustomCBDefeated. IsChecked(), - 'alive' : self.targetCustomCBAlive. IsChecked(), - 'mypet' : self.targetCustomCBMyPets. IsChecked(), - 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), - 'base' : self.targetCustomCBBaseItems. IsChecked(), - 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), - 'name' : self.targetCustomOptionalName.GetValue(), - } - - def Deserialize(self, init): - if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) - if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) - if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) - if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) - if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) - if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) - if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) - if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) - if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) - if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - - -####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) - targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetEnemyModeChoice.SetSelection(0) - targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetEnemySizer - - def MakeBindString(self): - choice = self.targetEnemyModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetenemy" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetEnemyModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) - -####### Target Friend -class TargetFriendCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) - targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetFriendModeChoice.SetSelection(0) - targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetFriendSizer - - def MakeBindString(self): - choice = self.targetFriendModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetfriend" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetFriendModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) - -####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): - def BuildUI(self, dialog): - teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], - style=wx.ALIGN_CENTER_VERTICAL) - self.teamPetSelectNumber.SetSelection(0) - teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) - - return teamPetSelectSizer - - def MakeBindString(self): - teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' - targetNumber = self.teamPetSelectNumber.GetSelection()+1 - - return f"{teamOrPet}select {targetNumber}" - - def Serialize(self): - return { - 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', - 'targetNum': self.teamPetSelectNumber.GetSelection(), - } - - def Deserialize(self, init): - ToP = init.get('teamOrPet', '') - if ToP == 'pet': - self.teamPetSelectPetRB.SetValue(True) - else: - self.teamPetSelectTeamRB.SetValue(True) - if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) - -####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' - -####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) - for _, types in GameData.Inspirations.items(): - for _, info in types.items(): - for insp in info['tiers']: - name = re.sub(' ', '', str(insp)) - icon = GetIcon(f'Inspirations/{name}') - self.useInspByNameModeChoice.Append(insp, icon) - self.useInspByNameModeChoice.SetSelection(0) - useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) - - return useInspByNameSizer - - def MakeBindString(self): - choice = self.useInspByNameModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "inspexecname " + mode.lower() - - def GetAllInsps(self): - Insplist = [] - for _, info in GameData.Inspirations.items(): - for insp in info['tiers']: - Insplist.append(insp) - Insplist.append("---") - Insplist.pop(-1) # snip the terminal "---" - - return Insplist - - def Serialize(self): - return { 'insp' : self.useInspByNameModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) - -####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnRow.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) - self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnCol.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) - - return useInspRowColumnSizer - - def MakeBindString(self): - row = self.useInspRowColumnRow.GetSelection()+1 - col = self.useInspRowColumnCol.GetSelection()+1 - - return f"inspexectray {col} {row}" - - def Serialize(self): - return { - 'col' : self.useInspRowColumnCol.GetSelection(), - 'row' : self.useInspRowColumnRow.GetSelection(), - } - - def Deserialize(self, init): - if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) - if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) - -####### Use Power -class UsePowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - outerSizer = wx.BoxSizer(wx.HORIZONTAL) - - usePowerSizer = wx.GridBagSizer(5,5) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBToggle, (0,1)) - self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOn, (0,2)) - self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOff, (0,3)) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerName = PowerPicker(dialog) - usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) - usePowerSizer.AddGrowableCol(3) - - outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) - - return outerSizer - - def MakeBindString(self): - if self.usePowerRBToggle.GetValue(): - method = "powexecname" - elif self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') - return '' - - return f"{method} {self.usePowerName.GetLabel()}" - - def Serialize(self): - if self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - method = "powexecname" - return { - 'method': method, - 'pname' : self.usePowerName.GetLabel(), - 'picon' : self.usePowerName.IconFilename - } - - def Deserialize(self, init): - method = init.get('method', '') - if method == 'powexectoggleon': - self.usePowerRBOn.SetValue(True) - elif method == 'powexectoggleoff': - self.usePowerRBOff.SetValue(True) - else: - self.usePowerRBToggle.SetValue(True) - if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) - -####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): - def BuildUI(self, dialog): - usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTrayTray = wx.Choice(dialog, -1, - choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', - 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) - self.usePowerFromTrayTray.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) - self.usePowerFromTraySlot.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return usePowerFromTraySizer - - def MakeBindString(self): - choice = self.usePowerFromTrayTray - tray = choice.GetSelection() - - choice = self.usePowerFromTraySlot - slot = choice.GetSelection()+1 - - mode = "slot" - mode2 = '' - if tray > 3: - mode = "tray" - mode2 = f" {tray - 3}" - elif tray == 3: - mode = "alt2slot" - elif tray == 2: - mode = "altslot" - - return f"powexec{mode} {slot}{mode2}" - - def Serialize(self): - return { - 'tray' : self.usePowerFromTrayTray.GetSelection(), - 'slot' : self.usePowerFromTraySlot.GetSelection(), - } - - def Deserialize(self, init): - if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) - if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) - -####### Window Color -class WindowColorCmd(PowerBindCmd): - def BuildUI(self, dialog): - windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) - borderSizer = wx.BoxSizer(wx.VERTICAL) - self.ColorBorder.SetSizer(borderSizer) - self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) - borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) - - windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) - - RGBASizer = wx.FlexGridSizer(3, 4, 5) - - RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) - self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) - self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - windowColorSizer.Add(RGBASizer) - - self.UpdateFromSlider() - - return windowColorSizer - - def MakeBindString(self): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - return f"windowcolor {Rval} {Gval} {Bval} {Aval}" - - def Serialize(self): - return { - 'Rval' : self.RSlider.GetValue(), - 'Gval' : self.GSlider.GetValue(), - 'Bval' : self.BSlider.GetValue(), - 'Aval' : self.ASlider.GetValue(), - } - - def Deserialize(self, init): - self.RSlider.SetValue(init['Rval']) - self.GSlider.SetValue(init['Gval']) - self.BSlider.SetValue(init['Bval']) - self.ASlider.SetValue(init['Aval']) - self.UpdateFromSlider() - - def UpdateFromSlider(self, _ = None): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RReadout.SetValue(Rval) - self.GReadout.SetValue(Gval) - self.BReadout.SetValue(Bval) - self.AReadout.SetValue(Aval) - self.ColorBorder.Refresh() - - def UpdateFromText(self, _ = None): - Rval = self.RReadout.GetValue() - Gval = self.GReadout.GetValue() - Bval = self.BReadout.GetValue() - Aval = self.AReadout.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RSlider.SetValue(Rval) - self.GSlider.SetValue(Gval) - self.BSlider.SetValue(Bval) - self.ASlider.SetValue(Aval) - self.ColorBorder.Refresh() - -####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) - self.CommandChoice.SetSelection(0) - sizer.Add(self.CommandChoice, 0, wx.ALL, 5) - - self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), - value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) - sizer.Add(self.FilePath, 0, wx.ALL, 5) - - return sizer - - def MakeBindString(self): - command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] - return f'{command} "{self.FilePath.GetValue()}"' - - def Serialize(self): - return { - 'command' : self.CommandChoice.GetSelection(), - 'filename' : self.FilePath.GetValue(), - } - - def Deserialize(self, init): - self.CommandChoice.SetSelection(init.get('command', 0)) - self.FilePath.SetValue(init.get('filename', '')) +from UI.PowerBinderCommand import PowerBinderCommand ####### Window Toggle -class WindowToggleCmd(PowerBindCmd): +class WindowToggleCmd(PowerBinderCommand): + Name = "Window Toggle" + Menu = "Graphics / UI" + def BuildUI(self, dialog): self.WindowNames = { 'Actions' : 'actions', @@ -1713,88 +133,3 @@ def Deserialize(self, init): self.windowHideRB.SetValue(True) else: self.windowToggleRB.SetValue(True) - - -# Must always add to this list when adding a new command class above -menuStructure = { - 'Graphics / UI' : [ - 'Attribute Monitor', - 'Buff Display Settings', - 'Graphics Settings', - 'Window Color', - 'Window Save / Load', - 'Window Toggle', - ], - 'Inspirations' : [ - 'Use Inspiration By Name', - 'Use Inspiration From Row/Column', - ], - 'Powers' : [ - 'Auto Power', - 'Power Abort', - 'Power Unqueue', - 'Use Power', - 'Use Power From Tray', - ], - 'Social' : [ - 'Away From Keyboard', - 'Chat Command', - 'Chat Command (Global)', - 'Costume Change', - 'Emote', - 'Supergroup Mode', - ], - 'Targeting' : [ - 'Target Custom', - 'Target Enemy', - 'Target Frield', - 'Team/Pet Select', - 'Unselect', - ], - 'Misc' : [ - 'Load Binds Directory', - 'Movement Commands', - ], - # 'Custom Bind', # we're going to add "Custom Bind" in by hand at the end, - # but I'm leaving it here to remind myself that we do that. - } - -# Must always add to this list when adding a new command class above -commandClasses = { - 'Auto Power' : AutoPowerCmd, - 'Away From Keyboard' : AFKCmd, - 'Attribute Monitor' : AttributeMonitorCmd, - 'Buff Display Settings' : BuffDisplayCmd, - 'Chat Command' : ChatCmd, - 'Chat Command (Global)' : ChatGlobalCmd, - 'Costume Change' : CostumeChangeCmd, - 'Custom Bind' : CustomBindCmd, - 'Emote' : EmoteCmd, - 'Graphics Settings' : GraphicsCmd, - 'Load Binds Directory' : LoadBindsDir, - 'Movement Commands' : MovementCmd, - 'Power Abort' : PowerAbortCmd, - 'Power Unqueue' : PowerUnqueueCmd, - 'Supergroup Mode' : SGModeCmd, - 'Target Custom' : TargetCustomCmd, - 'Target Enemy' : TargetEnemyCmd, - 'Target Friend' : TargetFriendCmd, - 'Team/Pet Select' : TeamPetSelectCmd, - 'Unselect' : UnselectCmd, - 'Use Inspiration By Name' : UseInspByNameCmd, - 'Use Inspiration From Row/Column' : UseInspRowColCmd, - 'Use Power' : UsePowerCmd, - 'Use Power From Tray' : UsePowerFromTrayCmd, - 'Window Color' : WindowColorCmd, - 'Window Save / Load' : WindowSaveLoadCmd, - 'Window Toggle' : WindowToggleCmd, -} -# use these when we rename a commandClass so that old Profiles will still load correctly. -# If we've also updated the class, we need to try to make sure the new class will still -# Deserialize the legacy data, or at least not crash. -deprecatedCommandClasses = { - 'SG Mode Toggle' : SGModeCmd, - 'Use Insp By Name' : UseInspByNameCmd, - 'Use Insp From Row/Column' : UseInspRowColCmd, -} -commandRevClasses = {v: k for k, v in commandClasses.items()} diff --git a/UI/PowerBinderDialog.py b/UI/PowerBinderDialog.py index ad26b7a..ed75645 100644 --- a/UI/PowerBinderDialog.py +++ b/UI/PowerBinderDialog.py @@ -1,17 +1,8 @@ import wx -import re, os, sys -import UI -import UI.EmotePicker -from UI.ControlGroup import ControlGroup -from UI.PowerPicker import PowerPicker +import os, sys, importlib from Help import HelpButton -import wx.adv -from wx.adv import BitmapComboBox, EditableListBox -from pathlib import Path, PureWindowsPath -import importlib -import GameData -import Profile from Icon import GetIcon +from pathlib import Path class PowerBinderDialog(wx.Dialog): def __init__(self, parent, button, init = {}): @@ -94,14 +85,16 @@ def __init__(self, parent, button, init = {}): def LoadModules(self): base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__))) path = Path(base_path) / 'PowerBinderCommand' - print(f"Looking for modules in {path}") for package_file in sorted(path.glob('*.py')): package = package_file.stem if package == '__init__': continue # TODO - fix up glob() to dtrt instead - print(f"Importing package {package}") + + modstr = "UI.PowerBinderCommand." + package + # check if we've already loaded this one, if so, we've done this before, bail out + if modstr in sys.modules: return # do the actual importing - mod = importlib.import_module('UI.PowerBinderCommand.' + package) + mod = importlib.import_module(modstr) if modclass := getattr(mod, package, None): @@ -112,14 +105,17 @@ def LoadModules(self): else: print(f"Class {modclass} didn't define 'Name' - this is a bug") + if depName := getattr(modclass, 'DeprecatedName', ''): + deprecatedCommandClasses[depName] = modclass + + # we treat "Custom Bind" specially in the menu, so skip the "Menu" step for it + if modName == "Custom Bind": continue + if modMenu := getattr(modclass, 'Menu', ''): menuStructure[modMenu].append(modName) else: print(f"Module {modclass} didn't define 'Menu' - this is probably a bug") - if depName := getattr(modclass, 'DeprecatedName', ''): - deprecatedCommandClasses[depName] = modclass - else: print(f"Module {mod} didn't define a class of the same name - this is a bug!") @@ -322,1432 +318,6 @@ def __init__(self, parent): self.Layout() self.Fit() -########### Power Binder Command Objects -class PowerBindCmd(): - def __init__(self, dialog, init = {}): - self.UI = self.BuildUI(dialog) - if init: self.Deserialize(init) - - # Methods to override - def BuildUI(self, dialog) -> wx.Sizer|None : return None - def MakeBindString(self) -> str : return '' - def Serialize(self) -> dict : return {} - def Deserialize(self, init) : return - - def MakeListEntryString(self): - commandClassName = commandRevClasses[type(self)] - bindstr = self.MakeBindString() - short_bindstr = "{:.40}{}".format(bindstr, "…" if len(bindstr) > 40 else "") - return f"{commandClassName} - {short_bindstr}" - - -####### Away From Keyboard -class AFKCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.AFKName = wx.TextCtrl(dialog, -1) - self.AFKName.SetHint('Away From Keyboard Text') - sizer.Add(self.AFKName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - message = self.AFKName.GetValue() - return f"afk {message}" if message else "afk" - - def Serialize(self): - return {'message': self.AFKName.GetValue()} - - def Deserialize(self, init): - if init['message']: - self.AFKName.SetValue(init['message']) - -####### Attribute Monitor -class AttributeMonitorCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.Groups = {} - self.AttributeTable = { - 'Base' : { - 'Current Hit Points' : 'NT H', - 'Max Hit Points' : 'X H', - 'Current Endurance' : 'T E', - 'Max Endurance' : 'X EN', - 'Regeneration Rate' : 'N RAT', - 'Recovery Rate' : 'Y RA', - 'Endurance Consumption' : 'SU', - 'ToHit Bonus' : 'T B', - 'Accuracy Bonus' : 'CC', - 'Last Hit Chance' : 'T C', - 'Damage Bonus' : 'DA', - 'Healing Bonus' : 'NG B', - 'Recharge Time Bonus' : 'ME B', - 'Endurance Discount' : 'CE DIS', - 'Stealth Radius (PvP)' : 'PVP', - 'Stealth Radius (PvE)' : 'PVE', - 'Perception Radius' : 'RC', - 'Range Bonus' : 'GE B', - 'Threat Level' : 'AT L', - 'Experience to Next Level' : 'XT', - 'Experience Debt' : 'XP', - 'Influence / Infamy' : 'INF', - 'Inherent' : 'NH', - }, - 'Movement Speed' : { - 'Flying Speed' : 'FL', - 'Jumping Speed' : 'PI', - 'Max Jump Height' : 'X J', - 'Run Speed' : 'RU', - }, - 'Damage Resistance' : { - 'Smashing Resistance' : 'G R', - 'Lethal Resistance' : 'L R', - 'Fire Resistance' : 'RE R', - 'Cold Resistance' : 'COLD R', - 'Energy Resistance' : 'DamageType[4]', - 'Negative Energy Resistance' : 'GY R', - 'Psyonic Resistance' : 'NIC R', - 'Toxic Resistance' : 'XIC R', - }, - 'Defense' : { - 'Base Defense' : 'BAS', - 'Ranged Defense' : 'ED', - 'Melee Defense' : 'MEL', - 'AoE Defense' : '2', - 'Smashing Defense' : '3', - 'Lethal Defense' : '4', - 'Fire Defense' : '5', - 'Cold Defense' : '6', - 'Energy Defense' : '7', - 'Negative Energy Defense' : '8', - 'Psionic Defense' : '9', - 'Toxic Defense' : '1', - }, - 'Debuff Resistance' : { - 'Regeneration Resistance' : 'ON R', - 'Recovery Resistance' : 'RY R', - 'To Hit Resistance' : 'IT R', - 'Defense Resistance' : 'NSE RES', - }, - 'Status Effect Protection' : { - 'Hold Protection' : 'D P', - 'Immobilize Protection' : 'LIZE P', - 'Stun Protection' : 'N P', - 'Sleep Protection' : 'P P', - 'Knockback Protection' : 'K P', - 'Confuse Protection' : 'SE P', - 'Terrorize Protection' : 'ZE P', - 'Repel Protection' : 'EL P', - 'Teleport Protection' : 'T P', - }, - 'Status Effect Resistance' : { - 'Hold Resistance' : 'D R', - 'Immobilize Resistance' : 'LIZE R', - 'Stun Resistance' : 'N R', - 'Sleep Resistance' : 'P R', - 'Knockback Resistance' : 'K R', - 'Confuse Resistance' : 'SE R', - 'Terrorize Resistance' : 'ZE R', - 'Placate Resistance' : 'TE R', - 'Taunt Resistance' : 'NT R', - }, - 'Miscellaneous' : { - 'Level Shift' : 'L S', - }, - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.AttributeMenu = wx.Menu() - for group, controls in self.AttributeTable.items(): - submenu = wx.Menu() - self.AttributeMenu.AppendSubMenu(submenu, group) - for cb in controls: - submenu.Append(wx.ID_ANY, cb) - - self.AttributeMenu.Bind(wx.EVT_MENU, self.OnMenuItem) - - self.editbox = EditableListBox(dialog, label = "Attributes", style = wx.adv.EL_ALLOW_NEW|wx.adv.EL_ALLOW_DELETE) - groupSizer.Add(self.editbox) - - newButton = self.editbox.GetNewButton() - newButton.Bind(wx.EVT_BUTTON, self.OnNewButton) - - return groupSizer - - def MakeBindString(self): - map = {} - bindstrings = [] - for _, controls in self.AttributeTable.items(): - for cb, data in controls.items(): - map[cb] = data - - for string in self.editbox.GetStrings(): - if string: - bindstrings.append(f'monitorattribute {map[string]}') - - return '$$'.join(bindstrings) - - def Serialize(self): - return { - 'attributes' : self.editbox.GetStrings() - } - - def Deserialize(self, init): - self.editbox.SetStrings(init.get('attributes', [])) - - def OnNewButton(self, evt): - evt.GetEventObject().PopupMenu(self.AttributeMenu) - - def OnMenuItem(self, evt): - menuitem = evt.EventObject.FindItemById(evt.GetId()) - existingstrings = self.editbox.GetStrings() - existingstrings.append(menuitem.GetItemLabel()) - self.editbox.SetStrings(existingstrings) - -####### Auto Power -class AutoPowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - autoPowerSizer = wx.BoxSizer(wx.HORIZONTAL) - autoPowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.autoPowerName = PowerPicker(dialog) - autoPowerSizer.Add(self.autoPowerName, 1, wx.ALIGN_CENTER_VERTICAL) - - return autoPowerSizer - - def MakeBindString(self): - return f"powexecauto {self.autoPowerName.GetLabel()}" - - def Serialize(self): - return { - 'pname' : self.autoPowerName.GetLabel(), - 'picon' : self.autoPowerName.IconFilename - } - - def Deserialize(self, init): - if init.get('pname', ''): self.autoPowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.autoPowerName.SetBitmap(GetIcon(init['picon'])) - -####### Buff Display Command -class BuffDisplayCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.Page = dialog.Page - self.buffDisplayMap = { - 'Status Window' : { - 'Hide Auto' : 1, - 'Hide Toggles' : 2, - 'No Blinking' : 4, - 'No Stacking' : 8, - 'Numeric Stacking' : 16, - 'Hide Buff Numbers' : 32, - 'Stop Sending Buffs' : 64, - }, - 'Group Window' : { - 'Hide Auto' : 256, - 'Hide Toggles' : 512, - 'No Blinking' : 1024, - 'No Stacking' : 2048, - 'Numeric Stacking' : 4096, - 'Hide Buff Numbers' : 8192, - 'Stop Sending Buffs' : 16384, - }, - 'Pet Window' : { - 'Hide Auto' : 65536, - 'Hide Toggles' : 131072, - 'No Blinking' : 262144, - 'No Stacking' : 524288, - 'Numeric Stacking' : 1048576, - 'Hide Buff Numbers' : 2097152, - 'Stop Sending Buffs' : 4194304, - }, - } - self.Groups = {} - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - groupSizer = wx.BoxSizer(wx.HORIZONTAL) - - for group, controls in self.buffDisplayMap.items(): - self.Groups[group] = ControlGroup(dialog, self.Page, label = group) - groupid = self.Groups[group].GetStaticBox().GetId() - for cb, data in controls.items(): - self.Groups[group].AddControl( - ctlType = 'checkbox', - ctlName = f"{groupid}_{group}_{cb}", - label = cb, - data = data, - ) - - groupSizer.Add(self.Groups[group]) - - return groupSizer - - def CalculateValue(self): - page = wx.App.Get().Main.Profile.CustomBinds - - total = 0 - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = page.Ctrls[f"{groupid}_{group}_{cb}"] - if checkbox.IsChecked(): - total = total + checkbox.Data - return total - - def MakeBindString(self): - return f"optionset buffsettings {self.CalculateValue()}" - - def Serialize(self): - return { 'value' : self.CalculateValue() } - - def Deserialize(self, init): - value = init.get('value', 0) - - value = value or 0 # in case we had for some reason 'None' stashed in the init values - - for group, controls in self.buffDisplayMap.items(): - groupid = self.Groups[group].GetStaticBox().GetId() - for cb in controls: - checkbox = self.Page.Ctrls[f"{groupid}_{group}_{cb}"] - checkbox.SetValue( checkbox.Data & value ) - -####### Chat Command -class ChatCmd(PowerBindCmd): - def __init__(self, dialog, init = {}): - self.chatChannelMap = { # before __init__ - 'say' : 's', - 'group' : 'g', - 'broadcast': 'b', - 'local': 'l', - 'yell': 'y', - 'friends': 'f', - 'general': 'gen', - 'help': 'h', - 'looking for group': 'lfg', - 'request': 'req', - 'arena': 'ac', - 'supergroup': 'sg', - 'coalition': 'c', - 'tell $target,': 't $target,', - 'tell $name': 't $name', - } - PowerBindCmd.__init__(self, dialog, init) - - def BuildUI(self, dialog): - chatCommandSizer = wx.GridBagSizer(5, 5) - self.chatCommandUseColorsCB = wx.CheckBox(dialog, -1, "Use Chat Bubble Colors") - chatCommandSizer.Add(self.chatCommandUseColorsCB, (0,0), (1,6), flag=wx.ALIGN_CENTER_VERTICAL) - # row 1 - self.chatCommandBorderColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Border:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBorderColor, (1,1)) - self.chatCommandBGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Background:"), (1,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandBGColor, (1,3)) - self.chatCommandFGColor = wx.ColourPickerCtrl(dialog, -1) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Text:"), (1,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandFGColor, (1,5)) - # row 2 - self.chatCommandDuration = wx.SpinCtrl(dialog, -1, style=wx.SP_ARROW_KEYS) - self.chatCommandDuration.SetRange(1, 20) - self.chatCommandDuration.SetValue(7) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Duration:"), (2,0), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandDuration, (2,1)) - self.chatCommandChatSize = wx.Choice(dialog, -1, - choices = ['0.5', '0.6', '0.7', '0.8', '0.9', '1', '1.1', '1.2', '1.3', '1.4', '1.5']) - self.chatCommandChatSize.SetSelection(5) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Size:"), (2,2), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChatSize, (2,3)) - self.chatCommandChannel = wx.Choice(dialog, -1, choices = [chan for chan in self.chatChannelMap]) - self.chatCommandChannel.SetSelection(0) - chatCommandSizer.Add(wx.StaticText(dialog, -1, "Channel:"), (2,4), flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT) - chatCommandSizer.Add(self.chatCommandChannel, (2,5)) - # row 3 - self.chatCommandUseBeginchatCB = wx.CheckBox(dialog, -1, "Use Beginchat") - chatCommandSizer.Add(self.chatCommandUseBeginchatCB, (3,0), (1,2), flag=wx.ALIGN_CENTER_VERTICAL) - self.chatCommandMessage = wx.TextCtrl(dialog, -1) - self.chatCommandMessage.SetHint('Chat Command Text') - chatCommandSizer.Add(self.chatCommandMessage, (3,2), (1,4), flag=wx.EXPAND) - - return chatCommandSizer - - def MakeBindString(self): - duration = self.chatCommandDuration.GetValue() - - choice = self.chatCommandChatSize - index = choice.GetSelection() - size = choice.GetString(index) - - duration = f"" if duration != 7 else "" - size = f"" if size != "1" else "" - - bdcolor = fgcolor = bgcolor = '' - if self.chatCommandUseColorsCB.IsChecked(): - bdcolor = self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - fgcolor = self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - bgcolor = self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX) - - bdcolor = f"" - fgcolor = f"" - bgcolor = f"" - - beginchat = "beginchat /" if self.chatCommandUseBeginchatCB.IsChecked() else '' - text = self.chatCommandMessage.GetValue() - - choice = self.chatCommandChannel - index = choice.GetSelection() - channel = choice.GetString(index) - - return f"{beginchat}{channel} {size}{duration}{bdcolor}{fgcolor}{bgcolor}{text}" - - def Serialize(self): - return { - 'usecolors' : self.chatCommandUseColorsCB.IsChecked(), - 'beginchat' : self.chatCommandUseBeginchatCB.IsChecked(), - 'channel' : self.chatCommandChannel .GetSelection(), - 'size' : self.chatCommandChatSize.GetSelection(), - 'duration' : self.chatCommandDuration.GetValue(), - 'bdcolor' : self.chatCommandBorderColor.GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'fgcolor' : self.chatCommandFGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'bgcolor' : self.chatCommandBGColor .GetColour().GetAsString(wx.C2S_HTML_SYNTAX), - 'text' : self.chatCommandMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usecolors', '') : self.chatCommandUseColorsCB .SetValue(init['usecolors']) - if init.get('beginchat', '') : self.chatCommandUseBeginchatCB.SetValue(init['beginchat']) - if init.get('channel' , '') : self.chatCommandChannel .SetSelection(init['channel']) - if init.get('size' , '') : self.chatCommandChatSize.SetSelection(init['size']) - if init.get('duration' , '') : self.chatCommandDuration.SetValue(init['duration']) - if init.get('bdcolor' , '') : self.chatCommandBorderColor.SetColour(init['bdcolor']) - if init.get('fgcolor' , '') : self.chatCommandFGColor .SetColour(init['fgcolor']) - if init.get('bgcolor' , '') : self.chatCommandBGColor .SetColour(init['bgcolor']) - if init.get('text' , '') : self.chatCommandMessage.SetValue(init['text']) - - -####### Chat Command Global -class ChatGlobalCmd(PowerBindCmd): - def BuildUI(self, dialog): - chatCommandGlobalSizer = wx.GridBagSizer(5,5) - - self.chatCommandGlobalUseBeginchatCB = wx.CheckBox(dialog, -1, "Use beginchat") - chatCommandGlobalSizer.Add(self.chatCommandGlobalUseBeginchatCB, (0,0), (1,2)) - - self.chatCommandGlobalChannel = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalChannel.SetHint("Channel") - chatCommandGlobalSizer.Add(self.chatCommandGlobalChannel, (1,0)) - - self.chatCommandGlobalMessage = wx.TextCtrl(dialog, -1) - self.chatCommandGlobalMessage.SetHint('Chat Command (Global) Message') - chatCommandGlobalSizer.Add(self.chatCommandGlobalMessage, (1,1), flag=wx.EXPAND) - - chatCommandGlobalSizer.AddGrowableCol(1) - - return chatCommandGlobalSizer - - def MakeBindString(self): - useBeginchat = self.chatCommandGlobalUseBeginchatCB.IsChecked() - channel = self.chatCommandGlobalChannel.GetValue() - message = self.chatCommandGlobalMessage.GetValue() - - preface = "beginchat /" if useBeginchat else "" - - return f'{preface}send "{channel}" {message}' - - def Serialize(self): - return { - 'usebeginchat': self.chatCommandGlobalUseBeginchatCB.GetValue(), - 'channel' : self.chatCommandGlobalChannel.GetValue(), - 'message' : self.chatCommandGlobalMessage.GetValue(), - } - - def Deserialize(self, init): - if init.get('usebeginchat', ''): self.chatCommandGlobalUseBeginchatCB.SetValue(init['usebeginchat']) - if init.get('channel', ''): self.chatCommandGlobalChannel.SetValue(init['channel']) - if init.get('message', ''): self.chatCommandGlobalMessage.SetValue(init['message']) - -#######Costume Change -class CostumeChangeCmd(PowerBindCmd): - def BuildUI(self, dialog): - costumeChangeSizer = wx.BoxSizer(wx.HORIZONTAL) - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "Costume:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeCostume = wx.Choice(dialog, -1, - choices = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"]) - self.costumeChangeCostume.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeCostume, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - costumeChangeSizer.Add(wx.StaticText(dialog, -1, "CC Emote:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.costumeChangeEmote = wx.Choice(dialog, -1, - choices = GameData.Emotes['costumechange']) - self.costumeChangeEmote.Insert("- None -", 0) - self.costumeChangeEmote.SetSelection(0) - costumeChangeSizer.Add(self.costumeChangeEmote, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return costumeChangeSizer - - def MakeBindString(self): - costumeNumber = self.costumeChangeCostume.GetSelection() - costumeEmote = self.costumeChangeEmote.GetSelection() - - if costumeEmote: # None, or 0 == "- None -" - ccCmd = 'cce' - emoteName = self.costumeChangeEmote.GetString(costumeEmote) - emoteName = " CC" + emoteName.replace(" ","") - else: - ccCmd = 'cc' - emoteName = '' - - return f"{ccCmd} {costumeNumber}{emoteName}" - - def Serialize(self): - return{ - 'costumeNumber': self.costumeChangeCostume.GetSelection(), - 'costumeEmote' : self.costumeChangeEmote.GetSelection(), - } - - def Deserialize(self, init): - if init.get('costumeNumber', ''): self.costumeChangeCostume.SetSelection(init['costumeNumber']) - if init.get('costumeEmote' , ''): self.costumeChangeEmote .SetSelection(init['costumeEmote']) - -####### Movement Command -class MovementCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.plusbutton = wx.RadioButton(dialog, label = "+", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - self.plusbutton.SetValue(True) - - self.plusplusbutton = wx.RadioButton(dialog, label = "++", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.plusplusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.minusbutton = wx.RadioButton(dialog, label = '-', style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.minusbutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.commandchoice = wx.Choice(dialog, choices = [ - "forward", "left", "right", "backward", "up", "down", - "turnleft", "turnright", "first", "autorun", "clicktomove", - ],) - sizer.Add(self.commandchoice, 0, wx.ALIGN_CENTER_VERTICAL) - self.commandchoice.SetSelection(0) - - self.zerobutton = wx.RadioButton(dialog, label = "0", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.zerobutton, 0, wx.ALIGN_CENTER_VERTICAL) - - self.onebutton = wx.RadioButton(dialog, label = "1", style=wx.ALIGN_CENTER_VERTICAL) - sizer.Add(self.onebutton, 0, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - pre = post = '' - if self.plusbutton.GetValue() : pre = "+" - elif self.plusplusbutton.GetValue() : pre = "++" - elif self.minusbutton.GetValue() : pre = "-" - elif self.zerobutton.GetValue() : post = " 0" - elif self.onebutton.GetValue() : post = " 1" - - command = self.commandchoice.GetString(self.commandchoice.GetSelection()) - - return f"{pre}{command}{post}" - - def Serialize(self): - mod = '' - if self.plusbutton.GetValue() : mod = "plus" - elif self.plusplusbutton.GetValue() : mod = "plusplus" - elif self.minusbutton.GetValue() : mod = "minus" - elif self.zerobutton.GetValue() : mod = "zero" - elif self.onebutton.GetValue() : mod = "one" - - return { - 'mod' : mod, - 'command' : self.commandchoice.GetString(self.commandchoice.GetSelection()), - } - - def Deserialize(self, init): - mod = init.get('mod', 'plus') - - if mod == 'plus' : self.plusbutton.SetValue(True) - elif mod == 'plusplus' : self.plusplusbutton.SetValue(True) - elif mod == 'minus' : self.minusbutton.SetValue(True) - elif mod == 'zero' : self.zerobutton.SetValue(True) - elif mod == 'one' : self.onebutton.SetValue(True) - - self.commandchoice.SetSelection(self.commandchoice.FindString(init.get('command', 'forward'))) - -####### Graphics Command -class GraphicsCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.FlexGridSizer(2) - - self.visscalecb = wx.CheckBox(dialog, label = "visscale") - sizer.Add(self.visscalecb) - self.visscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 10, inc = 0.1) - sizer.Add(self.visscalesc) - - self.dofweightcb = wx.CheckBox(dialog, label = "dofweight") - sizer.Add(self.dofweightcb) - self.dofweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.5, max = 2.0, inc = 0.1) - sizer.Add(self.dofweightsc) - - self.fsaacb = wx.CheckBox(dialog, label = "fsaa") - sizer.Add(self.fsaacb) - self.fsaach = wx.Choice(dialog, choices = ["0", "2", "4", "8"]) - self.fsaach.SetSelection(0) - sizer.Add(self.fsaach) - - self.bloomscalecb = wx.CheckBox(dialog, label = "bloomscale") - sizer.Add(self.bloomscalecb) - self.bloomscalech = wx.Choice(dialog, choices = ["2", "4"]) - self.bloomscalech.SetSelection(0) - sizer.Add(self.bloomscalech) - - self.bloomweightcb = wx.CheckBox(dialog, label = "bloomweight") - sizer.Add(self.bloomweightcb) - self.bloomweightsc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.0, max = 2.0, inc = 0.1) - sizer.Add(self.bloomweightsc) - - self.lodbiascb = wx.CheckBox(dialog, label = "lodbias") - sizer.Add(self.lodbiascb) - self.lodbiassc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.3, max = 20.0, inc = 0.1) - sizer.Add(self.lodbiassc) - - self.renderscalecb = wx.CheckBox(dialog, label = "renderscale") - sizer.Add(self.renderscalecb) - self.renderscalesc = wx.SpinCtrlDouble(dialog, initial = 1.0, min = 0.1, max = 20.0, inc = 0.1) - sizer.Add(self.renderscalesc) - - return sizer - - def MakeBindString(self): - # choice 1, do this one at a time by hand; choice 2, hack up some data-driven iterable. I choose 1. - bindstrings = [] - if self.visscalecb.IsChecked(): - bindstrings.append("visscale " + str(self.visscalesc.GetValue())) - if self.dofweightcb.IsChecked(): - bindstrings.append("dofweight " + str(self.dofweightsc.GetValue())) - if self.fsaacb.IsChecked(): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bindstrings.append("fsaa " + fsaavalue) - if self.bloomscalecb.IsChecked(): - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - bindstrings.append("bloomscale " + bloomscalevalue) - if self.bloomweightcb.IsChecked(): - bindstrings.append("bloomweight " + str(self.bloomweightsc.GetValue())) - if self.lodbiascb.IsChecked(): - bindstrings.append("lodbias " + str(self.lodbiassc.GetValue())) - if self.renderscalecb.IsChecked(): - bindstrings.append("renderscale " + str(self.renderscalesc.GetValue())) - - return '$$'.join(bindstrings) - - def Serialize(self): - fsaavalue = "" - fsaaselection = self.fsaach.GetSelection() - if fsaaselection != wx.NOT_FOUND: - fsaavalue = self.fsaach.GetString(fsaaselection) - bloomscalevalue = "" - bloomscaleselection = self.bloomscalech.GetSelection() - if bloomscaleselection != wx.NOT_FOUND: - bloomscalevalue = self.bloomscalech.GetString(bloomscaleselection) - return { - 'visscalecb' : self.visscalecb.IsChecked(), - 'visscalesc' : self.visscalesc.GetValue(), - 'dofweightcb' : self.dofweightcb.IsChecked(), - 'dofweightsc' : self.dofweightsc.GetValue(), - 'fsaacb' : self.fsaacb.IsChecked(), - 'fsaach' : fsaavalue, - 'bloomscalecb' : self.bloomscalecb.IsChecked(), - 'bloomscalech' : bloomscalevalue, - 'bloomweightcb' : self.bloomweightcb.IsChecked(), - 'bloomweightsc' : self.bloomweightsc.GetValue(), - 'lodbiascb' : self.lodbiascb.IsChecked(), - 'lodbiassc' : self.lodbiassc.GetValue(), - 'renderscalecb' : self.renderscalecb.IsChecked(), - 'renderscalesc' : self.renderscalesc.GetValue(), - } - - def Deserialize(self, init): - self.visscalecb.SetValue(init.get('visscalecb', False)) - self.visscalesc.SetValue(init.get('visscalesc', 1.0)) - self.dofweightcb.SetValue(init.get('dofweightcb', False)) - self.dofweightsc.SetValue(init.get('dofweightsc', 1.0)) - self.fsaacb.SetValue(init.get('fsaacb', False)) - self.fsaach.SetSelection(self.fsaach.FindString(init.get('fsaach', ''))) - self.bloomscalecb.SetValue(init.get('bloomscalecb', False)) - self.bloomscalech.SetSelection(self.bloomscalech.FindString(init.get('bloomscalech', ''))) - self.bloomweightcb.SetValue(init.get('bloomweightcb', False)) - self.bloomweightsc.SetValue(init.get('bloomweightsc', 1.0)) - self.lodbiascb.SetValue(init.get('lodbiascb', False)) - self.lodbiassc.SetValue(init.get('lodbiassc', 1.0)) - self.renderscalecb.SetValue(init.get('renderscalecb', False)) - self.renderscalesc.SetValue(init.get('renderscalesc', 1.0)) - -####### Custom Bind -class CustomBindCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - self.customBindName = wx.TextCtrl(dialog, -1) - self.customBindName.SetHint('Custom Bind Text') - sizer.Add(self.customBindName, 1, wx.ALIGN_CENTER_VERTICAL) - - return sizer - - def MakeBindString(self): - return self.customBindName.GetValue() - - def Serialize(self): - return { 'customBindName': self.customBindName.GetValue() } - - def Deserialize(self,init): - if init.get('customBindName', ''): self.customBindName.SetValue(init['customBindName']) - -####### Emote -class EmoteCmd(PowerBindCmd): - def BuildUI(self, dialog): - emoteSizer = wx.BoxSizer(wx.HORIZONTAL) - self.emoteText = wx.StaticText(dialog, -1, "Select Emote:") - emoteSizer.Add(self.emoteText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - self.emoteName = wx.Button(dialog, -1, "...") - self.emoteName.Bind(wx.EVT_BUTTON, UI.EmotePicker.OnEmotePicker) - emoteSizer.Add(self.emoteName, 1, wx.ALIGN_CENTER_VERTICAL) - - return emoteSizer - - def MakeBindString(self): - displayedEmoteName = self.emoteName.GetLabel() - actualEmotePayload = UI.EmotePicker.payloadMap[displayedEmoteName] - - return actualEmotePayload - - def Serialize(self): - return {'emoteName': self.emoteName.GetLabel()} - - def Deserialize(self, init): - if init.get('emoteName', ''): self.emoteName.SetLabel(init['emoteName']) - -####### Load Binds Directory -class LoadBindsDir(PowerBindCmd): - def BuildUI(self, dialog): - mainSizer = wx.BoxSizer(wx.VERTICAL) - - lbSizer = wx.BoxSizer(wx.HORIZONTAL) - lbText = wx.StaticText(dialog, -1, "Load Binds Directory:") - lbSizer.Add(lbText, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - - profiles = Profile.GetAllProfileBindsDirs() - - self.lbPicker = wx.Choice(dialog, -1, choices = sorted(profiles)) - lbSizer.Add(self.lbPicker, 1, wx.ALIGN_CENTER_VERTICAL) - - mainSizer.Add(lbSizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - self.lbResetCB = wx.CheckBox(dialog, -1, "Reset All Keybinds Before Loading") - self.lbResetCB.SetValue(True) - - mainSizer.Add(self.lbResetCB, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) - - return mainSizer - - def MakeBindString(self): - - # If the specified binds directory disappeared between runs, we'd crash, so handle that. - if self.lbPicker.GetSelection() == wx.NOT_FOUND: return '' - - config = wx.ConfigBase.Get() - if config.Exists('GameBindPath'): - bindpath = config.Read('GameBindPath') - else: - bindpath = config.Read('BindPath') - - reset = "" - if self.lbResetCB.GetValue(): - reset = "keybind_reset$$" - - resetfilepath = PureWindowsPath(bindpath) / self.lbPicker.GetString(self.lbPicker.GetSelection()) / 'reset.txt' - return reset + 'bindloadfile ' + str(resetfilepath) - - def Serialize(self): - return {'LoadBindProfile' : self.lbPicker.GetString(self.lbPicker.GetSelection()), - 'ResetKeybinds' : self.lbResetCB.GetValue(), - } - - def Deserialize(self, init): - if init.get('LoadBindProfile', ''): self.lbPicker.SetSelection(self.lbPicker.FindString(init['LoadBindProfile'])) - self.lbResetCB.SetValue(init.get('ResetKeybinds', False)) - -####### Power Abort -class PowerAbortCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecabort' - -####### Power Unqueue -class PowerUnqueueCmd(PowerBindCmd): - def MakeBindString(self): - return 'powexecunqueue' - -####### SG Mode -class SGModeCmd(PowerBindCmd): - def BuildUI(self, dialog): - sgmodeSizer = wx.BoxSizer(wx.HORIZONTAL) - sgmodeSizer.Add(wx.StaticText(dialog, -1, "Supergroup Mode:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.sgmodeToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.sgmodeOnRB = wx.RadioButton(dialog, -1, "On") - self.sgmodeOffRB = wx.RadioButton(dialog, -1, "Off") - - sgmodeSizer.Add(self.sgmodeToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOnRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - sgmodeSizer.Add(self.sgmodeOffRB, 0, wx.ALIGN_CENTER_VERTICAL) - - return sgmodeSizer - - def MakeBindString(self): - if self.sgmodeOnRB.GetValue(): - return 'sgmodeset 1' - elif self.sgmodeOffRB.GetValue(): - return 'sgmodeset 0' - else: - return 'sgmode' - - def Serialize(self): - if self.sgmodeOnRB.GetValue(): - val = "On" - elif self.sgmodeOffRB.GetValue(): - val = "Off" - else: - val = "Toggle" - - return {"value" : val} - - def Deserialize(self, init): - val = init.get('value', '') - if val == "On": - self.sgmodeOnRB.SetValue(True) - elif val == "Off": - self.sgmodeOffRB.SetValue(True) - else: - self.sgmodeToggleRB.SetValue(True) - -####### Target Custom -class TargetCustomCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetCustomSizer = wx.GridBagSizer(5,5) - targetCustomSizer.Add(wx.StaticText(dialog, -1, "Target Mode:"), (0,0), - flag =wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.RIGHT) - self.targetCustomModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetCustomModeChoice.SetSelection(0) - targetCustomSizer.Add(self.targetCustomModeChoice, (0,1), flag=wx.EXPAND) - self.targetCustomOptionalName = wx.TextCtrl(dialog, -1) - self.targetCustomOptionalName.SetHint("Optional name to match") - targetCustomSizer.Add(self.targetCustomOptionalName, (0,2), flag=wx.EXPAND) - self.targetCustomCBEnemies = wx.CheckBox(dialog, -1, "Enemies") - targetCustomSizer.Add(self.targetCustomCBEnemies, (1,0)) - self.targetCustomCBFriends = wx.CheckBox(dialog, -1, "Friends") - targetCustomSizer.Add(self.targetCustomCBFriends, (1,1)) - self.targetCustomCBDefeated = wx.CheckBox(dialog, -1, "Defeated") - targetCustomSizer.Add(self.targetCustomCBDefeated, (2,0)) - self.targetCustomCBAlive = wx.CheckBox(dialog, -1, "Alive") - targetCustomSizer.Add(self.targetCustomCBAlive, (2,1)) - self.targetCustomCBMyPets = wx.CheckBox(dialog, -1, "My Pets") - targetCustomSizer.Add(self.targetCustomCBMyPets, (3,0)) - self.targetCustomCBNotMyPets = wx.CheckBox(dialog, -1, "Not My Pets") - targetCustomSizer.Add(self.targetCustomCBNotMyPets, (3,1)) - self.targetCustomCBBaseItems = wx.CheckBox(dialog, -1, "Base Items") - targetCustomSizer.Add(self.targetCustomCBBaseItems, (4,0)) - self.targetCustomCBNotBaseItems = wx.CheckBox(dialog, -1, "Not Base Items") - targetCustomSizer.Add(self.targetCustomCBNotBaseItems, (4,1)) - - targetCustomSizer.AddGrowableCol(2) - - return targetCustomSizer - - def MakeBindString(self): - choice = self.targetCustomModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - targetCommand = "targetcustom" + mode.lower() - - enemy = " enemy" if self.targetCustomCBEnemies. IsChecked() else "" - friend = " friend" if self.targetCustomCBFriends. IsChecked() else "" - defeated = " defeated" if self.targetCustomCBDefeated. IsChecked() else "" - alive = " alive" if self.targetCustomCBAlive. IsChecked() else "" - mypet = " mypet" if self.targetCustomCBMyPets. IsChecked() else "" - notmypet = " notmypet" if self.targetCustomCBNotMyPets. IsChecked() else "" - base = " base" if self.targetCustomCBBaseItems. IsChecked() else "" - notbase = " notbase" if self.targetCustomCBNotBaseItems. IsChecked() else "" - - name = self.targetCustomOptionalName.GetValue() - - return f"{targetCommand}{enemy}{friend}{defeated}{alive}{mypet}{notmypet}{base}{notbase} {name}" - - def Serialize(self): - return { - 'mode' : self.targetCustomModeChoice.GetSelection(), - 'enemy' : self.targetCustomCBEnemies. IsChecked(), - 'friend' : self.targetCustomCBFriends. IsChecked(), - 'defeated' : self.targetCustomCBDefeated. IsChecked(), - 'alive' : self.targetCustomCBAlive. IsChecked(), - 'mypet' : self.targetCustomCBMyPets. IsChecked(), - 'notmypet' : self.targetCustomCBNotMyPets. IsChecked(), - 'base' : self.targetCustomCBBaseItems. IsChecked(), - 'notbase' : self.targetCustomCBNotBaseItems.IsChecked(), - 'name' : self.targetCustomOptionalName.GetValue(), - } - - def Deserialize(self, init): - if init.get('mode' , ''): self.targetCustomModeChoice.SetSelection(init['mode']) - if init.get('enemy' , ''): self.targetCustomCBEnemies. SetValue(init['enemy']) - if init.get('friend' , ''): self.targetCustomCBFriends. SetValue(init['friend']) - if init.get('defeated', ''): self.targetCustomCBDefeated. SetValue(init['defeated']) - if init.get('alive' , ''): self.targetCustomCBAlive. SetValue(init['alive']) - if init.get('mypet' , ''): self.targetCustomCBMyPets. SetValue(init['mypet']) - if init.get('notmypet', ''): self.targetCustomCBNotMyPets. SetValue(init['notmypet']) - if init.get('base' , ''): self.targetCustomCBBaseItems. SetValue(init['base']) - if init.get('notbase' , ''): self.targetCustomCBNotBaseItems.SetValue(init['notbase']) - if init.get('name' , ''): self.targetCustomOptionalName.SetValue(init['name']) - - -####### Target Enemy -class TargetEnemyCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetEnemySizer = wx.BoxSizer(wx.HORIZONTAL) - targetEnemySizer.Add(wx.StaticText(dialog, -1, "Target Enemy:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetEnemyModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetEnemyModeChoice.SetSelection(0) - targetEnemySizer.Add(self.targetEnemyModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetEnemySizer - - def MakeBindString(self): - choice = self.targetEnemyModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetenemy" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetEnemyModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetEnemyModeChoice.SetSelection(init['mode']) - -####### Target Friend -class TargetFriendCmd(PowerBindCmd): - def BuildUI(self, dialog): - targetFriendSizer = wx.BoxSizer(wx.HORIZONTAL) - targetFriendSizer.Add(wx.StaticText(dialog, -1, "Target Friend:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.targetFriendModeChoice = wx.Choice(dialog, -1, choices = ['Near','Far','Next','Prev']) - self.targetFriendModeChoice.SetSelection(0) - targetFriendSizer.Add(self.targetFriendModeChoice, 0, wx.ALIGN_CENTER_VERTICAL) - - return targetFriendSizer - - def MakeBindString(self): - choice = self.targetFriendModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "targetfriend" + mode.lower() - - def Serialize(self): - return { 'mode' : self.targetFriendModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('mode', ''): self.targetFriendModeChoice.SetSelection(init['mode']) - -####### Team/Pet Select -class TeamPetSelectCmd(PowerBindCmd): - def BuildUI(self, dialog): - teamPetSelectSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.teamPetSelectTeamRB = wx.RadioButton(dialog, -1, "Teammate", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectTeamRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectPetRB = wx.RadioButton(dialog, -1, "Pet/Henchman", style=wx.ALIGN_CENTER_VERTICAL) - teamPetSelectSizer.Add(self.teamPetSelectPetRB, 0, wx.ALIGN_CENTER_VERTICAL) - - self.teamPetSelectNumber = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8'], - style=wx.ALIGN_CENTER_VERTICAL) - self.teamPetSelectNumber.SetSelection(0) - teamPetSelectSizer.Add(self.teamPetSelectNumber, 0, wx.ALIGN_CENTER_VERTICAL) - - return teamPetSelectSizer - - def MakeBindString(self): - teamOrPet = 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet' - targetNumber = self.teamPetSelectNumber.GetSelection()+1 - - return f"{teamOrPet}select {targetNumber}" - - def Serialize(self): - return { - 'teamOrPet': 'team' if self.teamPetSelectTeamRB.GetValue() else 'pet', - 'targetNum': self.teamPetSelectNumber.GetSelection(), - } - - def Deserialize(self, init): - ToP = init.get('teamOrPet', '') - if ToP == 'pet': - self.teamPetSelectPetRB.SetValue(True) - else: - self.teamPetSelectTeamRB.SetValue(True) - if init.get('targetNum', ''): self.teamPetSelectNumber.SetSelection(init['targetNum']) - -####### Unselect -class UnselectCmd(PowerBindCmd): - def MakeBindString(self): - return 'unselect' - -####### Use Insp By Name -class UseInspByNameCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspByNameSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspByNameSizer.Add(wx.StaticText(dialog, -1, "Inspiration:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspByNameModeChoice = BitmapComboBox(dialog, style = wx.CB_READONLY) - for _, types in GameData.Inspirations.items(): - for _, info in types.items(): - for insp in info['tiers']: - name = re.sub(' ', '', str(insp)) - icon = GetIcon(f'Inspirations/{name}') - self.useInspByNameModeChoice.Append(insp, icon) - self.useInspByNameModeChoice.SetSelection(0) - useInspByNameSizer.Add(self.useInspByNameModeChoice, 1, wx.ALIGN_CENTER_VERTICAL) - - return useInspByNameSizer - - def MakeBindString(self): - choice = self.useInspByNameModeChoice - index = choice.GetSelection() - mode = choice.GetString(index) - return "inspexecname " + mode.lower() - - def GetAllInsps(self): - Insplist = [] - for _, info in GameData.Inspirations.items(): - for insp in info['tiers']: - Insplist.append(insp) - Insplist.append("---") - Insplist.pop(-1) # snip the terminal "---" - - return Insplist - - def Serialize(self): - return { 'insp' : self.useInspByNameModeChoice.GetSelection() } - - def Deserialize(self, init): - if init.get('insp', ''): self.useInspByNameModeChoice.SetSelection(init['insp']) - -####### Use Insp From Row / Column -class UseInspRowColCmd(PowerBindCmd): - def BuildUI(self, dialog): - useInspRowColumnSizer = wx.BoxSizer(wx.HORIZONTAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Row:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.useInspRowColumnRow = wx.Choice(dialog, -1, choices=['1','2','3','4'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnRow.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnRow, 0, wx.ALIGN_CENTER_VERTICAL) - useInspRowColumnSizer.Add(wx.StaticText(dialog, -1, "Column:"), 0, - wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, 4) - self.useInspRowColumnCol = wx.Choice(dialog, -1, choices=['1','2','3','4','5'], style=wx.ALIGN_CENTER_VERTICAL) - self.useInspRowColumnCol.SetSelection(0) - useInspRowColumnSizer.Add(self.useInspRowColumnCol, 0, wx.ALIGN_CENTER_VERTICAL) - - return useInspRowColumnSizer - - def MakeBindString(self): - row = self.useInspRowColumnRow.GetSelection()+1 - col = self.useInspRowColumnCol.GetSelection()+1 - - return f"inspexectray {col} {row}" - - def Serialize(self): - return { - 'col' : self.useInspRowColumnCol.GetSelection(), - 'row' : self.useInspRowColumnRow.GetSelection(), - } - - def Deserialize(self, init): - if init.get('col', ''): self.useInspRowColumnCol.SetSelection(init['col']) - if init.get('row', ''): self.useInspRowColumnRow.SetSelection(init['row']) - -####### Use Power -class UsePowerCmd(PowerBindCmd): - def BuildUI(self, dialog): - outerSizer = wx.BoxSizer(wx.HORIZONTAL) - - usePowerSizer = wx.GridBagSizer(5,5) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Method:"), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerRBToggle = wx.RadioButton(dialog, -1, "Toggle", style=wx.RB_GROUP|wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBToggle, (0,1)) - self.usePowerRBOn = wx.RadioButton(dialog, -1, "On", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOn, (0,2)) - self.usePowerRBOff = wx.RadioButton(dialog, -1, "Off", style=wx.ALIGN_CENTER_VERTICAL) - usePowerSizer.Add(self.usePowerRBOff, (0,3)) - usePowerSizer.Add(wx.StaticText(dialog, -1, "Power:"), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) - self.usePowerName = PowerPicker(dialog) - usePowerSizer.Add(self.usePowerName, (1,1), (1,3), flag=wx.EXPAND) - usePowerSizer.AddGrowableCol(3) - - outerSizer.Add(usePowerSizer, 1, wx.ALIGN_CENTER_VERTICAL) - - return outerSizer - - def MakeBindString(self): - if self.usePowerRBToggle.GetValue(): - method = "powexecname" - elif self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - wx.LogWarning('PowerBindCmd "UsePowerCmd" got an impossible value for toggle/on/off') - return '' - - return f"{method} {self.usePowerName.GetLabel()}" - - def Serialize(self): - if self.usePowerRBOn.GetValue(): - method = "powexectoggleon" - elif self.usePowerRBOff.GetValue(): - method = "powexectoggleoff" - else: - method = "powexecname" - return { - 'method': method, - 'pname' : self.usePowerName.GetLabel(), - 'picon' : self.usePowerName.IconFilename - } - - def Deserialize(self, init): - method = init.get('method', '') - if method == 'powexectoggleon': - self.usePowerRBOn.SetValue(True) - elif method == 'powexectoggleoff': - self.usePowerRBOff.SetValue(True) - else: - self.usePowerRBToggle.SetValue(True) - if init.get('pname', ''): self.usePowerName.SetLabel(init['pname']) - if init.get('picon', ''): self.usePowerName.SetBitmap(GetIcon(init['picon'])) - -####### Use Power From Tray -class UsePowerFromTrayCmd(PowerBindCmd): - def BuildUI(self, dialog): - usePowerFromTraySizer = wx.BoxSizer(wx.HORIZONTAL) - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Tray:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTrayTray = wx.Choice(dialog, -1, - choices = ['Main Tray', 'Alt Tray', 'Alt 2 Tray', 'Tray 1', 'Tray 2', 'Tray 3', - 'Tray 4', 'Tray 5', 'Tray 6', 'Tray 7', 'Tray 8', 'Tray 9', 'Tray 10']) - self.usePowerFromTrayTray.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTrayTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - usePowerFromTraySizer.Add(wx.StaticText(dialog, -1, "Slot:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 4) - self.usePowerFromTraySlot = wx.Choice(dialog, -1, choices=['1','2','3','4','5','6','7','8','9','10']) - self.usePowerFromTraySlot.SetSelection(0) - usePowerFromTraySizer.Add(self.usePowerFromTraySlot, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - return usePowerFromTraySizer - - def MakeBindString(self): - choice = self.usePowerFromTrayTray - tray = choice.GetSelection() - - choice = self.usePowerFromTraySlot - slot = choice.GetSelection()+1 - - mode = "slot" - mode2 = '' - if tray > 3: - mode = "tray" - mode2 = f" {tray - 3}" - elif tray == 3: - mode = "alt2slot" - elif tray == 2: - mode = "altslot" - - return f"powexec{mode} {slot}{mode2}" - - def Serialize(self): - return { - 'tray' : self.usePowerFromTrayTray.GetSelection(), - 'slot' : self.usePowerFromTraySlot.GetSelection(), - } - - def Deserialize(self, init): - if init.get('tray', ''): self.usePowerFromTrayTray.SetSelection(init['tray']) - if init.get('slot', ''): self.usePowerFromTraySlot.SetSelection(init['slot']) - -####### Window Color -class WindowColorCmd(PowerBindCmd): - def BuildUI(self, dialog): - windowColorSizer = wx.BoxSizer(wx.HORIZONTAL) - - self.ColorBorder = wx.Panel(dialog, -1, size = (150, 150)) - borderSizer = wx.BoxSizer(wx.VERTICAL) - self.ColorBorder.SetSizer(borderSizer) - self.ColorDisplay = wx.StaticText(self.ColorBorder, -1, size = (140, 140)) - borderSizer.Add(self.ColorDisplay, 0, wx.ALL, 5) - - windowColorSizer.Add(self.ColorBorder, 0, wx.ALIGN_CENTER|wx.RIGHT, 15) - - RGBASizer = wx.FlexGridSizer(3, 4, 5) - - RGBASizer.Add(wx.StaticText(dialog, label = "R:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RSlider = wx.Slider(dialog, -1, size = (300, -1), value = 36, minValue = 0, maxValue = 255) - self.RSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.RSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.RReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.RReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.RReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "G:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GSlider = wx.Slider(dialog, -1, size = (300, -1), value = 145, minValue = 0, maxValue = 255) - self.GSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.GSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.GReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.GReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.GReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "B:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BSlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.BSlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.BSlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.BReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.BReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.BReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - RGBASizer.Add(wx.StaticText(dialog, label = "A:"), 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.ASlider = wx.Slider(dialog, -1, size = (300, -1), value = 255, minValue = 0, maxValue = 255) - self.ASlider.Bind(wx.EVT_SCROLL, self.UpdateFromSlider) - RGBASizer.Add(self.ASlider, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - self.AReadout = wx.SpinCtrl(dialog, -1, initial = 128, min = 0, max = 255) - self.AReadout.Bind(wx.EVT_TEXT, self.UpdateFromText) - RGBASizer.Add(self.AReadout, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 3) - - windowColorSizer.Add(RGBASizer) - - self.UpdateFromSlider() - - return windowColorSizer - - def MakeBindString(self): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - return f"windowcolor {Rval} {Gval} {Bval} {Aval}" - - def Serialize(self): - return { - 'Rval' : self.RSlider.GetValue(), - 'Gval' : self.GSlider.GetValue(), - 'Bval' : self.BSlider.GetValue(), - 'Aval' : self.ASlider.GetValue(), - } - - def Deserialize(self, init): - self.RSlider.SetValue(init['Rval']) - self.GSlider.SetValue(init['Gval']) - self.BSlider.SetValue(init['Bval']) - self.ASlider.SetValue(init['Aval']) - self.UpdateFromSlider() - - def UpdateFromSlider(self, _ = None): - Rval = self.RSlider.GetValue() - Gval = self.GSlider.GetValue() - Bval = self.BSlider.GetValue() - Aval = self.ASlider.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RReadout.SetValue(Rval) - self.GReadout.SetValue(Gval) - self.BReadout.SetValue(Bval) - self.AReadout.SetValue(Aval) - self.ColorBorder.Refresh() - - def UpdateFromText(self, _ = None): - Rval = self.RReadout.GetValue() - Gval = self.GReadout.GetValue() - Bval = self.BReadout.GetValue() - Aval = self.AReadout.GetValue() - self.ColorBorder.SetBackgroundColour((Rval, Gval, Bval)) - self.ColorDisplay.SetBackgroundColour((Aval, Aval, Aval)) - self.RSlider.SetValue(Rval) - self.GSlider.SetValue(Gval) - self.BSlider.SetValue(Bval) - self.ASlider.SetValue(Aval) - self.ColorBorder.Refresh() - -####### Window Save / Load -class WindowSaveLoadCmd(PowerBindCmd): - def BuildUI(self, dialog): - sizer = wx.BoxSizer(wx.HORIZONTAL) - - self.CommandChoice = wx.Choice(dialog, -1, choices = ["Save Window Settings", "Load Window Settings"]) - self.CommandChoice.SetSelection(0) - sizer.Add(self.CommandChoice, 0, wx.ALL, 5) - - self.FilePath = wx.TextCtrl(dialog, -1, size = (400, -1), - value = str(wx.App.Get().Main.Profile.GameBindsDir() / 'windows.txt')) - sizer.Add(self.FilePath, 0, wx.ALL, 5) - - return sizer - - def MakeBindString(self): - command = ['wdwsavefile', 'wdwloadfile'][self.CommandChoice.GetSelection()] - return f'{command} "{self.FilePath.GetValue()}"' - - def Serialize(self): - return { - 'command' : self.CommandChoice.GetSelection(), - 'filename' : self.FilePath.GetValue(), - } - - def Deserialize(self, init): - self.CommandChoice.SetSelection(init.get('command', 0)) - self.FilePath.SetValue(init.get('filename', '')) - -####### Window Toggle -class WindowToggleCmd(PowerBindCmd): - def BuildUI(self, dialog): - self.WindowNames = { - 'Actions' : 'actions', - 'Auction House' : 'ah', - 'Badge' : 'badge', - 'Channel Search' : 'chansearch', - 'Chat' : 'chat', - 'Custom Chat 1' : 'chat1', - 'Custom Chat 2' : 'chat2', - 'Custom Chat 3' : 'chat3', - 'Custom Chat 4' : 'chat4', - 'Clues' : 'clue', - 'Combat Numbers' : 'combatnumbers', - 'Contacts' : 'contact', - 'Contact Finder' : 'contactfinder', - 'Costumes' : 'costume', - 'Email' : 'email', - 'Enhancements' : 'enhancements', - 'Friends' : 'friend', - 'Group' : 'group', - 'Help' : 'helpwindow', - 'Incarnate' : 'incarnate', - 'Inspirations' : 'insp', - 'League' : 'league', - 'LFG' : 'lfg', - 'Map' : 'map', - 'Mission' : 'mission', - 'Nav / Compass' : 'nav', - 'Options' : 'options', - 'Pets' : 'pet', - 'Petition' : 'petition', - 'Power Tray' : 'powers', - 'Power List' : 'powerlist', - 'Quit' : 'quit', - 'Recipes' : 'recipe', - 'Salvage' : 'salvage', - 'Search' : 'search', - 'Supergroup' : 'sg', - 'Target' : 'target', - 'Team' : 'team', - 'Tray' : 'tray', - 'Tray1' : 'tray1', - 'Tray2' : 'tray2', - 'Tray3' : 'tray3', - 'Tray4' : 'tray4', - 'Tray5' : 'tray5', - 'Tray6' : 'tray6', - 'Tray7' : 'tray7', - 'Tray8' : 'tray8', - 'Vault' : 'vault', - } - - self.ShortToggleCommands = { - 'Auction House' : 'ah', - 'Chat' : 'chat', - 'Help' : 'helpwindow', - 'Map' : 'map', - 'Nav / Compass' : 'nav', - 'Power Tray' : 'powers', - 'Target' : 'target', - 'Tray' : 'tray', - } - - windowToggleSizer = wx.BoxSizer(wx.HORIZONTAL) - windowToggleSizer.Add(wx.StaticText(dialog, -1, "Window:"), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - self.windowToggleTray = wx.Choice(dialog, -1, choices = list(self.WindowNames.keys())) - self.windowToggleTray.SetSelection(0) - windowToggleSizer.Add(self.windowToggleTray, 1, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - - self.windowToggleRB = wx.RadioButton(dialog, -1, "Toggle", style = wx.RB_GROUP) - self.windowShowRB = wx.RadioButton(dialog, -1, "Show") - self.windowHideRB = wx.RadioButton(dialog, -1, "Hide") - - windowToggleSizer.Add(self.windowToggleRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowShowRB, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5) - windowToggleSizer.Add(self.windowHideRB, 0, wx.ALIGN_CENTER_VERTICAL, 0) - - return windowToggleSizer - - def MakeBindString(self): - choice = self.windowToggleTray - index = choice.GetSelection() - windowdesc = choice.GetString(index) - windowname = self.WindowNames[windowdesc] - - if self.windowShowRB.GetValue(): - return 'show ' + windowname - elif self.windowHideRB.GetValue(): - return 'windowhide ' + windowname - else: - if shortcmd := self.ShortToggleCommands.get(windowdesc, None): - return shortcmd - else: - return 'toggle ' + windowname - - - def Serialize(self): - choice = self.windowToggleTray - if self.windowShowRB.GetValue(): - action = "Show" - elif self.windowHideRB.GetValue(): - action = "Hide" - else: - action = "Toggle" - return { - 'window': choice.GetString(choice.GetSelection()), - 'action': action, - } - - def Deserialize(self, init): - choice = self.windowToggleTray - if window := init.get('window', ''): - if isinstance(window, int): - choice.SetSelection(window) - else: - choice.SetSelection(choice.FindString(window)) - - if choice.GetSelection() == wx.NOT_FOUND: - choice.SetSelection(0) - - action = init.get('action', '') - if action == "Show": - self.windowShowRB.SetValue(True) - elif action == "Hide": - self.windowHideRB.SetValue(True) - else: - self.windowToggleRB.SetValue(True) - menuStructure = { 'Graphics / UI' : [ ], 'Inspirations' : [ ],