flickerstreak@175: local addonName, addonTable = ... flickerstreak@175: local ReAction = addonTable.ReAction flickerstreak@109: local L = ReAction.L flickerstreak@109: local _G = _G flickerstreak@185: local wipe = wipe flickerstreak@185: flickerstreak@109: local AceConfigReg = LibStub("AceConfigRegistry-3.0") flickerstreak@109: local AceConfigDialog = LibStub("AceConfigDialog-3.0") flickerstreak@109: flickerstreak@109: flickerstreak@185: local pointTable = { flickerstreak@185: CENTER = L["Center"], flickerstreak@185: LEFT = L["Left"], flickerstreak@185: RIGHT = L["Right"], flickerstreak@185: TOP = L["Top"], flickerstreak@185: BOTTOM = L["Bottom"], flickerstreak@185: TOPLEFT = L["Top Left"], flickerstreak@185: TOPRIGHT = L["Top Right"], flickerstreak@185: BOTTOMLEFT = L["Bottom Left"], flickerstreak@185: BOTTOMRIGHT = L["Bottom Right"], flickerstreak@185: } flickerstreak@109: Flick@237: local Editor = { Flick@237: buttonHandlers = { } Flick@237: } flickerstreak@109: flickerstreak@185: function Editor:New() flickerstreak@185: -- create new self flickerstreak@185: self = setmetatable( { }, { __index = self } ) flickerstreak@109: flickerstreak@185: self.barOptMap = setmetatable({},{__mode="v"}) flickerstreak@185: self.tmp = { } flickerstreak@185: self.configID = "ReAction-Editor" flickerstreak@109: flickerstreak@185: self.gui = LibStub("AceGUI-3.0"):Create("Frame") flickerstreak@185: flickerstreak@185: local frame = self.gui.frame flickerstreak@109: frame:SetClampedToScreen(true) flickerstreak@109: frame:Hide() flickerstreak@185: flickerstreak@185: frame:SetScript("OnHide", flickerstreak@185: function(...) flickerstreak@109: ReAction:SetConfigMode(false) flickerstreak@185: end) flickerstreak@109: flickerstreak@195: self.title = ("%s - %s"):format(L["ReAction"],L["Bar Editor"]) flickerstreak@195: self.gui:SetTitle(self.title) flickerstreak@195: flickerstreak@185: self.options = { flickerstreak@109: type = "group", flickerstreak@195: name = self.title, flickerstreak@185: handler = self, flickerstreak@185: childGroups = "select", flickerstreak@109: args = { flickerstreak@109: launchConfig = { flickerstreak@109: type = "execute", flickerstreak@109: name = L["Global Config"], flickerstreak@109: desc = L["Opens ReAction global configuration settings panel"], flickerstreak@194: func = function() ReAction:ShowOptions(); self:Close() end, flickerstreak@185: order = 1 flickerstreak@109: }, flickerstreak@185: desc = { flickerstreak@185: type = "description", flickerstreak@185: name = L["Use the mouse to arrange and resize the bars on screen. Tooltips on bars indicate additional functionality."], flickerstreak@195: order = 2, flickerstreak@195: }, flickerstreak@195: hdr = { flickerstreak@195: type = "header", flickerstreak@195: name = L["Select Bar"], flickerstreak@194: order = 3, flickerstreak@185: }, flickerstreak@185: _new = { flickerstreak@109: type = "group", flickerstreak@109: name = L["New Bar..."], flickerstreak@194: order = 4, flickerstreak@109: args = { flickerstreak@109: desc = { flickerstreak@109: type = "description", flickerstreak@109: name = L["Choose a name, type, and initial grid for your new action bar:"], flickerstreak@109: order = 1, flickerstreak@109: }, flickerstreak@109: name = { flickerstreak@109: type = "input", flickerstreak@109: name = L["Bar Name"], flickerstreak@109: desc = L["Enter a name for your new action bar"], flickerstreak@185: get = function() return self.tmp.barName or "" end, flickerstreak@185: set = function(info, val) self.tmp.barName = val end, flickerstreak@109: order = 2, flickerstreak@109: }, flickerstreak@109: type = { flickerstreak@109: type = "select", flickerstreak@109: name = L["Button Type"], flickerstreak@185: get = function() return self.tmp.barType or ReAction:GetDefaultBarType() or "" end, flickerstreak@109: set = function(info, val) flickerstreak@218: local c = ReAction:GetDefaultBarConfig(val) flickerstreak@185: self.tmp.barType = val flickerstreak@218: self.tmp.barSize = c.btnWidth or self.tmp.barSize flickerstreak@218: self.tmp.barRows = c.btnRows or self.tmp.barRows flickerstreak@218: self.tmp.barCols = c.btnColumns or self.tmp.barCols flickerstreak@218: self.tmp.barSpacing = c.spacing or self.tmp.barSpacing flickerstreak@109: end, flickerstreak@109: values = "GetBarTypes", flickerstreak@109: order = 3, flickerstreak@109: }, flickerstreak@185: go = { flickerstreak@185: type = "execute", flickerstreak@185: name = L["Create Bar"], flickerstreak@185: func = "CreateBar", flickerstreak@185: order = 4, flickerstreak@185: }, flickerstreak@109: grid = { flickerstreak@109: type = "group", flickerstreak@109: name = L["Button Grid"], flickerstreak@109: inline = true, flickerstreak@185: order = 5, flickerstreak@109: args = { flickerstreak@109: rows = { flickerstreak@109: type = "range", flickerstreak@109: name = L["Rows"], flickerstreak@185: get = function() return self.tmp.barRows or 1 end, flickerstreak@185: set = function(info, val) self.tmp.barRows = val end, flickerstreak@185: width = "full", flickerstreak@109: min = 1, flickerstreak@109: max = 32, flickerstreak@109: step = 1, flickerstreak@109: order = 2, flickerstreak@109: }, flickerstreak@109: cols = { flickerstreak@109: type = "range", flickerstreak@109: name = L["Columns"], flickerstreak@185: get = function() return self.tmp.barCols or 12 end, flickerstreak@185: set = function(info, val) self.tmp.barCols = val end, flickerstreak@185: width = "full", flickerstreak@109: min = 1, flickerstreak@109: max = 32, flickerstreak@109: step = 1, flickerstreak@109: order = 3, flickerstreak@109: }, flickerstreak@109: sz = { flickerstreak@109: type = "range", flickerstreak@109: name = L["Size"], flickerstreak@185: get = function() return self.tmp.barSize or 36 end, flickerstreak@185: set = function(info, val) self.tmp.barSize = val end, flickerstreak@185: width = "full", flickerstreak@109: min = 10, flickerstreak@109: max = 72, flickerstreak@109: step = 1, flickerstreak@109: order = 4, flickerstreak@109: }, flickerstreak@109: spacing = { flickerstreak@109: type = "range", flickerstreak@109: name = L["Spacing"], flickerstreak@185: get = function() return self.tmp.barSpacing or 3 end, flickerstreak@185: set = function(info, val) self.tmp.barSpacing = val end, flickerstreak@185: width = "full", flickerstreak@109: min = 0, flickerstreak@109: max = 24, flickerstreak@109: step = 1, flickerstreak@109: order = 5, flickerstreak@109: } flickerstreak@195: } flickerstreak@195: } flickerstreak@109: } flickerstreak@109: } flickerstreak@195: } flickerstreak@109: } flickerstreak@109: flickerstreak@185: self.gui:SetCallback("OnClose", flickerstreak@185: function() flickerstreak@185: ReAction:SetConfigMode(false) flickerstreak@185: end ) flickerstreak@185: flickerstreak@185: AceConfigReg:RegisterOptionsTable(self.configID, self.options) flickerstreak@185: AceConfigDialog:SetDefaultSize(self.configID, 700, 540) flickerstreak@185: flickerstreak@185: ReAction.RegisterCallback(self,"OnCreateBar") flickerstreak@185: ReAction.RegisterCallback(self,"OnDestroyBar") flickerstreak@185: ReAction.RegisterCallback(self,"OnRenameBar") flickerstreak@185: flickerstreak@216: self:RefreshBarOptions() flickerstreak@109: flickerstreak@185: return self flickerstreak@109: end flickerstreak@109: flickerstreak@109: flickerstreak@185: function Editor:Open(bar, ...) flickerstreak@185: if bar then flickerstreak@185: AceConfigDialog:SelectGroup(self.configID, self.barOptMap[bar:GetName()], ...) flickerstreak@185: end flickerstreak@185: AceConfigDialog:Open(self.configID,self.gui) flickerstreak@185: self.gui:SetTitle(self.title) flickerstreak@185: end flickerstreak@185: flickerstreak@185: function Editor:Close() flickerstreak@185: if self.gui then flickerstreak@185: self.gui:ReleaseChildren() flickerstreak@185: self.gui:Hide() flickerstreak@109: end flickerstreak@109: end flickerstreak@109: flickerstreak@185: function Editor:Refresh() flickerstreak@185: AceConfigReg:NotifyChange(self.configID) flickerstreak@185: end flickerstreak@185: flickerstreak@216: function Editor:UpdateBarOptions(bar) flickerstreak@185: local name = bar:GetName() flickerstreak@216: local key = self.barOptMap[name] flickerstreak@185: local args = self.options.args flickerstreak@216: flickerstreak@216: if not key then flickerstreak@216: -- AceConfig doesn't allow spaces, etc, in arg key names, and they must be flickerstreak@216: -- unique strings. So generate a unique key (it can be whatever) for the bar flickerstreak@216: local i = 1 flickerstreak@216: repeat flickerstreak@216: key = ("bar%s"):format(i) flickerstreak@216: i = i+1 flickerstreak@216: until args[key] == nil flickerstreak@216: self.barOptMap[name] = key flickerstreak@216: flickerstreak@216: args[key] = { flickerstreak@216: type = "group", flickerstreak@216: name = name, flickerstreak@216: childGroups = "tab", flickerstreak@216: order = i+100, flickerstreak@216: args = { flickerstreak@216: general = { flickerstreak@216: type = "group", flickerstreak@216: name = L["General"], flickerstreak@216: order = 1, flickerstreak@216: args = { flickerstreak@216: name = { flickerstreak@216: type = "input", flickerstreak@216: name = L["Rename Bar"], flickerstreak@216: get = function() return bar:GetName() end, flickerstreak@216: set = function(info, value) return ReAction:RenameBar(bar, value) end, flickerstreak@216: order = 1, flickerstreak@216: }, flickerstreak@216: delete = { flickerstreak@216: type = "execute", flickerstreak@216: name = L["Delete Bar"], flickerstreak@216: desc = function() return bar:GetName() end, flickerstreak@216: confirm = true, flickerstreak@216: func = function() ReAction:EraseBar(bar) end, flickerstreak@216: order = 2 flickerstreak@216: }, flickerstreak@216: anchor = { flickerstreak@216: type = "group", flickerstreak@216: name = L["Anchor"], flickerstreak@216: inline = true, flickerstreak@216: args = { flickerstreak@216: frame = { flickerstreak@216: type = "input", flickerstreak@216: name = L["Frame"], flickerstreak@216: desc = L["The frame that the bar is anchored to"], flickerstreak@216: get = function() local _, f = bar:GetAnchor(); return f end, flickerstreak@216: set = function(info, val) bar:SetAnchor(nil,val) end, flickerstreak@216: validate = function(info, name) flickerstreak@216: if name then flickerstreak@216: local f = ReAction:GetBar(name) flickerstreak@216: if f then flickerstreak@216: return true flickerstreak@216: else flickerstreak@216: f = _G[name] flickerstreak@216: if f and type(f) == "table" and f.IsObjectType and f:IsObjectType("Frame") then flickerstreak@216: local _, explicit = f:IsProtected() flickerstreak@216: return explicit flickerstreak@216: end flickerstreak@185: end flickerstreak@185: end flickerstreak@216: return false flickerstreak@216: end, flickerstreak@216: width = "double", flickerstreak@216: order = 1 flickerstreak@216: }, flickerstreak@216: point = { flickerstreak@216: type = "select", flickerstreak@216: name = L["Point"], flickerstreak@216: desc = L["Anchor point on the bar frame"], flickerstreak@216: style = "dropdown", flickerstreak@216: get = function() return bar:GetAnchor() end, flickerstreak@216: set = function(info, val) bar:SetAnchor(val) end, flickerstreak@216: values = pointTable, flickerstreak@216: order = 2, flickerstreak@216: }, flickerstreak@216: relativePoint = { flickerstreak@216: type = "select", flickerstreak@216: name = L["Relative Point"], flickerstreak@216: desc = L["Anchor point on the target frame"], flickerstreak@216: style = "dropdown", flickerstreak@216: get = function() local p,f,r = bar:GetAnchor(); return r end, flickerstreak@216: set = function(info, val) bar:SetAnchor(nil,nil,val) end, flickerstreak@216: values = pointTable, flickerstreak@216: order = 3, flickerstreak@216: }, flickerstreak@216: x = { flickerstreak@216: type = "input", flickerstreak@216: pattern = "\-?%d+", flickerstreak@216: name = L["X offset"], flickerstreak@216: get = function() local p,f,r,x = bar:GetAnchor(); return ("%d"):format(x) end, flickerstreak@216: set = function(info,val) bar:SetAnchor(nil,nil,nil,val) end, flickerstreak@216: order = 4 flickerstreak@216: }, flickerstreak@216: y = { flickerstreak@216: type = "input", flickerstreak@216: pattern = "\-?%d+", flickerstreak@216: name = L["Y offset"], flickerstreak@216: get = function() local p,f,r,x,y = bar:GetAnchor(); return ("%d"):format(y) end, flickerstreak@216: set = function(info,val) bar:SetAnchor(nil,nil,nil,nil,val) end, flickerstreak@216: order = 5 flickerstreak@216: }, flickerstreak@185: }, flickerstreak@216: order = 3 flickerstreak@185: }, flickerstreak@216: alpha = { flickerstreak@216: type = "range", flickerstreak@216: name = L["Transparency"], flickerstreak@216: get = function() return bar:GetAlpha() end, flickerstreak@216: set = function(info, val) bar:SetAlpha(val) end, flickerstreak@216: min = 0, flickerstreak@216: max = 1, flickerstreak@216: isPercent = true, flickerstreak@216: step = 0.01, flickerstreak@216: bigStep = 0.05, flickerstreak@216: order = 4, flickerstreak@216: }, flickerstreak@185: }, flickerstreak@185: }, Flick@237: buttonOpts = self:CreateButtonOptions(bar) flickerstreak@185: }, flickerstreak@216: plugins = { } flickerstreak@185: } flickerstreak@216: end flickerstreak@216: flickerstreak@216: if ReAction.barOptionGenerators then flickerstreak@216: for module, func in pairs(ReAction.barOptionGenerators) do flickerstreak@216: local success, r flickerstreak@216: if type(func) == "string" then flickerstreak@216: success, r = pcall(module[func], module, bar) flickerstreak@216: else flickerstreak@216: success, r = pcall(func, bar) flickerstreak@216: end flickerstreak@216: if success then flickerstreak@216: if r then flickerstreak@216: args[key].plugins[module:GetName()] = { [module:GetName()] = r } flickerstreak@216: end flickerstreak@216: else flickerstreak@216: geterrorhandler()(r) flickerstreak@216: end flickerstreak@216: end flickerstreak@216: end flickerstreak@185: end flickerstreak@185: Flick@237: function Editor:CreateButtonOptions(bar) Flick@237: local buttonClass = bar:GetButtonClass() Flick@237: local classID = buttonClass:GetButtonTypeID() Flick@237: local handler = self.buttonHandlers[classID] Flick@237: Flick@237: if handler then Flick@237: local h = handler:New(bar) Flick@237: return h:GetOptions() Flick@237: end Flick@237: end Flick@237: flickerstreak@185: function Editor:RefreshBarOptions() flickerstreak@219: for name, key in pairs(self.barOptMap) do flickerstreak@216: if not ReAction:GetBar(name) then flickerstreak@219: self.barOptMap[name] = nil flickerstreak@219: self.options.args[key] = nil flickerstreak@185: end flickerstreak@185: end flickerstreak@216: for name, bar in ReAction:IterateBars() do flickerstreak@216: self:UpdateBarOptions(bar) flickerstreak@216: end flickerstreak@216: self:Refresh() flickerstreak@185: end flickerstreak@185: flickerstreak@185: function Editor:OnCreateBar(evt, bar) flickerstreak@216: self:UpdateBarOptions(bar) flickerstreak@216: self:Refresh() flickerstreak@185: end flickerstreak@185: flickerstreak@185: function Editor:OnDestroyBar(evt, bar, name) flickerstreak@185: local key = self.barOptMap[name] flickerstreak@185: if key then flickerstreak@216: self.barOptMap[name] = nil flickerstreak@185: self.options.args[key] = nil flickerstreak@185: self:Refresh() flickerstreak@185: end flickerstreak@185: end flickerstreak@185: flickerstreak@185: function Editor:OnRenameBar(evt, bar, oldname, newname) flickerstreak@185: local key = self.barOptMap[oldname] flickerstreak@185: if key then flickerstreak@216: self.barOptMap[oldname], self.barOptMap[newname] = nil, key flickerstreak@185: self.options.args[key].name = newname flickerstreak@185: self:Refresh() flickerstreak@185: end flickerstreak@185: end flickerstreak@185: flickerstreak@185: local _scratch = { } flickerstreak@185: function Editor:GetBarTypes() flickerstreak@185: wipe(_scratch) flickerstreak@185: return ReAction:GetBarTypeOptions(_scratch) flickerstreak@185: end flickerstreak@185: flickerstreak@185: function Editor:CreateBar() flickerstreak@185: if self.tmp.barName and self.tmp.barName ~= "" then flickerstreak@185: local bar = ReAction:CreateBar(self.tmp.barName, self.tmp.barType or ReAction:GetDefaultBarType(), self.tmp.barRows, self.tmp.barCols, self.tmp.barSize, self.tmp.barSpacing) flickerstreak@185: if bar then flickerstreak@185: AceConfigDialog:SelectGroup(self.configID, self.barOptMap[self.tmp.barName]) flickerstreak@185: self.tmp.barName = nil flickerstreak@185: end flickerstreak@185: end flickerstreak@185: end flickerstreak@185: Flick@237: ------------------------------- Flick@237: ---- Action button handler ---- Flick@237: ------------------------------- Flick@237: Flick@237: do Flick@237: local ActionHandler = { Flick@237: buttonClass = ReAction.Button.Action, Flick@237: options = { Flick@237: hideEmpty = { Flick@237: name = L["Hide Empty Buttons"], Flick@237: order = 1, Flick@237: type = "toggle", Flick@237: width = "double", Flick@237: get = "GetHideEmpty", Flick@237: set = "SetHideEmpty", Flick@237: }, Flick@237: lockButtons = { Flick@237: name = L["Lock Buttons"], Flick@237: desc = L["Prevents picking up/dragging actions (use SHIFT to override this behavior)"], Flick@237: order = 2, Flick@237: type = "toggle", Flick@237: get = "GetLockButtons", Flick@237: set = "SetLockButtons", Flick@237: }, Flick@237: lockOnlyCombat = { Flick@237: name = L["Only in Combat"], Flick@237: desc = L["Only lock the buttons when in combat"], Flick@237: order = 3, Flick@237: type = "toggle", Flick@237: disabled = "LockButtonsCombatDisabled", Flick@237: get = "GetLockButtonsCombat", Flick@237: set = "SetLockButtonsCombat", Flick@237: }, Flick@237: pages = { Flick@237: name = L["# Pages"], Flick@237: desc = L["Use the Dynamic State tab to specify page transitions"], Flick@237: order = 4, Flick@237: type = "range", Flick@237: min = 1, Flick@237: max = 10, Flick@237: step = 1, Flick@237: get = "GetNumPages", Flick@237: set = "SetNumPages", Flick@237: }, Flick@237: mindcontrol = { Flick@237: name = L["Mind Control Support"], Flick@237: desc = L["When possessing a target (e.g. via Mind Control), map the first 12 buttons of this bar to the possessed target's actions."], Flick@237: order = 5, Flick@237: type = "toggle", Flick@237: width = "double", Flick@237: set = "SetMindControl", Flick@237: get = "GetMindControl", Flick@237: }, Flick@237: vehicle = { Flick@237: name = L["Vehicle Support"], Flick@237: desc = L["When on a vehicle, map the first 6 buttons of this bar to the vehicle actions. The vehicle-exit button is mapped to the 7th button. Pitch controls are not supported."], Flick@237: order = 6, Flick@237: type = "toggle", Flick@237: width = "double", Flick@237: get = "GetVehicle", Flick@237: set = "SetVehicle", Flick@237: }, Flick@237: actions = { Flick@237: name = L["Edit Action IDs"], Flick@237: order = 7, Flick@237: type = "group", Flick@237: inline = true, Flick@237: args = { Flick@237: method = { Flick@237: name = L["Assign"], Flick@237: order = 1, Flick@237: type = "select", Flick@237: width = "double", Flick@237: values = { [0] = L["Choose Method..."], Flick@237: [1] = L["Individually"], Flick@237: [2] = L["All at Once"], }, Flick@237: get = "GetActionEditMethod", Flick@237: set = "SetActionEditMethod", Flick@237: }, Flick@237: rowSelect = { Flick@237: name = L["Row"], Flick@237: desc = L["Rows are numbered top to bottom"], Flick@237: order = 2, Flick@237: type = "select", Flick@237: width = "half", Flick@237: hidden = "IsButtonSelectHidden", Flick@237: values = "GetRowList", Flick@237: get = "GetSelectedRow", Flick@237: set = "SetSelectedRow", Flick@237: }, Flick@237: colSelect = { Flick@237: name = L["Col"], Flick@237: desc = L["Columns are numbered left to right"], Flick@237: order = 3, Flick@237: type = "select", Flick@237: width = "half", Flick@237: hidden = "IsButtonSelectHidden", Flick@237: values = "GetColumnList", Flick@237: get = "GetSelectedColumn", Flick@237: set = "SetSelectedColumn", Flick@237: }, Flick@237: pageSelect = { Flick@237: name = L["Page"], Flick@237: order = 4, Flick@237: type = "select", Flick@237: width = "half", Flick@237: hidden = "IsPageSelectHidden", Flick@237: values = "GetPageList", Flick@237: get = "GetSelectedPage", Flick@237: set = "SetSelectedPage", Flick@237: }, Flick@237: single = { Flick@237: name = L["Action ID"], Flick@237: usage = L["Specify ID 1-120"], Flick@237: order = 5, Flick@237: type = "input", Flick@237: width = "half", Flick@237: hidden = "IsButtonSelectHidden", Flick@237: get = "GetActionID", Flick@237: set = "SetActionID", Flick@237: validate = "ValidateActionID", Flick@237: }, Flick@237: multi = { Flick@237: name = L["ID List"], Flick@237: usage = L["Specify a comma-separated list of IDs for each button in the bar (in order). Separate multiple pages with semicolons (;)"], Flick@237: order = 6, Flick@237: type = "input", Flick@237: multiline = true, Flick@237: width = "double", Flick@237: hidden = "IsMultiIDHidden", Flick@237: get = "GetMultiID", Flick@237: set = "SetMultiID", Flick@237: validate = "ValidateMultiID", Flick@237: }, Flick@237: }, Flick@237: }, Flick@237: } Flick@237: } Flick@237: Flick@237: Editor.buttonHandlers[ActionHandler.buttonClass:GetButtonTypeID()] = ActionHandler Flick@237: Flick@237: local meta = { __index = ActionHandler } Flick@237: Flick@237: function ActionHandler:New( bar ) Flick@237: return setmetatable( Flick@237: { Flick@237: bar = bar, Flick@237: config = bar:GetConfig(), Flick@237: }, Flick@237: meta) Flick@237: end Flick@237: Flick@237: function ActionHandler:Refresh() Flick@237: self.buttonClass:SetupBar(self.bar) Flick@237: end Flick@237: Flick@237: function ActionHandler:UpdateButtonLock() Flick@237: self.buttonClass:SetButtonLock(self.bar, self.config.lockButtons, self.config.lockButtonsCombat) Flick@237: end Flick@237: Flick@237: function ActionHandler:GetLastButton() Flick@237: return self.bar:GetButton(self.bar:GetNumButtons()) Flick@237: end Flick@237: Flick@237: -- options handlers Flick@237: function ActionHandler:GetOptions() Flick@237: return { Flick@237: type = "group", Flick@237: name = L["Action Buttons"], Flick@237: handler = self, Flick@237: order = 2, Flick@237: args = self.options Flick@237: } Flick@237: end Flick@237: Flick@237: function ActionHandler:SetHideEmpty(info, value) Flick@237: if value ~= self.config.hideEmpty then Flick@237: self.config.hideEmpty = value Flick@237: for _, b in self.bar:IterateButtons() do Flick@237: b:ShowGrid(not value) Flick@237: end Flick@237: end Flick@237: end Flick@237: Flick@237: function ActionHandler:GetHideEmpty() Flick@237: return self.config.hideEmpty Flick@237: end Flick@237: Flick@237: function ActionHandler:GetLockButtons() Flick@237: return self.config.lockButtons Flick@237: end Flick@237: Flick@237: function ActionHandler:SetLockButtons(info, value) Flick@237: self.config.lockButtons = value Flick@237: self:UpdateButtonLock() Flick@237: end Flick@237: Flick@237: function ActionHandler:GetLockButtonsCombat() Flick@237: return self.config.lockButtonsCombat Flick@237: end Flick@237: Flick@237: function ActionHandler:SetLockButtonsCombat(info, value) Flick@237: self.config.lockButtonsCombat = value Flick@237: self:UpdateButtonLock() Flick@237: end Flick@237: Flick@237: function ActionHandler:LockButtonsCombatDisabled() Flick@237: return not self.config.lockButtons Flick@237: end Flick@237: Flick@237: function ActionHandler:GetNumPages() Flick@237: return self.config.nPages Flick@237: end Flick@237: Flick@237: function ActionHandler:SetNumPages(info, value) Flick@237: self.config.nPages = value Flick@237: self:Refresh() Flick@237: end Flick@237: Flick@237: function ActionHandler:GetMindControl() Flick@237: return self.config.mindcontrol Flick@237: end Flick@237: Flick@237: function ActionHandler:SetMindControl(info, value) Flick@237: self.config.mindcontrol = value Flick@237: self:Refresh() Flick@237: end Flick@237: Flick@237: function ActionHandler:GetVehicle() Flick@237: return self.config.vehicle Flick@237: end Flick@237: Flick@237: function ActionHandler:SetVehicle(info, value) Flick@237: self.config.vehicle = value Flick@237: self:Refresh() Flick@237: end Flick@237: Flick@237: function ActionHandler:GetActionEditMethod() Flick@237: return self.editMethod or 0 Flick@237: end Flick@237: Flick@237: function ActionHandler:SetActionEditMethod(info, value) Flick@237: self.editMethod = value Flick@237: end Flick@237: Flick@237: function ActionHandler:IsButtonSelectHidden() Flick@237: return self.editMethod ~= 1 Flick@237: end Flick@237: Flick@237: function ActionHandler:GetRowList() Flick@237: local r,c = self.bar:GetButtonGrid() Flick@237: if self.rowList == nil or #self.rowList ~= r then Flick@237: local list = { } Flick@237: for i = 1, r do Flick@237: table.insert(list,i) Flick@237: end Flick@237: self.rowList = list Flick@237: end Flick@237: return self.rowList Flick@237: end Flick@237: Flick@237: function ActionHandler:GetSelectedRow() Flick@237: local r, c = self.bar:GetButtonGrid() Flick@237: local row = self.selectedRow or 1 Flick@237: if row > r then Flick@237: row = 1 Flick@237: end Flick@237: self.selectedRow = row Flick@237: return row Flick@237: end Flick@237: Flick@237: function ActionHandler:SetSelectedRow(info, value) Flick@237: self.selectedRow = value Flick@237: end Flick@237: Flick@237: function ActionHandler:GetColumnList() Flick@237: local r,c = self.bar:GetButtonGrid() Flick@237: if self.columnList == nil or #self.columnList ~= c then Flick@237: local list = { } Flick@237: for i = 1, c do Flick@237: table.insert(list,i) Flick@237: end Flick@237: self.columnList = list Flick@237: end Flick@237: return self.columnList Flick@237: end Flick@237: Flick@237: function ActionHandler:GetSelectedColumn() Flick@237: local r, c = self.bar:GetButtonGrid() Flick@237: local col = self.selectedColumn or 1 Flick@237: if col > c then Flick@237: col = 1 Flick@237: end Flick@237: self.selectedColumn = col Flick@237: return col Flick@237: end Flick@237: Flick@237: function ActionHandler:SetSelectedColumn(info, value) Flick@237: self.selectedColumn = value Flick@237: end Flick@237: Flick@237: function ActionHandler:IsPageSelectHidden() Flick@237: return self.editMethod ~= 1 or (self.config.nPages or 1) < 2 Flick@237: end Flick@237: Flick@237: function ActionHandler:GetPageList() Flick@237: local n = self.config.nPages or 1 Flick@237: if self.pageList == nil or #self.pageList ~= n then Flick@237: local p = { } Flick@237: for i = 1, n do Flick@237: table.insert(p,i) Flick@237: end Flick@237: self.pageList = p Flick@237: end Flick@237: return self.pageList Flick@237: end Flick@237: Flick@237: function ActionHandler:GetSelectedPage() Flick@237: local p = self.selectedPage or 1 Flick@237: if p > (self.config.nPages or 1) then Flick@237: p = 1 Flick@237: end Flick@237: self.selectedPage = p Flick@237: return p Flick@237: end Flick@237: Flick@237: function ActionHandler:SetSelectedPage(info, value) Flick@237: self.selectedPage = value Flick@237: end Flick@237: Flick@237: function ActionHandler:GetActionID() Flick@237: local row = self.selectedRow or 1 Flick@237: local col = self.selectedColumn or 1 Flick@237: local r, c = self.bar:GetButtonGrid() Flick@237: local n = (row-1) * c + col Flick@237: local btn = self.bar:GetButton(n) Flick@237: if btn then Flick@237: return tostring(btn:GetActionID(self.selectedPage or 1)) Flick@237: end Flick@237: end Flick@237: Flick@237: function ActionHandler:SetActionID(info, value) Flick@237: local row = self.selectedRow or 1 Flick@237: local col = self.selectedColumn or 1 Flick@237: local r, c = self.bar:GetButtonGrid() Flick@237: local n = (row-1) * c + col Flick@237: local btn = self.bar:GetButton(n) Flick@237: if btn then Flick@237: btn:SetActionID(tonumber(value), self.selectedPage or 1) Flick@237: end Flick@237: end Flick@237: Flick@237: function ActionHandler:ValidateActionID(info, value) Flick@237: value = tonumber(value) Flick@237: if value == nil or value < 1 or value > 120 then Flick@237: return L["Specify ID 1-120"] Flick@237: end Flick@237: return true Flick@237: end Flick@237: Flick@237: function ActionHandler:IsMultiIDHidden() Flick@237: return self.editMethod ~= 2 Flick@237: end Flick@237: Flick@237: function ActionHandler:GetMultiID() Flick@237: local p = { } Flick@237: for i = 1, self.config.nPages or 1 do Flick@237: local b = { } Flick@237: for _, btn in self.bar:IterateButtons() do Flick@237: table.insert(b, btn:GetActionID(i)) Flick@237: end Flick@237: table.insert(p, table.concat(b,",")) Flick@237: end Flick@237: return table.concat(p,";\n") Flick@237: end Flick@237: Flick@237: Flick@237: local function ParseMultiID(nBtns, nPages, s) Flick@237: if s:match("[^%d%s,;]") then Flick@237: return nil Flick@237: end Flick@237: local p = { } Flick@237: for list in s:gmatch("[^;]+") do Flick@237: local pattern = ("^%s?$"):format(("%s*(%d+)%s*,"):rep(nBtns)) Flick@237: local ids = { list:match(pattern) } Flick@237: if #ids ~= nBtns then Flick@237: return nil Flick@237: end Flick@237: table.insert(p,ids) Flick@237: end Flick@237: if #p ~= nPages then Flick@237: return nil Flick@237: end Flick@237: return p Flick@237: end Flick@237: Flick@237: function ActionHandler:SetMultiID(info, value) Flick@237: local p = ParseMultiID(self.bar:GetNumButtons(), self.config.nPages or 1, value) Flick@237: for page, b in ipairs(p) do Flick@237: for button, id in ipairs(b) do Flick@237: self.bar:GetButton(button):SetActionID(id, page) Flick@237: end Flick@237: end Flick@237: end Flick@237: Flick@237: function ActionHandler:ValidateMultiID(info, value) Flick@237: local bad = L["Invalid action ID list string"] Flick@237: if value == nil or ParseMultiID(self.bar:GetNumButtons(), self.config.nPages or 1, value) == nil then Flick@237: return bad Flick@237: end Flick@237: return true Flick@237: end Flick@237: end Flick@237: Flick@237: Flick@237: ---------------------------------- Flick@237: ---- PetAction button handler ---- Flick@237: ---------------------------------- Flick@237: Flick@237: do Flick@237: local PetHandler = { Flick@237: buttonClass = ReAction.Button.PetAction, Flick@237: } Flick@237: Flick@237: Editor.buttonHandlers[PetHandler.buttonClass:GetButtonTypeID()] = PetHandler Flick@237: Flick@237: local meta = { __index = PetHandler } Flick@237: Flick@237: function PetHandler:New(bar) Flick@237: return setmetatable( Flick@237: { Flick@237: bar = bar, Flick@237: config = bar.config Flick@237: }, meta) Flick@237: end Flick@237: Flick@237: function PetHandler:GetLockButtons() Flick@237: return self.config.lockButtons Flick@237: end Flick@237: Flick@237: function PetHandler:SetLockButtons(info, value) Flick@237: self.config.lockButtons = value Flick@237: self.buttonClass:UpdateButtonLock(self.bar) Flick@237: end Flick@237: Flick@237: function PetHandler:GetLockButtonsCombat() Flick@237: return self.config.lockButtonsCombat Flick@237: end Flick@237: Flick@237: function PetHandler:SetLockButtonsCombat(info, value) Flick@237: self.config.lockButtonsCombat = value Flick@237: self.buttonClass:UpdateButtonLock(self.bar) Flick@237: end Flick@237: Flick@237: function PetHandler:LockButtonsCombatDisabled() Flick@237: return not self.config.lockButtons Flick@237: end Flick@237: Flick@237: function PetHandler:GetOptions() Flick@237: return { Flick@237: type = "group", Flick@237: name = L["Pet Buttons"], Flick@237: handler = self, Flick@237: order = 2, Flick@237: args = { Flick@237: lockButtons = { Flick@237: name = L["Lock Buttons"], Flick@237: desc = L["Prevents picking up/dragging actions (use SHIFT to override this behavior)"], Flick@237: order = 2, Flick@237: type = "toggle", Flick@237: get = "GetLockButtons", Flick@237: set = "SetLockButtons", Flick@237: }, Flick@237: lockOnlyCombat = { Flick@237: name = L["Only in Combat"], Flick@237: desc = L["Only lock the buttons when in combat"], Flick@237: order = 3, Flick@237: type = "toggle", Flick@237: disabled = "LockButtonsCombatDisabled", Flick@237: get = "GetLockButtonsCombat", Flick@237: set = "SetLockButtonsCombat", Flick@237: }, Flick@237: } Flick@237: } Flick@237: end Flick@237: end Flick@237: Flick@237: Flick@237: ------------------------------------- Flick@237: ---- Vehicle Exit button handler ---- Flick@237: ------------------------------------- Flick@237: Flick@237: do Flick@237: local VExitHandler = { Flick@237: buttonClass = ReAction.Button.VehicleExit, Flick@237: } Flick@237: Flick@237: Editor.buttonHandlers[VExitHandler.buttonClass:GetButtonTypeID()] = VExitHandler Flick@237: Flick@237: local meta = { __index = VExitHandler } Flick@237: Flick@237: function VExitHandler:New(bar) Flick@237: return setmetatable( Flick@237: { Flick@237: bar = bar, Flick@237: }, meta) Flick@237: end Flick@237: Flick@237: function VExitHandler:GetConfig() Flick@237: return self.bar:GetConfig() Flick@237: end Flick@237: Flick@237: function VExitHandler:GetPassengerOnly() Flick@237: return not self:GetConfig().withControls Flick@237: end Flick@237: Flick@237: function VExitHandler:SetPassengerOnly(info, value) Flick@237: self:GetConfig().withControls = not value Flick@237: self.buttonClass:UpdateRegistration(self.bar) Flick@237: end Flick@237: Flick@237: Flick@237: function VExitHandler:GetOptions() Flick@237: return { Flick@237: type = "group", Flick@237: name = L["Exit Vehicle"], Flick@237: handler = self, Flick@237: args = { Flick@237: passengerOnly = { Flick@237: name = L["Show only when passenger"], Flick@237: desc = L["Only show the button when riding as a passenger in a vehicle (no vehicle controls)"], Flick@237: order = 2, Flick@237: width = "double", Flick@237: type = "toggle", Flick@237: get = "GetPassengerOnly", Flick@237: set = "SetPassengerOnly", Flick@237: }, Flick@237: } Flick@237: } Flick@237: end Flick@237: end Flick@237: flickerstreak@185: flickerstreak@185: flickerstreak@185: ---- Export to ReAction ---- flickerstreak@185: function ReAction:ShowEditor(bar, ...) flickerstreak@185: if InCombatLockdown() then flickerstreak@185: self:UserError(L["ReAction config mode disabled during combat."]) flickerstreak@185: else flickerstreak@185: self.editor = self.editor or Editor:New() flickerstreak@185: self.editor:Open(bar, ...) flickerstreak@185: self:SetConfigMode(true) flickerstreak@185: end flickerstreak@185: end flickerstreak@185: flickerstreak@185: function ReAction:CloseEditor() flickerstreak@185: if self.editor then flickerstreak@185: self.editor:Close() flickerstreak@185: end flickerstreak@185: end flickerstreak@185: flickerstreak@185: function ReAction:RefreshEditor() flickerstreak@185: if self.editor then flickerstreak@185: self.editor:RefreshBarOptions() flickerstreak@185: end flickerstreak@185: end flickerstreak@185: flickerstreak@185: function ReAction:RegisterBarOptionGenerator( module, func ) flickerstreak@185: if not module or type(module) ~= "table" then -- doesn't need to be a proper module, strictly flickerstreak@185: error("ReAction:RegisterBarOptionGenerator() : Invalid module") flickerstreak@185: end flickerstreak@185: if type(func) == "string" then flickerstreak@185: if not module[func] then flickerstreak@185: error(("ReAction:RegisterBarOptionGenerator() : Invalid method '%s'"):format(func)) flickerstreak@185: end flickerstreak@185: elseif func and type(func) ~= "function" then flickerstreak@185: error("ReAction:RegisterBarOptionGenerator() : Invalid function") flickerstreak@185: end flickerstreak@185: self.barOptionGenerators = self.barOptionGenerators or { } flickerstreak@185: self.barOptionGenerators[module] = func flickerstreak@185: flickerstreak@185: if self.editor then flickerstreak@185: self.editor:RefreshBarOptions() flickerstreak@185: end flickerstreak@185: end flickerstreak@185: