From 321d991fd5fbaed047af25919bb6399bb4316590 Mon Sep 17 00:00:00 2001 From: p3lim-52096 Date: Tue, 14 Oct 2008 17:56:01 +0000 Subject: [PATCH] Update to 30000 git-svn-id: svn://svn.wowinterface.com/pMinimap-54/trunk@25 ae24c21f-2f0c-4c94-9256-0092abe71e0d --- pMinimap/Libs/LibSimpleOptions-1.0.lua | 955 ++++++++++++++++++++++++++++++++ pMinimap/Libs/LibStub.lua | 51 ++ pMinimap/pMinimap.lua | 9 +- pMinimap/pMinimap.toc | 10 +- pMinimap/pMinimapConfig.lua | 2 +- 5 files changed, 1017 insertions(+), 10 deletions(-) create mode 100644 pMinimap/Libs/LibSimpleOptions-1.0.lua create mode 100644 pMinimap/Libs/LibStub.lua diff --git a/pMinimap/Libs/LibSimpleOptions-1.0.lua b/pMinimap/Libs/LibSimpleOptions-1.0.lua new file mode 100644 index 0000000..b7a21a8 --- /dev/null +++ b/pMinimap/Libs/LibSimpleOptions-1.0.lua @@ -0,0 +1,955 @@ +--[[ +Name: LibSimpleOptions-1.0 +Revision: $Rev: 81443 $ +Author(s): ckknight (ckknight@gmail.com) +Website: http://ckknight.wowinterface.com/ +Description: A library to provide a way to easily create controls for Blizzard's options system +License: MIT +]] + +local MAJOR_VERSION = "LibSimpleOptions-1.0" +local MINOR_VERSION = tonumber(("$Revision: 81443 $"):match("(%d+)")) + +if not LibStub then error(MAJOR_VERSION .. " requires LibStub") end + +-- #AUTODOC_NAMESPACE LibSimpleOptions + +local LibSimpleOptions, oldLib = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION) +if not LibSimpleOptions then + return +end +if oldLib then + oldLib = {} + for k, v in pairs(LibSimpleOptions) do + LibSimpleOptions[k] = nil + oldLib[k] = v + end +end + +local getArgs, doneArgs +do + local tmp = {} + function getArgs(...) + assert(next(tmp) == nil) + for i = 1, select('#', ...), 2 do + local k, v = select(i, ...) + if type(k) ~= "string" then + error(("Received a bad key, must be a %q, got %q (%s)"):format("string", type(k), tostring(k)), 3) + elseif tmp[k] ~= nil then + error(("Received key %q twice"):format(k), 3) + end + tmp[k] = v + end + return tmp + end + function doneArgs(args) + assert(args == tmp) + for k in pairs(args) do + args[k] = nil + end + return nil + end +end + +local WotLK = not not ToggleAchievementFrame + +local panels +if oldLib then + panels = oldLib.panels or {} +else + panels = {} +end +LibSimpleOptions.panels = panels + +local panelMeta +if oldLib then + panelMeta = oldLib.panelMeta or {} +else + panelMeta = {} +end +LibSimpleOptions.panelMeta = panelMeta +for funcName in pairs(panelMeta) do + for panel in pairs(panels) do + panel[funcName] = nil + end + panelMeta[funcName] = nil +end + +do + local function update(control, ...) + if (...) ~= control.value then + control:SetValue(...) + end + end + --- Refresh a panel's controls + -- This updates any controls that provide a getFunc + -- When a panel is shown, this is automatically called + -- @name panel:Refresh + -- @usage panel:Refresh() + function panelMeta:Refresh() + for control in pairs(self.controls) do + if control.getFunc then + update(control, control.getFunc()) + end + end + if self.refreshFunc then + self:refreshFunc() + end + end + local function panel_OnShow(self) + self:SetScript("OnShow", self.Refresh) + self:controlCreationFunc() + self.controlCreationFunc = nil + self:Refresh() + end + local function panel_okay(self) + for control in pairs(self.controls) do + control.oldValue = control.value + if control.okayFunc then + control.okayFunc() + end + end + end + local function panel_cancel(self) + for control in pairs(self.controls) do + control:SetValue(control.oldValue) + if control.cancelFunc then + control.cancelFunc() + end + end + end + local function panel_default(self) + for control in pairs(self.controls) do + control:SetValue(control.default) + if control.defaultFunc then + control.defaultFunc() + end + end + end + local function makePanel(name, parentName, controlCreationFunc) + local panel + if not parentName then + panel = CreateFrame("Frame", name .. "_Panel") + else + panel = CreateFrame("Frame", parentName .. "_Panel_" .. name) + end + panels[panel] = true + + panel.name = name + panel.controls = {} + panel.parent = parentName + + panel.okay = panel_okay + panel.cancel = panel_cancel + panel.default = panel_default + + InterfaceOptions_AddCategory(panel) + + panel.controlCreationFunc = controlCreationFunc + panel:SetScript("OnShow", panel_OnShow) + for k, v in pairs(panelMeta) do + panel[k] = v + end + end + + --- Make a new options panel and add it to the Blizzard Interface Options + -- @param name name of your panel + -- @param controlCreationFunc function to call when the panel is first shown + -- @usage LibStub("LibSimpleOptions-1.0").AddOptionsPanel("My Options", function(panel) ... end) + -- @return the created panel + function LibSimpleOptions.AddOptionsPanel(name, controlCreationFunc) + return makePanel(name, nil, controlCreationFunc) + end + + --- Make a new options panel that is a child of another options panel and add it to the Blizzard Interface Options + -- @param parentName name of the parent panel + -- @param name name of your panel + -- @param controlCreationFunc function to call when the panel is first shown + -- @usage LibStub("LibSimpleOptions-1.0").AddOptionsPanel("My Options", "My Suboptions", function(panel) ... end) + -- @return the created panel + function LibSimpleOptions.AddSuboptionsPanel(parentName, name, controlCreationFunc) + return makePanel(name, parentName, controlCreationFunc) + end +end + +--- Return a new title text and sub-text for a panel. +-- Note that this automatically places the title and sub-text appropriately +-- @name panel:MakeTitleTextAndSubText +-- @param titleText the text to show as the title +-- @param subTextText the text to show as the sub-text +-- @usage local title, subText = panel:MakeTitleTextAndSubText("My Options", "These allow you to change assorted options") +-- @return the title FontString +-- @return the sub-text FontString +function panelMeta:MakeTitleTextAndSubText(titleText, subTextText) + local title = self:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge") + title:SetText(titleText) + title:SetJustifyH("LEFT") + title:SetJustifyV("TOP") + title:SetPoint("TOPLEFT", 16, -16) + + local subText = self:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall") + subText:SetText(subTextText) + subText:SetNonSpaceWrap(true) + subText:SetJustifyH("LEFT") + subText:SetJustifyV("TOP") + subText:SetPoint("TOPLEFT", title, "BOTTOMLEFT", 0, -8) + subText:SetPoint("RIGHT", -32, 0) + + return title, subText +end + +do + local backdrop = { + bgFile = [=[Interface\Buttons\WHITE8X8]=], + edgeFile = [=[Interface\Tooltips\UI-Tooltip-Border]=], + tile = true, + tileSize = 16, + edgeSize = 16, + insets = { left = 3, right = 3, top = 3, bottom = 3 }, + } + --- Return a scrollable frame to organize controls within + -- This is useful to create if you have too many controls to properly fit within one panel + -- @name panel:MakeScrollFrame + -- @usage local scrollFrame = panel:MakeScrollFrame() + -- @return the ScrollFrame + function panelMeta:MakeScrollFrame() + local name + local i = 0 + repeat + i = i + 1 + name = self:GetName() .. "_ScrollFrame" .. i + until not _G[name] + local scrollFrame = CreateFrame("ScrollFrame", name, self, "UIPanelScrollFrameTemplate") + scrollFrame:SetFrameLevel(scrollFrame:GetFrameLevel() + 1) + local bg = CreateFrame("Frame", nil, self) + bg:SetPoint("TOPLEFT", scrollFrame, "TOPLEFT", -3, 3) + bg:SetPoint("BOTTOMRIGHT", scrollFrame, "BOTTOMRIGHT", 3, -3) + bg:SetBackdrop(backdrop) + bg:SetBackdropColor(0, 0, 0, 0.25) + local scrollChild = CreateFrame("Frame", name .. "_Child", scrollFrame) + scrollFrame:SetScrollChild(scrollChild) + scrollChild:SetWidth(1) + scrollChild:SetHeight(1) + return scrollFrame, scrollChild + end +end + +do + local function slider_OnValueChanged(self) + self.value = self:GetValue() + self:SetValue(self:GetValue()) + end + + local function slider_SetValue(self, value) + getmetatable(self).__index.SetValue(self, value) + self.value = value + self.changeFunc(value) + if self.currentText then + self.currentText:SetText(self.currentTextFunc(value)) + end + end + + --- Return a horizontal slider + -- This is primarily for manipulating numbers within a range + -- @name panel:MakeSlider + -- @param ... tuple of key-value pairs
+ -- name: What the slider displays above it
+ -- description: What the tooltip displays when hovering over
+ -- minText: What the slider shows on the left side
+ -- maxText: What the slider shows on the right side
+ -- minValue: The minimum value of the slider
+ -- maxValue: The maximum value of the slider
+ -- [optional] step: The amount that the slider steps between movements
+ -- default: The default value
+ -- current: The current value - can provide either this or getFunc
+ -- getFunc: Function to get the current value
+ -- setFunc: What is called when the value changes
+ -- [optional] currentTextFunc: What is called to get text value at the bottom
+ -- [optional] okayFunc: Called when the okay button is pressed
+ -- [optional] cancelFunc: Called when the cancel button is pressed
+ -- [optional] defaultFunc: Called when the default button is pressed + -- @usage panel:MakeSlider( + -- 'name', 'Range', + -- 'description', 'Specify your tooltip description', + -- 'minText', '0%', + -- 'maxText', '100%', + -- 'minValue', 0, + -- 'maxValue', 1, + -- 'step', 0.05, + -- 'default', 0.5, + -- 'current', db.currentRange, + -- 'setFunc', function(value) db.currentRange = value end, + -- 'currentTextFunc', function(value) return ("%.0f%%"):format(value * 100) end + -- ) + -- @return the Slider + function panelMeta:MakeSlider(...) + local args = getArgs(...) + if type(args.name) ~= "string" then + error(("name must be %q, got %q (%s)"):format("string", type(args.name), tostring(args.name)), 2) + elseif type(args.description) ~= "string" then + error(("description must be %q, got %q (%s)"):format("string", type(args.description), tostring(args.description)), 2) + elseif type(args.minText) ~= "string" then + error(("minText must be %q, got %q (%s)"):format("string", type(args.minText), tostring(args.minText)), 2) + elseif type(args.maxText) ~= "string" then + error(("maxText must be %q, got %q (%s)"):format("string", type(args.maxText), tostring(args.maxText)), 2) + elseif type(args.minValue) ~= "number" then + error(("minValue must be %q, got %q (%s)"):format("number", type(args.minValue), tostring(args.minValue)), 2) + elseif type(args.maxValue) ~= "number" then + error(("maxValue must be %q, got %q (%s)"):format("number", type(args.maxValue), tostring(args.maxValue)), 2) + elseif args.step and type(args.step) ~= "number" then + error(("step must be %q or %q, got %q (%s)"):format("nil", "number", type(args.step), tostring(args.step)), 2) + elseif type(args.default) ~= "number" then + error(("default must be %q, got %q (%s)"):format("number", type(args.default), tostring(args.default)), 2) + elseif args.default < args.minValue or args.default > args.maxValue then + error(("default must be [%s, %s], got %s"):format(args.minValue, args.maxValue, tostring(args.default)), 2) + elseif not args.current == not args.getFunc then + error(("either current or getFunc must be supplied, but not both"), 2) + elseif args.current and type(args.current) ~= "number" then + error(("current must be %q, got %q (%s)"):format("number", type(args.current), tostring(args.current)), 2) + elseif args.getFunc and type(args.getFunc) ~= "function" then + error(("getFunc must be %q, got %q (%s)"):format("function", type(args.getFunc), tostring(args.getFunc)), 2) + elseif type(args.setFunc) ~= "function" then + error(("setFunc must be %q, got %q (%s)"):format("function", type(args.setFunc), tostring(args.setFunc)), 2) + elseif args.currentTextFunc and type(args.currentTextFunc) ~= "function" then + error(("currentTextFunc must be %q or %q, got %q (%s)"):format("nil", "function", type(args.currentTextFunc), tostring(args.currentTextFunc)), 2) + elseif args.okayFunc and type(args.okayFunc) ~= "function" then + error(("okayFunc must be %q or %q, got %q (%s)"):format("nil", "function", type(args.okayFunc), tostring(args.okayFunc)), 2) + elseif args.cancelFunc and type(args.cancelFunc) ~= "function" then + error(("cancelFunc must be %q or %q, got %q (%s)"):format("nil", "function", type(args.cancelFunc), tostring(args.cancelFunc)), 2) + elseif args.defaultFunc and type(args.defaultFunc) ~= "function" then + error(("defaultFunc must be %q or %q, got %q (%s)"):format("nil", "function", type(args.defaultFunc), tostring(args.defaultFunc)), 2) + end + + local name + local i = 0 + repeat + i = i + 1 + name = self:GetName() .. "_Slider" .. i + until not _G[name] + local slider = CreateFrame("Slider", name, self, "InterfaceOptionsSliderTemplate") + self.controls[slider] = true + _G[slider:GetName() .. "Text"]:SetText(args.name) + slider.tooltipText = args.description + _G[slider:GetName() .. "Text"]:SetTextColor(NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b) + _G[slider:GetName() .. "Low"]:SetText(args.minText) + _G[slider:GetName() .. "Low"]:SetTextColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b) + _G[slider:GetName() .. "High"]:SetText(args.maxText) + _G[slider:GetName() .. "High"]:SetTextColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b) + + local current + if args.getFunc then + slider.getFunc = args.getFunc + current = args.getFunc() + else + current = args.current + end + + if args.currentTextFunc then + slider.currentTextFunc = args.currentTextFunc + local currentText = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall") + slider.currentText = currentText + currentText:SetPoint("TOP", slider, "CENTER", 0, -8) + currentText:SetText(args.currentTextFunc(current)) + end + + slider.default = args.default + slider:SetMinMaxValues(args.minValue, args.maxValue) + if args.step then + slider:SetValueStep(args.step) + end + slider.oldValue = current + slider.value = current + slider:SetValue(current) + slider.changeFunc = args.setFunc + slider.SetValue = slider_SetValue + slider:SetScript("OnValueChanged", slider_OnValueChanged) + slider.okayFunc = args.okayFunc + slider.cancelFunc = args.cancelFunc + slider.defaultFunc = args.defaultFunc + args = doneArgs(args) + return slider + end +end + +local function generic_OnEnter(self) + GameTooltip:SetOwner(self, "ANCHOR_TOPRIGHT") + GameTooltip:SetText(self.tooltipText, nil, nil, nil, nil, 1) +end +local function generic_OnLeave(self) + GameTooltip:Hide() +end + +do + local function dropDown_SetValue(self, value) + self.value = value + UIDropDownMenu_SetSelectedValue(self, value) + self.changeFunc(value) + end + local helper__num, helper__values + local function helper() + local value, text = helper__values[helper__num], helper__values[helper__num+1] + if value == nil then + helper__num, helper__values = nil, nil + return nil + end + helper__num = helper__num + 2 + return value, text + end + local function get_iter(values) + if type(values) == "function" then + return values + end + helper__num = 1 + helper__values = values + return helper + end + local SetValue_wrapper + if WotLK then + function SetValue_wrapper(self, ...) + return dropDown_SetValue(...) + end + else + SetValue_wrapper = dropDown_SetValue + end + local function dropDown_menu(self) + for value, text in get_iter(self.values) do + local info = UIDropDownMenu_CreateInfo() + info.text = text + info.value = value + info.checked = self.value == value + info.func = SetValue_wrapper + info.arg1 = self + info.arg2 = value + UIDropDownMenu_AddButton(info) + end + end + + local tmp = {} + --- Return a single-choice dropdown menu + -- This is for choosing a single choice among many + -- @name panel:MakeDropDown + -- @param ... tuple of key-value pairs
+ -- name: What shows above the dropdown
+ -- description: What shows when hovering over the dropdown
+ -- values: A list of options, in order, where the odd keys are the key and even are its corresponding value
+ -- default: The default key
+ -- current: The current key - you can either provide this or getFunc
+ -- getFunc: Function to return the current key
+ -- setFunc: What is called when the key changes
+ -- [optional] okayFunc: Called when the okay button is pressed
+ -- [optional] cancelFunc: Called when the cancel button is pressed
+ -- [optional] defaultFunc: Called when the default button is pressed + -- @usage panel:MakeDropDown( + -- 'name', 'Choose', + -- 'description', 'Specify your tooltip description', + -- 'values', { + -- 'ONE', "One", + -- 'TWO', "Two", + -- 'THREE', "Three", + -- }, + -- 'default', 'ONE', + -- 'current', db.choice, + -- 'setFunc', function(value) db.choice = value end, + -- ) + -- @return the DropDown frame + function panelMeta:MakeDropDown(...) + local args = getArgs(...) + if type(args.name) ~= "string" then + error(("name must be %q, got %q (%s)"):format("string", type(args.name), tostring(args.name)), 2) + elseif type(args.description) ~= "string" then + error(("description must be %q, got %q (%s)"):format("string", type(args.description), tostring(args.description)), 2) + elseif type(args.values) ~= "function" then + if type(args.values) ~= "table" then + error(("values must be %q, got %q (%s)"):format("table", type(args.values), tostring(args.values)), 2) + elseif #args.values%2 ~= 0 then + error(("values must have an even number of items, got %d"):format(#args.values), 2) + end + for i = 1, #args.values, 2 do + local k, v = args.values[i], args.values[2] + if type(k) ~= "string" and type(k) ~= "number" then + error(("values' keys must be %q or %q, got %q (%s)"):format("string", "number", type(k), tostring(k))) + elseif type(v) ~= "string" then + error(("values' values must be %q, got %q (%s)"):format("string", type(v), tostring(v))) + end + tmp[k] = v + end + end + if type(args.default) ~= "number" and type(args.default) ~= "string" then + error(("default must be %q or %q, got %q (%s)"):format("number", "string", type(args.default), tostring(args.default)), 2) + elseif type(args.values) ~= "function" and not tmp[args.default] then + error(("default must be in values, %s is not"):format(tostring(args.default)), 2) + elseif not args.current == not args.getFunc then + error(("either current or getFunc must be supplied, but not both"), 2) + elseif args.current and type(args.current) ~= "string" and type(args.current) ~= "number" then + error(("current must be %q or %q, got %q (%s)"):format("string", "number", type(args.current), tostring(args.current)), 2) + elseif type(args.values) ~= "function" and args.current and not tmp[args.current] then + error(("current must be in values, %s is not"):format(tostring(args.current)), 2) + elseif args.getFunc and type(args.getFunc) ~= "function" then + error(("getFunc must be %q, got %q (%s)"):format("function", type(args.getFunc), tostring(args.getFunc)), 2) + elseif type(args.setFunc) ~= "function" then + error(("setFunc must be %q, got %q (%s)"):format("function", type(args.setFunc), tostring(args.setFunc)), 2) + elseif args.okayFunc and type(args.okayFunc) ~= "function" then + error(("okayFunc must be %q or %q, got %q (%s)"):format("nil", "function", type(args.okayFunc), tostring(args.okayFunc)), 2) + elseif args.cancelFunc and type(args.cancelFunc) ~= "function" then + error(("cancelFunc must be %q or %q, got %q (%s)"):format("nil", "function", type(args.cancelFunc), tostring(args.cancelFunc)), 2) + elseif args.defaultFunc and type(args.defaultFunc) ~= "function" then + error(("defaultFunc must be %q or %q, got %q (%s)"):format("nil", "function", type(args.defaultFunc), tostring(args.defaultFunc)), 2) + end + for k in pairs(tmp) do + tmp[k] = nil + end + local name + local i = 0 + repeat + i = i + 1 + name = self:GetName() .. "_DropDown" .. i + until not _G[name] + + local dropDown = CreateFrame("Frame", name, self, "UIDropDownMenuTemplate") + self.controls[dropDown] = true + if args.name ~= "" then + local label = dropDown:CreateFontString(nil, "BACKGROUND", "GameFontNormal") + label:SetText(args.name) + label:SetPoint("BOTTOMLEFT", dropDown, "TOPLEFT", 16, 3) + end + dropDown.tooltipText = args.description + dropDown.values = args.values + UIDropDownMenu_Initialize(dropDown, function() + dropDown_menu(dropDown) + end) + if WotLK then + UIDropDownMenu_SetWidth(dropDown, 90) + else + UIDropDownMenu_SetWidth(90, dropDown) + end + local current + if args.getFunc then + dropDown.getFunc = args.getFunc + current = args.getFunc() + else + current = args.current + end + UIDropDownMenu_SetSelectedValue(dropDown, current) + dropDown.default = args.default + dropDown.value = args.current + dropDown.oldValue = args.current + dropDown.changeFunc = args.setFunc + dropDown.SetValue = dropDown_SetValue + dropDown:EnableMouse(true) + dropDown:SetScript("OnEnter", generic_OnEnter) + dropDown:SetScript("OnLeave", generic_OnLeave) + dropDown.okayFunc = args.okayFunc + dropDown.cancelFunc = args.cancelFunc + dropDown.defaultFunc = args.defaultFunc + args = doneArgs(args) + return dropDown + end +end + +do + local function donothing() end + local function button_OnClick(self) + self.clickFunc() + end + --- Return a button + -- @name panel:MakeButton + -- @param ... tuple of key-value pairs
+ -- name: What shows above the dropdown
+ -- description: What shows when hovering over the dropdown
+ -- func: What is called when the button is pressed + -- @usage panel:MakeButton( + -- 'name', 'Click', + -- 'description', 'Specify your tooltip description', + -- 'func', function() DEFAULT_CHAT_FRAME:AddMessage("Clicked!") end + -- ) + -- @return the Button + function panelMeta:MakeButton(...) + local args = getArgs(...) + if type(args.name) ~= "string" then + error(("name must be %q, got %q (%s)"):format("string", type(args.name), tostring(args.name)), 2) + elseif type(args.description) ~= "string" then + error(("description must be %q, got %q (%s)"):format("string", type(args.description), tostring(args.description)), 2) + elseif type(args.func) ~= "function" then + error(("description must be %q, got %q (%s)"):format("function", type(args.func), tostring(args.func)), 2) + end + local name + local i = 0 + repeat + i = i + 1 + name = self:GetName() .. "_Button" .. i + until not _G[name] + + local button = CreateFrame("Button", name, self, "UIPanelButtonTemplate2") + self.controls[button] = true + button:SetText(args.name) + button.tooltipText = args.description + button:SetWidth(120) + button:SetHeight(22) + button.SetValue = donothing + button.clickFunc = args.func + button:SetScript("OnClick", button_OnClick) + button:SetScript("OnEnter", generic_OnEnter) + button:SetScript("OnLeave", generic_OnLeave) + args = doneArgs(args) + return button + end +end + +do + local function toggle_SetValue(self, value) + value = not not value + self.changeFunc(value) + self.value = value + self:SetChecked(value) + end + local function toggle_OnClick(self) + self:SetValue(not not self:GetChecked()) + end + --- Return a checkbox + -- @name panel:MakeToggle + -- @param ... tuple of key-value pairs
+ -- name: What appears to the right of the checkbox
+ -- description: What the tooltip shows when hovering over
+ -- default: The default value
+ -- current: The current value - you can provide this or getFunc
+ -- getFunc: Function to return the current value
+ -- setFunc: What is called when the value changes
+ -- [optional] okayFunc: Called when the okay button is pressed
+ -- [optional] cancelFunc: Called when the cancel button is pressed
+ -- [optional] defaultFunc: Called when the default button is pressed + -- @usage panel:MakeToggle( + -- 'name', 'Toggle', + -- 'description', 'Specify your tooltip description', + -- 'default', false, + -- 'getFunc', function() return db.myToggle end + -- 'setFunc', function(value) db.myToggle = value end + -- ) + -- @return the CheckButton + function panelMeta:MakeToggle(...) + local args = getArgs(...) + if type(args.name) ~= "string" then + error(("name must be %q, got %q (%s)"):format("string", type(args.name), tostring(args.name)), 2) + elseif type(args.description) ~= "string" then + error(("description must be %q, got %q (%s)"):format("string", type(args.description), tostring(args.description)), 2) + elseif type(args.default) ~= "boolean" then + error(("default must be %q, got %q (%s)"):format("boolean", type(args.default), tostring(args.default)), 2) + elseif (args.current == nil) == not args.getFunc then + error(("either current or getFunc must be supplied, but not both"), 2) + elseif args.current and type(args.current) ~= "boolean" then + error(("current must be %q, got %q (%s)"):format("boolean", type(args.current), tostring(args.current)), 2) + elseif args.getFunc and type(args.getFunc) ~= "function" then + error(("getFunc must be %q, got %q (%s)"):format("function", type(args.getFunc), tostring(args.getFunc)), 2) + elseif type(args.setFunc) ~= "function" then + error(("setFunc must be %q, got %q (%s)"):format("function", type(args.setFunc), tostring(args.setFunc)), 2) + elseif args.okayFunc and type(args.okayFunc) ~= "function" then + error(("okayFunc must be %q or %q, got %q (%s)"):format("nil", "function", type(args.okayFunc), tostring(args.okayFunc)), 2) + elseif args.cancelFunc and type(args.cancelFunc) ~= "function" then + error(("cancelFunc must be %q or %q, got %q (%s)"):format("nil", "function", type(args.cancelFunc), tostring(args.cancelFunc)), 2) + elseif args.defaultFunc and type(args.defaultFunc) ~= "function" then + error(("defaultFunc must be %q or %q, got %q (%s)"):format("nil", "function", type(args.defaultFunc), tostring(args.defaultFunc)), 2) + end + local name + local i = 0 + repeat + i = i + 1 + name = self:GetName() .. "_Toggle" .. i + until not _G[name] + + local toggle = CreateFrame("CheckButton", name, self, "InterfaceOptionsCheckButtonTemplate") + self.controls[toggle] = true + _G[toggle:GetName() .. "Text"]:SetText(args.name) + toggle:SetHitRectInsets(0, -_G[toggle:GetName() .. "Text"]:GetWidth() - 1, 0, 0) + toggle.tooltipText = args.description + toggle.default = args.default + local current + if args.getFunc then + toggle.getFunc = args.getFunc + current = args.getFunc() + else + current = args.current + end + toggle.value = current + toggle.oldValue = current + toggle.changeFunc = args.setFunc + toggle.SetValue = toggle_SetValue + toggle:SetScript("OnClick", toggle_OnClick) + toggle:SetChecked(current) + toggle:SetScript("OnEnter", generic_OnEnter) + toggle:SetScript("OnLeave", generic_OnLeave) + toggle.okayFunc = args.okayFunc + toggle.cancelFunc = args.cancelFunc + toggle.defaultFunc = args.defaultFunc + args = doneArgs(args) + return toggle + end +end + +do + local function update(self, r, g, b, a) + if not self.hasAlpha then + a = 1 + end + self.info.r = r + self.info.g = g + self.info.b = b + if self.hasAlpha then + self.info.opacity = a + end + self.color:SetTexture(r, g, b, a) + if self.value == self.oldValue then + self.value = {} + end + self.value[1] = r + self.value[2] = g + self.value[3] = b + if self.hasAlpha then + self.value[4] = a + end + self.info.r = r + self.info.g = g + self.info.b = b + if self.hasAlpha then + self.info.opacity = 1 - a + end + if self.hasAlpha then + self.changeFunc(r, g, b, a) + else + self.changeFunc(r, g, b) + end + end + local function button_SetValue(self, ...) + if select('#', ...) == 1 and type((...)) == "table" then + return button_SetValue(self, unpack(value)) + end + update(self, ...) + end + local function button_OnClick(self) + OpenColorPicker(self.info) + end + local function swatchFunc(self) + local r, g, b = ColorPickerFrame:GetColorRGB() + local opacity = 1 - OpacitySliderFrame:GetValue() + + update(self, r, g, b, opacity) + end + local function cancelFunc(self) + local previousValues = ColorPickerFrame.previousValues + local r, g, b, opacity = previousValues.r, previousValues.g, previousValues.b, hasAlpha and 1 - previousValues.opacity or 1 + + update(self, r, g, b, opacity) + end + --- Return a color swatch that opens a color picker + -- @name panel:MakeColorPicker + -- @param ... tuple of key-value pairs
+ -- name: What shows up next to the swatch
+ -- description: What shows up in the tooltip on hover
+ -- hasAlpha: Whether the color picker should have an alpha setting
+ -- defaultR: Default red value [0, 1]
+ -- defaultG: Default green value [0, 1]
+ -- defaultB: Default blue value [0, 1]
+ -- defaultA: Default alpha value [0, 1], only needed if hasAlpha is true
+ -- currentR: The current red value - you can provide this or getFunc
+ -- currentG: The current green value - you can provide this or getFunc
+ -- currentB: The current blue value - you can provide this or getFunc
+ -- currentA: The current alpha value - you can provide this or getFunc
+ -- getFunc: Function to return the current color as a tuple
+ -- setFunc: What is called when the color changes
+ -- [optional] okayFunc: Called when the okay button is pressed
+ -- [optional] cancelFunc: Called when the cancel button is pressed
+ -- [optional] defaultFunc: Called when the default button is pressed + -- @usage panel:MakeColorPicker( + -- 'name', 'Pick a color', + -- 'description', 'Specify your tooltip description', + -- 'hasAlpha', false, + -- 'defaultR', 1, + -- 'defaultG', 0.82, + -- 'defaultB', 0, + -- 'getFunc', function() return unpack(db.color) end + -- 'setFunc', function(r, g, b) db.color[1], db.color[2], db.color[3] = r, g, b end + -- ) + -- @usage panel:MakeColorPicker( + -- 'name', 'Pick a color', + -- 'description', 'Specify your tooltip description', + -- 'hasAlpha', true, + -- 'defaultR', 0, + -- 'defaultG', 1, + -- 'defaultB', 0, + -- 'defaultA', 0.5, + -- 'currentR', db.color2.r, + -- 'currentG', db.color2.g, + -- 'currentB', db.color2.b, + -- 'currentA', db.color2.a, + -- 'setFunc', function(r, g, b, a) db.color2.r, db.color2.g db.color2.b, db.color2.a = r, g, b, a end + -- ) + -- @return the color swatch + function panelMeta:MakeColorPicker(...) + local args = getArgs(...) + if type(args.name) ~= "string" then + error(("name must be %q, got %q (%s)"):format("string", type(args.name), tostring(args.name)), 2) + elseif type(args.description) ~= "string" then + error(("description must be %q, got %q (%s)"):format("string", type(args.description), tostring(args.description)), 2) + elseif type(args.hasAlpha) ~= "boolean" then + error(("hasAlpha must be %q, got %q (%s)"):format("boolean", type(args.hasAlpha), tostring(args.hasAlpha)), 2) + elseif type(args.defaultR) ~= "number" then + error(("defaultR must be %q, got %q (%s)"):format("number", type(args.defaultR), tostring(args.defaultR)), 2) + elseif args.defaultR < 0 or args.defaultR > 1 then + error(("defaultR must be [0, 1], got %s"):format(tostring(args.defaultR)), 2) + elseif type(args.defaultG) ~= "number" then + error(("defaultG must be %q, got %q (%s)"):format("number", type(args.defaultG), tostring(args.defaultG)), 2) + elseif args.defaultG < 0 or args.defaultG > 1 then + error(("defaultG must be [0, 1], got %s"):format(tostring(args.defaultG)), 2) + elseif type(args.defaultB) ~= "number" then + error(("defaultB must be %q, got %q (%s)"):format("number", type(args.defaultB), tostring(args.defaultB)), 2) + elseif args.defaultB < 0 or args.defaultB > 1 then + error(("defaultB must be [0, 1], got %s"):format(tostring(args.defaultB)), 2) + elseif args.hasAlpha and type(args.defaultA) ~= "number" then + error(("defaultA must be %q, got %q (%s)"):format("number", type(args.defaultA), tostring(args.defaultA)), 2) + elseif args.hasAlpha and (args.defaultA < 0 or args.defaultA > 1) then + error(("defaultA must be [0, 1], got %s"):format(tostring(args.defaultA)), 2) + elseif not args.currentR == not args.getFunc then + error(("either currentR or getFunc must be supplied, but not both"), 2) + elseif args.currentR and (not args.currentG or not args.currentB or (args.hasAlpha and not args.currentA)) then + error(("if you supply currentR, you must supply currentG and currentB (and currentA if hasAlpha)"), 2) + elseif args.currentR and type(args.currentR) ~= "number" then + error(("current must be %q, got %q (%s)"):format("number", type(args.currentR), tostring(args.currentR)), 2) + elseif args.currentG and type(args.currentG) ~= "number" then + error(("current must be %q, got %q (%s)"):format("number", type(args.currentG), tostring(args.currentG)), 2) + elseif args.currentB and type(args.currentB) ~= "number" then + error(("current must be %q, got %q (%s)"):format("number", type(args.currentB), tostring(args.currentB)), 2) + elseif args.currentA and type(args.currentA) ~= "number" then + error(("current must be %q, got %q (%s)"):format("number", type(args.currentA), tostring(args.currentA)), 2) + elseif args.getFunc and type(args.getFunc) ~= "function" then + error(("getFunc must be %q, got %q (%s)"):format("function", type(args.getFunc), tostring(args.getFunc)), 2) + elseif type(args.setFunc) ~= "function" then + error(("setFunc must be %q, got %q (%s)"):format("function", type(args.setFunc), tostring(args.setFunc)), 2) + elseif args.okayFunc and type(args.okayFunc) ~= "function" then + error(("okayFunc must be %q or %q, got %q (%s)"):format("nil", "function", type(args.okayFunc), tostring(args.okayFunc)), 2) + elseif args.cancelFunc and type(args.cancelFunc) ~= "function" then + error(("cancelFunc must be %q or %q, got %q (%s)"):format("nil", "function", type(args.cancelFunc), tostring(args.cancelFunc)), 2) + elseif args.defaultFunc and type(args.defaultFunc) ~= "function" then + error(("defaultFunc must be %q or %q, got %q (%s)"):format("nil", "function", type(args.defaultFunc), tostring(args.defaultFunc)), 2) + end + + local name + local i = 0 + repeat + i = i + 1 + name = self:GetName() .. "_ColorPicker" .. i + until not _G[name] + + if not args.hasAlpha then + args.defaultA = 1 + end + + local button = CreateFrame("Button", name, self) + self.controls[button] = true + + + local currentR, currentG, currentB, currentA + if args.getFunc then + button.getFunc = args.getFunc + currentR, currentG, currentB, currentA = button.getFunc() + if not args.hasAlpha then + currentA = 1 + end + else + currentR = args.currentR + currentG = args.currentG + currentB = args.currentB + if not args.hasAlpha then + currentA = 1 + else + currentR = args.currentA + end + end + + button.tooltipText = args.description + local text = button:CreateFontString(nil, "ARTWORK", "GameFontHighlight") + text:SetText(args.name) + text:SetPoint("LEFT", button, "RIGHT", 0, 1) + button:SetHitRectInsets(0, -text:GetWidth() - 1, 0, 0) + local color = button:CreateTexture(nil, "ARTWORK") + button.color = color + color:SetTexture(currentR, currentG, currentB, currentA) + local background = button:CreateTexture(nil, "BORDER") + background:SetTexture([=[Tileset\Generic\Checkers]=]) + background:SetTexCoord(0, 0.5, 0, 0.5) + local border = button:CreateTexture(nil, "BACKGROUND") + border:SetTexture([=[Interface\ChatFrame\ChatFrameColorSwatch]=]) + button:SetWidth(26) + button:SetHeight(26) + background:SetPoint("CENTER") + background:SetWidth(14) + background:SetHeight(14) + color:SetPoint("CENTER") + color:SetWidth(14) + color:SetHeight(14) + border:SetAllPoints(button) + button.default = { args.defaultR, args.defaultG, args.defaultB } + button.oldValue = { currentR, currentG, currentB } + if hasAlpha then + button.default[4] = args.defaultA + button.oldValue[4] = currentA + end + button.value = button.oldValue + button.hasAlpha = args.hasAlpha + button.changeFunc = args.setFunc + button.SetValue = button_SetValue + local function swatchFunc_wrapper() + swatchFunc(button) + end + local function cancelFunc_wrapper() + cancelFunc(button) + end + button.info = { + swatchFunc = swatchFunc_wrapper, + hasOpacity = args.hasAlpha, + opacityFunc = args.hasAlpha and swatchFunc_wrapper or nil, + r = currentR, + g = currentB, + b = currentG, + opacity = args.hasAlpha and 1 - currentA or nil, + cancelFunc = cancelFunc_wrapper, + } + button:SetScript("OnClick", button_OnClick) + button:SetScript("OnEnter", generic_OnEnter) + button:SetScript("OnLeave", generic_OnLeave) + button:RegisterForClicks("LeftButtonUp") + button.okayFunc = args.okayFunc + button.cancelFunc = args.cancelFunc + button.defaultFunc = args.defaultFunc + args = doneArgs(args) + return button + end +end + +--- Add a slash command to open a specific options panel +-- @param name name of the panel to open +-- @param ... tuple of slash commands +-- @usage LibStub("LibSimpleOptions-1.0").AddSlashCommand("My Options", "/MyOpt", "/MO") +function LibSimpleOptions.AddSlashCommand(name, ...) + local num = 0 + local name_upper = name:upper() + for i = 1, select('#', ...) do + local cmd = select(i, ...) + num = num + 1 + _G["SLASH_" .. name_upper .. num] = cmd + local cmd_lower = cmd:lower() + if cmd_lower ~= cmd then + num = num + 1 + _G["SLASH_" .. name_upper .. num] = cmd_lower + end + end + + _G.hash_SlashCmdList[name_upper] = nil + _G.SlashCmdList[name_upper] = function() + InterfaceOptionsFrame_OpenToFrame(name) + end +end + +for funcName, func in pairs(panelMeta) do + LibSimpleOptions[funcName] = func + for panel in pairs(panels) do + panel[funcName] = func + end +end \ No newline at end of file diff --git a/pMinimap/Libs/LibStub.lua b/pMinimap/Libs/LibStub.lua new file mode 100644 index 0000000..f5fc919 --- /dev/null +++ b/pMinimap/Libs/LibStub.lua @@ -0,0 +1,51 @@ +-- $Id: LibStub.lua 76 2007-09-03 01:50:17Z mikk $ +-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info +-- LibStub is hereby placed in the Public Domain +-- Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke +local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS! +local LibStub = _G[LIBSTUB_MAJOR] + +-- Check to see is this version of the stub is obsolete +if not LibStub or LibStub.minor < LIBSTUB_MINOR then + LibStub = LibStub or {libs = {}, minors = {} } + _G[LIBSTUB_MAJOR] = LibStub + LibStub.minor = LIBSTUB_MINOR + + -- LibStub:NewLibrary(major, minor) + -- major (string) - the major version of the library + -- minor (string or number ) - the minor version of the library + -- + -- returns nil if a newer or same version of the lib is already present + -- returns empty library object or old library object if upgrade is needed + function LibStub:NewLibrary(major, minor) + assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)") + minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.") + + local oldminor = self.minors[major] + if oldminor and oldminor >= minor then return nil end + self.minors[major], self.libs[major] = minor, self.libs[major] or {} + return self.libs[major], oldminor + end + + -- LibStub:GetLibrary(major, [silent]) + -- major (string) - the major version of the library + -- silent (boolean) - if true, library is optional, silently return nil if its not found + -- + -- throws an error if the library can not be found (except silent is set) + -- returns the library object if found + function LibStub:GetLibrary(major, silent) + if not self.libs[major] and not silent then + error(("Cannot find a library instance of %q."):format(tostring(major)), 2) + end + return self.libs[major], self.minors[major] + end + + -- LibStub:IterateLibraries() + -- + -- Returns an iterator for the currently registered libraries + function LibStub:IterateLibraries() + return pairs(self.libs) + end + + setmetatable(LibStub, { __call = LibStub.GetLibrary }) +end diff --git a/pMinimap/pMinimap.lua b/pMinimap/pMinimap.lua index 9c2822d..f3cbab5 100644 --- a/pMinimap/pMinimap.lua +++ b/pMinimap/pMinimap.lua @@ -1,8 +1,8 @@ pMinimap = CreateFrame('Frame', 'pMinimap', UIParent) -pMinimap:SetScript('OnEvent', function(self, event, ...) self[event](self, event, ...) end) +pMinimap:SetScript('OnEvent', function(self, event, ...) self[event](self, ...) end) pMinimap:RegisterEvent('ADDON_LOADED') -function pMinimap:ADDON_LOADED() +function pMinimap.ADDON_LOADED(self) local db = pMinimapDB or {point = {'TOPRIGHT', UIParent, 'TOPRIGHT', -15, -15}, scale = 0.9, offset = 1, colors = {0, 0, 0}, durability = true} MinimapBorder:SetTexture() @@ -23,8 +23,9 @@ function pMinimap:ADDON_LOADED() MinimapZoneText:Hide() MinimapZoneTextButton:Hide() - MiniMapTrackingBorder:SetTexture() + MiniMapTrackingButtonBorder:SetTexture() MiniMapTrackingBackground:Hide() + MiniMapTrackingIconOverlay:SetAlpha(0) MiniMapTrackingIcon:SetTexCoord(0.065, 0.935, 0.065, 0.935) MiniMapTracking:SetParent(Minimap) MiniMapTracking:ClearAllPoints() @@ -83,7 +84,7 @@ function pMinimap:ADDON_LOADED() self:UnregisterEvent('ADDON_LOADED') end -function pMinimap:UPDATE_INVENTORY_ALERTS() +function pMinimap.UPDATE_INVENTORY_ALERTS() local db = pMinimapDB or {colors = {0, 0, 0, 1}} local maxStatus = 0 for id in pairs(INVENTORY_ALERT_STATUS_SLOTS) do diff --git a/pMinimap/pMinimap.toc b/pMinimap/pMinimap.toc index 0e674b1..a679854 100644 --- a/pMinimap/pMinimap.toc +++ b/pMinimap/pMinimap.toc @@ -1,13 +1,13 @@ -## Interface: 20400 +## Interface: 30000 ## Author: p3lim -## Version: 20400.wowi:revision +## Version: 30000.wowi:revision ## Title: |cffff6000p|rMinimap ## Notes: Yet another square minimap addon ## OptionalDeps: LibStub, LibSimpleOptions-1.0 ## SavedVariablesPerCharacter: pMinimapDB -LibSimpleOptions-1.0\LibStub\LibStub.lua -LibSimpleOptions-1.0\LibSimpleOptions-1.0.lua +Libs\LibStub.lua +Libs\LibSimpleOptions-1.0.lua pMinimap.lua -pMinimapConfig.lua \ No newline at end of file +pMinimapConfig.lua diff --git a/pMinimap/pMinimapConfig.lua b/pMinimap/pMinimapConfig.lua index 7d5a4fb..273491c 100644 --- a/pMinimap/pMinimapConfig.lua +++ b/pMinimap/pMinimapConfig.lua @@ -91,7 +91,7 @@ local function CreateOptions(self, db) ):SetPoint('TOPLEFT', sub, 'BOTTOMLEFT', 0, -156) end -function pMinimap:PLAYER_ENTERING_WORLD(event) +function pMinimap.PLAYER_ENTERING_WORLD(self, event) local db = pMinimapDB or {point = {'TOPRIGHT', 'UIParent', 'TOPRIGHT', -15, -15}, scale = 0.9, offset = 1, colors = {0, 0, 0, 1}, durability = true} LibStub('LibSimpleOptions-1.0').AddOptionsPanel('pMinimap', function(self) CreateOptions(self, db) end) -- 1.7.9.5