--[[-- @name Portfolio @description Interface Option Creation Utility @release 1.23 @author Karl Isenberg (AnduinLothar) @revision $Id: Portfolio.lua 3705 2006-06-26 08:15:29Z karlkfi $ @usage local Portfolio = LibStub("Portfolio")<br/> <div class="p"> <b>Dependant Usage:</b><ol> <li>Add Portfolio as a Required Dependency.</li> <li>Include Portfolio in your download<br/> OR link users to <a href="http://www.wowinterface.com/downloads/info11749-Portfolio.html">WoW Interface</a> for downloading.</li></ol> <b>Embedded Usage:</b><ol> <li>Include Portfolio in the Libs folder of you addon: <addon>\Libs\Portfolio.</li> <li>Include Loader.xml in your xml file with <Include file="Libs\Portfolio\Loader.xml"/><br/> OR load Libs\Portfolio\Loader.xml from your toc file.</li> <li>Add Portfolio as an Optional Dependency in your toc, and as an X-Embeds.</li></ol> </div> --]]-- local version = 1.23 local Portfolio, oldminor = LibStub:NewLibrary("Portfolio", version) if not Portfolio then return end Portfolio.version = version Portfolio.registered = Portfolio.registered or {} -- Loading Flags (nil so that other files will load) Portfolio.RegisterControl = nil Portfolio.Control = nil ------------------------------------------------------------------------------ --[[ Portfolio External - Option Set Registration ]]-- ------------------------------------------------------------------------------ --[[-- Register a new set of options. Creates and registers the option set frame and registers all the options with <a href="RegisterControl.html">RegisterControl</a>. @param optionSetTable (table) option set registration table @return options frame --]]-- function Portfolio.RegisterOptionSet(optionSetTable) --Check for duplicate set name (id) if (Portfolio.registered[optionSetTable.id]) then Portfolio.PrintError("RegisterOptionSet: Option set already exists - "..optionSetTable.id) return end --Create Control Panel Frame local optionsFrame, frameName = Portfolio.CreateOptionsFrame(optionSetTable) --Shortcut: Set all unassigned options' novar if (optionSetTable.novarDefault) then for i, option in next, optionSetTable.options do if (option.tvar == nil and option.cvar == nil and option.uvar == nil and option.novar == nil) then option.novar = optionSetTable.novarDefault end end end -- Add Header & Options Portfolio.PopulateOptionsFrame(optionsFrame, optionSetTable, frameName) --OnLoad --optionsFrame.options = optionSetTable --optionSetTable.frame = optionsFrame --frame:RegisterEvent("PLAYER_ENTERING_WORLD"); --frame:SetScript("OnEvent", BlizzardOptionsPanel_OnEvent); --BlizzardOptionsPanel_OnLoad(optionsFrame, okay, cancel, default, refresh) --UIDropDownMenu_SetSelectedValue(InterfaceOptionsControlsPanelAutoLootKeyDropDown, GetModifiedClick("AUTOLOOTTOGGLE")); --UIDropDownMenu_EnableDropDown(InterfaceOptionsControlsPanelAutoLootKeyDropDown); optionsFrame:Hide() -- Store the newly registered frame Portfolio.registered[optionSetTable.id] = optionsFrame InterfaceOptions_AddCategory(optionsFrame) -- If the addon name is valid, add an about page if optionsFrame.addon then if optionSetTable.about ~= false then LibStub("InterfaceOptionAboutPanel").new(optionsFrame.name, optionsFrame.addon) end LibStub("LibDefaults"):SetScript(optionsFrame.addon, function() optionsFrame:CallCallbacks() end) end return optionsFrame end ------------------------------------------------------------------------------ --[[ Options Frame Functions ]]-- ------------------------------------------------------------------------------ --[[-- Get the options frame by set id. @usage control = optionsFrame:GetControl(optionid) @param setid (string) option set id @return options frame --]]-- function Portfolio.GetOptionsFrame(setid) return Portfolio.registered[setid] end --[[-- Get the control frame by option id. @usage control = optionsFrame:GetControl(optionid) @param optionsFrame options frame @param optionid (string) option id @return control frame --]]-- function Portfolio.GetControl(optionsFrame, optionid) for _, control in next, optionsFrame.controls do if (control.id == optionid) then return control end end end --[[-- Call Update() on all the controls. @usage optionsFrame:CallCallbacks() @param optionsFrame options frame --]]-- function Portfolio.CallCallbacks(optionsFrame) --Portfolio.Print("CallCallbacks: "..optionsFrame.addon) for _, control in next, optionsFrame.controls do if (control.Update) then control:Update() end end end ------------------------------------------------------------------------------ --[[ Portfolio Internal - Registration Support Functions ]]-- ------------------------------------------------------------------------------ function Portfolio.CreateOptionsFrame(optionTable) local frameName = optionTable.id.."ControlPanel" local parent = InterfaceOptionsFramePanelContainer local optionsFrame = CreateFrame("Frame", frameName, parent) optionsFrame:SetPoint("TOPLEFT", parent, "TOPLEFT"); optionsFrame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMRIGHT"); local scrollFrame = CreateFrame("ScrollFrame", frameName.."ScrollFrame", optionsFrame, "UIPanelScrollFrameTemplate") scrollFrame.scrollBarHideable = true scrollFrame:SetVerticalScroll(0) optionsFrame.UpdateBox = Portfolio.OptionSet_UpdateBox Portfolio.InsetScrollBar(scrollFrame) --ScrollFrame Inset scrollFrame:SetPoint("TOPLEFT", optionsFrame, "TOPLEFT", 5, -5); scrollFrame:SetPoint("BOTTOMRIGHT", optionsFrame, "BOTTOMRIGHT", -5, 5); optionsFrame.scrollChild = CreateFrame("Frame", frameName.."ScrollChildFrame", scrollFrame) scrollFrame:SetScrollChild(optionsFrame.scrollChild) optionsFrame.scrollChild:SetWidth(scrollFrame:GetWidth()) optionsFrame.scrollChild:SetHeight(scrollFrame:GetHeight()) --optionsFrame.scrollChild:SetBackdrop(GameTooltip:GetBackdrop()) optionsFrame.scrollChild.xOffsetRelative = 12 optionsFrame.scrollChild.yOffsetRelative = 8 optionsFrame.savedVarTable = optionTable.savedVarTable optionsFrame.id = optionTable.id -- Validate the addon name local addon = optionTable.addon or optionTable.id if (GetAddOnInfo(addon)) then optionsFrame.addon = addon end -- Defaults to true optionsFrame.initCallbacks = optionTable.initCallbacks == nil and true or optionTable.initCallbacks return optionsFrame, frameName end function Portfolio.PopulateOptionsFrame(optionsFrame, optionTable, frameName) optionsFrame.GetControl = Portfolio.GetControl optionsFrame.CallCallbacks = Portfolio.CallCallbacks optionsFrame.RegisterControl = Portfolio.RegisterControl optionsFrame.okay = Portfolio.OptionSet_Okay; optionsFrame.cancel = Portfolio.OptionSet_Cancel; optionsFrame.default = Portfolio.OptionSet_Reset; optionsFrame.refresh = Portfolio.OptionSet_Refresh; optionsFrame.name = optionTable.text or optionsFrame.addon and GetAddOnMetadata(optionsFrame.addon, "Title") or optionTable.id --Title w/ SubText local header = {} header.type = CONTROLTYPE_HEADER header.id = frameName.."Title" header.text = optionsFrame.name header.subText = optionTable.subText or optionsFrame.addon and GetAddOnMetadata(optionsFrame.addon, "Notes") optionsFrame:RegisterControl(header) --Options for i, option in next, optionTable.options do optionsFrame:RegisterControl(option) end --Update the scrollbar Portfolio.ScrollFrame_OnScrollRangeChanged(optionsFrame.scrollChild:GetParent()) end ------------------------------------------------------------------------------ --[[ Portfolio Internal - Option Set Frame Event Functions ]]-- ------------------------------------------------------------------------------ function Portfolio.OptionSet_Refresh(self) _G[self:GetName().."ScrollFrame"]:SetVerticalScroll(0) Portfolio.PassThrough(self,"Refresh") --Portfolio.ScrollFrame_OnScrollRangeChanged(self.scrollChild:GetParent()) end function Portfolio.OptionSet_Okay(self) Portfolio.PassThrough(self,"Okay") end function Portfolio.OptionSet_Cancel(self) Portfolio.PassThrough(self,"Cancel") end function Portfolio.OptionSet_Reset(self) Portfolio.PassThrough(self,"Reset") end function Portfolio.OptionSet_UpdateBox(self) self.scrollChild:SetWidth(self.scrollChild:GetParent():GetWidth()) self.scrollChild:SetHeight(self.scrollChild:GetParent():GetHeight()) Portfolio.PassThrough(self,"UpdateBox") end ------------------------------------------------------------------------------ --[[ Support Functions ]]-- ------------------------------------------------------------------------------ function Portfolio.Print(text) (SELECTED_CHAT_FRAME or DEFAULT_CHAT_FRAME):AddMessage(text) end function Portfolio.PrintError(text) (SELECTED_CHAT_FRAME or DEFAULT_CHAT_FRAME):AddMessage(text, RED_FONT_COLOR.r, RED_FONT_COLOR.g, RED_FONT_COLOR.b) end function Portfolio.CopyTableElements(to, from, ...) for i=1, select("#", ...) do local key = select(i, ...) to[key] = from[key] end end function Portfolio.InitField(to, from, key, default) if from[key] ~= nil then to[key] = from[key] elseif default ~= nil then to[key] = default end end function Portfolio.Round(num, idp) local mult = 10^(idp or 0) return floor(num * mult + 0.5) / mult end function Portfolio.PassThrough(self, methodName) if self.controls then for i, control in ipairs(self.controls) do if control[methodName] then control[methodName](control) end end end end function Portfolio.InsetScrollBar(scrollFrame) local frameName = scrollFrame:GetName() local scrollbar = _G[frameName.."ScrollBar"] scrollbar:EnableMouseWheel(true) scrollbar:ClearAllPoints() scrollbar:SetPoint("TOPLEFT", scrollFrame, "TOPRIGHT", 6, -22) scrollbar:SetPoint("BOTTOMLEFT", scrollFrame, "BOTTOMRIGHT", 6, 21) local scrollBackdrop = { edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", tile = true, tileSize = 16, edgeSize = 12, insets = { left = 0, right = 0, top = 5, bottom = 5 } } local border = CreateFrame("Frame", nil, scrollbar) border:SetPoint("TOPLEFT", _G[frameName.."ScrollBarScrollUpButton"], -5, 5) border:SetPoint("BOTTOMRIGHT", _G[frameName.."ScrollBarScrollDownButton"], 5, -4) border:SetBackdrop(scrollBackdrop) border:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b, 0.5) scrollFrame:SetScript("OnScrollRangeChanged", Portfolio.ScrollFrame_OnScrollRangeChanged) scrollFrame:SetScript("OnShow", Portfolio.ScrollFrame_OnScrollRangeChanged) scrollFrame:SetScript("OnMouseWheel", Portfolio.ScrollFrameTemplate_OnMouseWheel) scrollbar:SetScript("OnMouseWheel", function (self, ...) Portfolio.ScrollFrameTemplate_OnMouseWheel(self:GetParent(), ...) end) --Portfolio.ScrollFrame_OnScrollRangeChanged(scrollFrame) end function Portfolio.ScrollFrame_OnScrollRangeChanged(self, yrange, xrange, count) local scrollbarName = self:GetName().."ScrollBar" local scrollbar = _G[scrollbarName] if ( not yrange ) then yrange = self:GetVerticalScrollRange() end local value = scrollbar:GetValue() if ( value > yrange ) then value = yrange end scrollbar:SetMinMaxValues(0, yrange) scrollbar:SetValue(value) local thumb = _G[scrollbarName.."ThumbTexture"] if ( floor(yrange) == 0 ) then if (self.scrollBarHideable ) then scrollbar:Hide() self:SetPoint("BOTTOMRIGHT", self:GetParent(), "BOTTOMRIGHT", -5, 5) else _G[scrollbarName.."ScrollDownButton"]:Disable() _G[scrollbarName.."ScrollUpButton"]:Disable() self:SetPoint("BOTTOMRIGHT", self:GetParent(), "BOTTOMRIGHT", -32, 5) end thumb:Hide() else scrollbar:Show() _G[scrollbarName.."ScrollDownButton"]:Enable() thumb:Show() self:SetPoint("BOTTOMRIGHT", self:GetParent(), "BOTTOMRIGHT", -32, 5) end self:GetParent():UpdateBox() local newYRange = self:GetVerticalScrollRange() local count = count or 0 local maxResursion = 5 if ( yrange ~= newYRange and count < maxResursion ) then Portfolio.ScrollFrame_OnScrollRangeChanged(self, newYRange, nil, count+1) return end if scrollbar:GetHeight() <= 24 then if scrollbar:GetHeight() <= 12 then thumb:SetHeight(6) else thumb:SetHeight(12) end else thumb:SetHeight(24) end end function Portfolio.ScrollFrameTemplate_OnMouseWheel(self, value, scrollBar) scrollBar = scrollBar or _G[self:GetName() .. "ScrollBar"] if scrollBar:IsShown() then local min, max = scrollBar:GetMinMaxValues() if value > 0 then scrollBar:SetValue(scrollBar:GetValue() - math.max(40,scrollBar:GetHeight() / 3)) else scrollBar:SetValue(scrollBar:GetValue() + math.max(40,scrollBar:GetHeight() / 3)) end else --Passthrough local window = self:GetParent() if window.optionsFrame then local pScrollFrame = window.optionsFrame.scrollChild:GetParent() pScrollFrame:GetScript("OnMouseWheel")(pScrollFrame, value) end end end