You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

746 lines
28 KiB

--imports
local WIM = WIM;
local _G = _G;
local CreateFrame = CreateFrame;
local unpack = unpack;
local tostring = tostring;
local type = type;
local table = table;
local pairs = pairs;
local tonumber = tonumber;
--set namespace
setfenv(1, WIM);
--[[
To create an option frame, invoke WIM.options.CreateOptionsFrame() returns Frame
Available Tools:
- frame:CreateSection(title[, description]) returns Frame
- frame:SetFullSize()
- frame:CreateText(inherritFrom[, fontHeight]) returns FontString
- frame:ImportCustomObject(theObject) returns theObject
- frame:CreateFramedPanel() returns Frame
- CreateCheckButton(parent, title, dbTree, varName, tooltip, valChanged) returns CheckButton
- CreateCheckButtonMenu(parent, title, dbTree, varName, tooltip, valChanged, itemList, dbTree2, varName2, valChanged2) returns CheckButton
- CreateSlider(parent, title, minText, maxText, min, max, step, dbTree, varName, valChanged) returns Slider
- CreateColorPicker(parent, title, dbTree, varName, valChanged) returns Frame
- CreateButton(parent, title, fun) returns Button
Frame Modifying Tools:
- WIM.options.AddFramedBackdrop(theFrame)
]]
local DefaultFont = "ChatFontNormal";
local TitleColor = {_G.GameFontNormal:GetTextColor()};
local DisabledColor = {.5, .5, .5};
local ObjectStats = {};
local function statObject(str)
ObjectStats[str] = ObjectStats[str] or 0;
ObjectStats[str] = ObjectStats[str] + 1;
return str..ObjectStats[str];
end
local function SetNextAnchor(obj)
local parent = obj:GetParent();
local relativePoint = parent.lastObj;
--obj:ClearAllPoints();
if(relativePoint) then
obj:SetPoint("TOPLEFT", relativePoint, "BOTTOMLEFT", parent.nextOffSetX or 0, parent.nextOffSetY or 0);
else
obj:SetPoint("TOPLEFT", parent.nextOffSetX or 0, parent.nextOffSetY or 0);
end
parent.nextOffsetX, parent.nextOffSetY = 0, 0;
parent.lastObj = obj;
end
local function SetFullSize(self)
self:SetPoint("LEFT");
self:SetPoint("RIGHT");
end
local function CreateButton(parent, text, fun)
local button = CreateFrame("Button", parent:GetName()..statObject("Button"), parent, "UIPanelButtonTemplate");
button.text = _G[button:GetName().."Text"];
button.text:SetText(text);
button:SetWidth(button.text:GetStringWidth()+40);
button:SetScript("OnClick", fun);
SetNextAnchor(button);
return button;
end
local function CreateColorPicker(parent, title, dbTree, varName, valChanged)
local frame = CreateFrame("Frame", parent:GetName()..statObject("ColorPicker"), parent);
frame:SetWidth(22); frame:SetHeight(22);
frame.swatch = CreateFrame("Button", frame:GetName().."Swatch", frame);
frame.swatch:SetWidth(20); frame.swatch:SetHeight(20);
frame.swatch:SetPoint("LEFT");
frame.swatch.bg = frame.swatch:CreateTexture(frame.swatch:GetName().."Bg", "BACKGROUND");
frame.swatch.bg:SetWidth(18); frame.swatch.bg:SetHeight(18);
frame.swatch.bg:SetPoint("CENTER");
frame.swatch.bg:SetColorTexture(1, 1, 1);
frame.swatch:SetNormalTexture("Interface\\ChatFrame\\ChatFrameColorSwatch");
frame.swatch:SetScript("OnEnter", function(self)
self.bg:SetVertexColor(_G.NORMAL_FONT_COLOR.r, _G.NORMAL_FONT_COLOR.g, _G.NORMAL_FONT_COLOR.b);
end);
frame.swatch:SetScript("OnLeave", function(self)
self.bg:SetVertexColor(_G.HIGHLIGHT_FONT_COLOR.r, _G.HIGHLIGHT_FONT_COLOR.g, _G.HIGHLIGHT_FONT_COLOR.b);
end);
frame.swatch:SetScript("OnClick", function(self, button)
_G.ColorPickerFrame.hasOpacity = false;
_G.ColorPickerFrame.func = function()
local r,g,b = _G.ColorPickerFrame:GetColorRGB();
dbTree[varName].r = r;
dbTree[varName].g = g;
dbTree[varName].b = b;
self:Hide();
self:Show();
options.frame:Enable();
end
_G.ColorPickerFrame.prev = {dbTree[varName].r, dbTree[varName].g, dbTree[varName].b};
_G.ColorPickerFrame:SetColorRGB(dbTree[varName].r, dbTree[varName].g, dbTree[varName].b);
_G.ColorPickerFrame.cancelFunc = function()
dbTree[varName].r = _G.ColorPickerFrame.prev[1];
dbTree[varName].g = _G.ColorPickerFrame.prev[2];
dbTree[varName].b = _G.ColorPickerFrame.prev[3];
self:Hide();
self:Show();
options.frame:Enable();
end
_G.ColorPickerFrame:SetFrameStrata("DIALOG");
_G.ColorPickerFrame:Show();
options.frame:Disable();
end);
frame.swatch:SetScript("OnShow", function(self)
self:GetNormalTexture():SetVertexColor(dbTree[varName].r, dbTree[varName].g, dbTree[varName].b);
end);
frame.swatch.title = frame.swatch:CreateFontString(frame.swatch:GetName().."Text", "OVERLAY", DefaultFont);
frame.swatch.title:SetPoint("LEFT", frame.swatch, "RIGHT", 10, 0);
frame.swatch.title:SetText(title);
SetNextAnchor(frame);
return frame;
end
local function CreateSlider(parent, title, minText, maxText, min, max, step, dbTree, varName, valChanged)
-- Changes to Patch 9.0.1 - Shadowlands, retail and classic
local s = CreateFrame("Slider", parent:GetName()..statObject("Slider"), parent, isTBC and "BackdropTemplate");
-- set backdrop -changes to Patch 9.0.1 - Shadowlands, retail and classic
s.backdropInfo = {bgFile = "Interface\\Buttons\\UI-SliderBar-Background",
edgeFile = "Interface\\Buttons\\UI-SliderBar-Border",
tile = true, tileSize = 8, edgeSize = 8,
insets = { left = 3, right = 3, top = 6, bottom = 6 }};
if not isTBC then
s:SetBackdrop(s.backdropInfo);
else
s:ApplyBackdrop();
end
s:SetHeight(17);
s:SetPoint("LEFT");
s:SetPoint("RIGHT", -75, 0);
s:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Horizontal");
s:SetOrientation("HORIZONTAL");
s:SetMinMaxValues(min, max);
s.title = s:CreateFontString(s:GetName().."Title", "OVERLAY", DefaultFont);
s.title:SetPoint("BOTTOMLEFT", s, "TOPLEFT", 0, 5);
s.title:SetText(title);
s.minText = s:CreateFontString(s:GetName().."Min", "OVERLAY", "ChatFontSmall");
s.minText:SetPoint("TOPLEFT", s, "BOTTOMLEFT", 5, 0);
s.minText:SetText(minText);
s.maxText = s:CreateFontString(s:GetName().."Max", "OVERLAY", "ChatFontSmall");
s.maxText:SetPoint("TOPRIGHT", s, "BOTTOMRIGHT", -5, 0);
s.maxText:SetText(maxText);
s.valText = s:CreateFontString(s:GetName().."Val", "OVERLAY", "ChatFontSmall");
s.valText:SetPoint("LEFT", s, "RIGHT", 15, 2);
s.valText:SetTextColor(unpack(TitleColor));
s.valText:SetText("");
s:SetValueStep(step);
s:SetScript("OnValueChanged", function(self)
if not self._onsetting then -- is single threaded
self._onsetting = true
self:SetValue(self:GetValue())
value = self:GetValue() -- cant use original 'value' parameter
self._onsetting = false
else return end
local newValue = self:GetValue()
self.valText:SetText(newValue);
dbTree[varName] = newValue;
if(type(valChanged) == "function") then
valChanged(self, newValue);
end
end);
s:SetScript("OnShow", function(self)
self:SetValue(tonumber(dbTree[varName]));
end);
SetNextAnchor(s);
return s;
end
local function CreateDropDownMenu(parent, dbTree, varName, itemList, width)
local menu = CreateFrame("Frame", parent:GetName()..statObject("DropDownMenu"), parent, "UIDropDownMenuTemplate");
menu:EnableMouse(true);
if(width) then
_G.UIDropDownMenu_SetWidth(menu, width);
end
menu.itemList = itemList or {};
menu.init = function()
for i=1, #menu.itemList do
if(not menu.itemList[i].hooked) then
local func = menu.itemList[i].func or function(self) end;
menu.itemList[i].func = function(self, arg1, arg2)
self = self or _G.this; -- wotlk/tbc hack
dbTree[varName] = self.value;
_G.UIDropDownMenu_SetSelectedValue(menu, self.value);
func(self, arg1, arg2);
end
menu.itemList[i].hooked = true;
end
local info = _G.UIDropDownMenu_CreateInfo();
for k,v in pairs(menu.itemList[i]) do
info[k] = v;
end
_G.UIDropDownMenu_AddButton(info, _G.UIDROPDOWNMENU_MENU_LEVEL);
end
end
menu:SetScript("OnShow", function(self)
_G.UIDropDownMenu_Initialize(self, self.init);
_G.UIDropDownMenu_SetSelectedValue(self, dbTree[varName]);
end);
menu.SetValue = function(self, value)
_G.UIDropDownMenu_SetSelectedValue(self, value);
end;
SetNextAnchor(menu);
menu:Hide(); menu:Show();
return menu;
end
local function CreateCheckButton(parent, title, dbTree, varName, tooltip, valChanged)
local cb = CreateFrame("CheckButton", parent:GetName()..statObject("CheckButton"), parent, "UICheckButtonTemplate");
cb.text = _G.getglobal(cb:GetName().."Text");
cb.children = {};
cb.isCheckButton = true;
cb.disabledByParent = nil; -- used to track enable and disables.
cb.CreateCheckButton = CreateCheckButton;
cb._Disable = cb.Disable;
cb._Enable = cb.Enable;
cb.text:SetText(" "..tostring(title));
cb.text:SetFontObject(DefaultFont);
cb:SetScript("OnShow", function(self)
local dbTbl = dbTree;
if(type(dbTree) == "function") then
dbTbl = dbTree();
end
self:SetChecked(dbTbl[varName]);
self:UpdateChildren();
end);
cb:SetScript("OnClick", function(self, button)
_G.PlaySound(856);
for i=1, #self.children do
if(self:GetChecked()) then
self.children[i]:Enable(self);
else
self.children[i]:Disable(self);
end
end
local dbTbl = dbTree;
if(type(dbTree) == "function") then
dbTbl = dbTree();
end
dbTbl[varName] = self:GetChecked() and true or false;
if(type(valChanged) == "function") then
valChanged(self, button);
end
end);
cb.Enable = function(self, enabler)
enabler = _enabler or self;
for i=1, #self.children do
if(not self.children[i]:IsEnabled() and self.children[i].disabledByParent == enabler) then
self.children[i]:Enable(enabler);
end
end
self:UpdateChildren();
self.disabledByParent = nil;
self.text:SetTextColor(1, 1, 1);
self:_Enable();
end
cb.Disable = function(self, disabler)
disabler = disabler or self;
for i=1, #self.children do
if(self.children[i]:IsEnabled()) then
--self.children[i]:UpdateChildren();
self.children[i]:Disable(disabler);
end
end
self.disabledByParent = disabler;
self.text:SetTextColor(unpack(DisabledColor));
self:_Disable();
end
cb.UpdateChildren = function(self)
for i=1, #self.children do
if(self:GetChecked()) then
self.children[i].text:SetTextColor(1, 1, 1);
self.children[i]:_Enable(self);
else
self.children[i].text:SetTextColor(unpack(DisabledColor));
self.children[i]:Disable(self);
end
end
end
if(parent.isCheckButton) then
cb:SetScale(.90);
if(#parent.children == 0) then
parent.nextOffSetX = parent:GetWidth();
parent.nextOffSetY = -parent:GetHeight();
else
parent.nextOffSetX = nil;
parent.nextOffSetY = nil;
end
table.insert(parent.children, cb);
end
SetNextAnchor(cb);
return cb;
end
local function CreateCheckButtonMenu(parent, title, dbTree, varName, tooltip, valChanged, itemList, dbTree2, varName2, valChanged2)
local cbm = CreateCheckButton(parent, title, dbTree, varName, tooltip, valChanged);
cbm.CreateCheckButtonMenu = CreateCheckButtonMenu;
cbm.menu = CreateFrame("Button", cbm:GetName().."MenuButton", cbm);
cbm.menu:SetWidth(26); cbm.menu:SetHeight(cbm.menu:GetWidth());
cbm.menu:SetNormalTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Up");
cbm.menu:SetPushedTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Down");
cbm.menu:SetDisabledTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Disabled");
cbm.menu:SetHighlightTexture("Interface\\Buttons\\UI-Common-MouseHilight", "ADD");
cbm.menu:SetPoint("LEFT", cbm:GetWidth()-2, 0);
cbm.menu.itemList = itemList;
cbm.menu.dropdown = options.createDropDownFrame();
cbm.text:ClearAllPoints(); cbm.text:SetPoint("LEFT", cbm.menu, "RIGHT");
-- some hooks to enherit disabled functionality.
local Enable, Disable = cbm.Enable, cbm.Disable;
cbm.Enable = function(...) cbm.menu:Enable(); Enable(...); end
cbm.Disable = function(...) cbm.menu:Disable(); Disable(...); end
local function clickFunc(self, ...)
dbTree2[varName2] = self.value;
end
-- now the menu work...
cbm.menu:SetScript("OnClick", function(self, button)
_G.PlaySound(1115);
self.dropdown:SetItemList(self.itemList, dbTree2[varName2], clickFunc);
self.dropdown:ToggleDropDownMenu(self, "TOPLEFT", "BOTTOMLEFT", 0, 0);
end);
return cbm;
end
local function CreateText(parent, inherritFrom, fontHeight)
inherritFrom = inherritFrom or DefaultFont;
local fs = parent:CreateFontString(parent:GetName()..statObject("FontString"), "OVERLAY", inherritFrom);
fs:Show();
if(fontHeight) then
local font, _, flags = fs:GetFont();
fs:SetFont(font, fontHeight, flags);
end
fs.SetFullSize = SetFullSize;
SetNextAnchor(fs);
return fs;
end
local function CreateSection(parent, title, desc)
local frame = options.CreateOptionsFrame();
frame:SetParent(parent);
frame:Show();
frame:SetFullSize();
if(title) then
frame.title = frame:CreateText(nil, 16);
frame.title:SetText(title);
frame.title:SetTextColor(unpack(TitleColor));
frame.title:SetFullSize();
frame.title:SetJustifyH("LEFT");
frame.title:SetPoint("TOPLEFT");
frame.nextOffSetY = -6;
end
if(desc) then
frame.description = frame:CreateText();
frame.description:SetText(desc);
frame.description:SetFullSize();
frame.description:SetJustifyH("LEFT");
frame.description:SetJustifyV("TOP");
--[[ frame:SetScript("OnUpdate", function(self, elapsed)
if(frame:GetWidth() < self.description:GetStringWidth()) then
self.description:SetHeight(self.description:GetStringWidth()/parent:GetWidth()*(self.description:GetStringHeight()+
self.description:GetSpacing()) + (self.description:GetStringHeight()+self.description:GetSpacing()));
end
frame:Hide();
frame:Show();
self:SetScript("OnUpdate", nil);
end);]]
end
frame:SetScript("OnShow", function(self)
if(self.lastObj and cbm) then
self:SetHeight(self:GetTop()-self.lastObj:GetBottom());
end
end);
SetNextAnchor(frame);
return frame;
end
local function CreateFramedPanel(parent)
local frame = CreateSection(parent, nil, nil);
options.AddFramedBackdrop(frame);
return frame;
end
local function ImportCustomObject(parent, obj)
statObject("CustomObj");
obj:SetParent(parent);
options.InherritOptionFrameProperties(obj);
SetNextAnchor(obj);
return obj;
end
function options.InherritOptionFrameProperties(obj)
obj.CreateSection = CreateSection;
obj.CreateText = CreateText;
obj.SetFullSize = SetFullSize;
obj.CreateCheckButton = CreateCheckButton;
obj.ImportCustomObject = ImportCustomObject;
obj.CreateFramedPanel = CreateFramedPanel;
obj.CreateDropDownMenu = CreateDropDownMenu;
obj.CreateCheckButtonMenu = CreateCheckButtonMenu;
obj.CreateSlider = CreateSlider;
obj.CreateColorPicker = CreateColorPicker;
obj.CreateButton = CreateButton;
end
-- Global usage for modules
function options.CreateOptionsFrame()
local frame = CreateFrame("Frame", "WIM3_OptionFrame"..statObject("Frame"));
frame:Hide();
-- declare the following tools.
options.InherritOptionFrameProperties(frame);
return frame;
end
function options.AddFramedBackdrop(obj)
obj.backdrop = {};
obj.backdrop.top = obj:CreateTexture(nil, "BACKGROUND");
obj.backdrop.top:SetColorTexture(1, 1, 1, .25);
obj.backdrop.top:SetPoint("TOPLEFT",-1 , 1);
obj.backdrop.top:SetPoint("TOPRIGHT",1 , 1);
obj.backdrop.top:SetHeight(1);
obj.backdrop.bottom = obj:CreateTexture(nil, "BACKGROUND");
obj.backdrop.bottom:SetColorTexture(1, 1, 1, .25);
obj.backdrop.bottom:SetPoint("BOTTOMLEFT",-1 , -1);
obj.backdrop.bottom:SetPoint("BOTTOMRIGHT",1 , -1);
obj.backdrop.bottom:SetHeight(1);
obj.backdrop.left = obj:CreateTexture(nil, "BACKGROUND");
obj.backdrop.left:SetColorTexture(1, 1, 1, .25);
obj.backdrop.left:SetPoint("TOPLEFT", obj.backdrop.top, "BOTTOMLEFT" ,0 , 0);
obj.backdrop.left:SetPoint("BOTTOMLEFT", obj.backdrop.bottom, "TOPLEFT" ,0 , 0);
obj.backdrop.left:SetWidth(1);
obj.backdrop.right = obj:CreateTexture(nil, "BACKGROUND");
obj.backdrop.right:SetColorTexture(1, 1, 1, .25);
obj.backdrop.right:SetPoint("TOPRIGHT", obj.backdrop.top, "BOTTOMRIGHT" ,0 , 0);
obj.backdrop.right:SetPoint("BOTTOMRIGHT", obj.backdrop.bottom, "TOPRIGHT" ,0 , 0);
obj.backdrop.right:SetWidth(1);
obj.backdrop.bg = obj:CreateTexture(nil, "BACKGROUND");
obj.backdrop.bg:SetColorTexture(0, 0, 0, .25);
obj.backdrop.bg:SetAllPoints();
end
--[[
Textures:
Buttons/UI-SliderBar-Button-Horizontal.blp - scroll thumb
]]
-- Prototype for scrollable menu. Must be toggled by whatever object it is bound to.
local dropDownFrame;
local dropDownButtonCount = 11;
local buttonProps = {"func", "owner", "keepShownOnClick", "tooltipTitle", "tooltipText", "arg1", "arg2", "notCheckable", "value"};
local function clearButton(self)
for i=1, #buttonProps do
self[buttonProps[i]] = nil;
end
end
local function clearButtons(self)
for i=1, #self.buttons do
self.buttons[i]:ClearButton();
end
end
local function setButton(self, info)
self:ClearButton();
local invisibleButton = _G[self:GetName().."InvisibleButton"];
local normalText = _G[self:GetName().."NormalText"];
-- set default values
self:Enable();
self:SetDisabledFontObject(_G.GameFontDisableSmallLeft);
invisibleButton:Hide();
-- If not clickable then disable the button and set it white
if ( info.notClickable ) then
info.disabled = 1;
self:SetDisabledFontObject(_G.GameFontHighlightSmallLeft);
end
-- Set the text color and disable it if its a title
if ( info.isTitle ) then
info.disabled = 1;
self:SetDisabledFontObject(_G.GameFontNormalSmallLeft);
end
-- Disable the button if disabled and turn off the color code
if ( info.disabled ) then
self:Disable();
invisibleButton:Show();
info.colorCode = nil;
end
self:SetText(info.text or "");
-- Pass through attributes
self.func = info.func;
self.owner = info.owner;
self.keepShownOnClick = info.keepShownOnClick;
self.tooltipTitle = info.tooltipTitle;
self.tooltipText = info.tooltipText;
self.arg1 = info.arg1;
self.arg2 = info.arg2;
self.notCheckable = info.notCheckable;
if ( info.value ) then
self.value = info.value;
elseif ( info.text ) then
self.value = info.text;
else
self.value = nil;
end
local checked = info.checked;
-- If not checkable move everything over to the left to fill in the gap where the check would be
normalText:ClearAllPoints();
if ( info.notCheckable ) then
if ( info.justifyH and info.justifyH == "CENTER" ) then
normalText:SetPoint("CENTER", self, "CENTER", -7, 0);
else
normalText:SetPoint("LEFT", self, "LEFT", 0, 0);
end
else
normalText:SetPoint("LEFT", self, "LEFT", 20, 0);
if(self.value and self:GetParent().value == self.value) then
checked = true;
end
end
-- Checked can be a function now
if ( type(checked) == "function" ) then
checked = checked();
end
-- Show the check if checked
if ( checked ) then
self:LockHighlight();
_G.getglobal(self:GetName().."Check"):Show();
else
self:UnlockHighlight();
_G.getglobal(self:GetName().."Check"):Hide();
end
self.checked = info.checked;
end
local function DropDown_OnMouseWheel(self, delta)
local scroll = self.scroll or self:GetParent().scroll or self:GetParent():GetParent().scroll;
if(scroll and scroll:IsShown()) then
local min, max = scroll:GetMinMaxValues();
local newVal = _G.math.floor(scroll:GetValue()) - delta;
if(newVal >= min and newVal <= max) then
scroll:SetValue(newVal);
end
end
end
function options.createDropDownFrame()
if(dropDownFrame) then
-- don't create more than once.
return dropDownFrame;
end
-- Changes to Patch 9.0.1 - Shadowlands, retail and classic
local f = CreateFrame("Button", "WIM_DropDownFrame", _G.UIParent, isTBC and "BackdropTemplate");
f:Hide();
f:SetFrameStrata("TOOLTIP");
f:SetPoint("CENTER");
f:SetWidth(100);
f:SetHeight(300);
f:EnableMouseWheel(1);
-- Changes to Patch 9.0.1 - Shadowlands, retail and classic
f.backdropInfo = {
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", tile = true, tileSize = 16, edgeSize = 16,
insets = { left = 5, right = 5, top = 5, bottom = 5 }
};
if not isTBC then
f:SetBackdrop(f.backdropInfo);
else
f:ApplyBackdrop();
end
f:SetBackdropBorderColor(_G.TOOLTIP_DEFAULT_COLOR.r, _G.TOOLTIP_DEFAULT_COLOR.g, _G.TOOLTIP_DEFAULT_COLOR.b);
f:SetBackdropColor(_G.TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, _G.TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, _G.TOOLTIP_DEFAULT_BACKGROUND_COLOR.b);
f.testString = f:CreateFontString(f:GetName().."TestString", "OVERLAY", "GameFontNormalSmallLeft");
f.testString:SetPoint("TOPLEFT");
f.testString:Hide();
--create scroll bar
f.scroll = CreateFrame("Slider", f:GetName().."Slider", f);
f.scroll.bg = f.scroll:CreateTexture(nil, "BACKGROUND");
f.scroll.bg:SetPoint("TOP", 0, -15);
f.scroll.bg:SetPoint("BOTTOM", 0, 15);
f.scroll.bg:SetWidth(2);
f.scroll.bg:SetColorTexture(1, 1, 1, .10);
f.scroll:SetOrientation("VERTICAL");
f.scroll:SetPoint("TOPRIGHT", -8, 0);
f.scroll:SetPoint("BOTTOM", 0 ,0);
f.scroll:SetWidth(5);
f.scroll:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Horizontal");
f.scroll:SetMinMaxValues(0, 10);
f.scroll:SetValue(5);
f.scroll:EnableMouseWheel(1);
f.scroll:SetScript("OnEnter", function(self) _G.UIDropDownMenu_StopCounting(self:GetParent()) end);
f.scroll:SetScript("OnLeave", function(self) _G.UIDropDownMenu_StartCounting(self:GetParent()) end);
f.scroll:SetScript("OnMouseWheel", DropDown_OnMouseWheel);
f.scroll:SetScript("OnValueChanged", function(self)
self:GetParent():Refresh();
end);
-- create buttons
f.buttons = {};
for i=1, dropDownButtonCount do
local button = CreateFrame("Button", f.scroll:GetName().."Button"..i, f, "UIDropDownMenuButtonTemplate");
button.ClearButton = clearButton;
button.SetButton = setButton;
table.insert(f.buttons, button);
if(i==1) then
button:SetPoint("TOPLEFT", 9, -9);
button:SetPoint("RIGHT", f.scroll, "LEFT", -2, 0);
else
button:SetPoint("TOPLEFT", f.buttons[i-1], "BOTTOMLEFT");
button:SetPoint("TOPRIGHT", f.buttons[i-1], "BOTTOMRIGHT");
end
button:EnableMouseWheel(1);
button:SetScript("OnMouseWheel", DropDown_OnMouseWheel);
button:HookScript("OnClick", function(self, ...)
local func = self:GetParent().clickFunc;
if(func) then
func(self, ...);
end
end);
end
-- actions
f.ClearButtons = clearButtons;
-- this call is made to reconfigure buttons.
f.Refresh = function(self)
local offset = _G.math.floor(self.scroll:GetValue()) or 0;
for i=1, (self.buttonsShown or 0) do
self.buttons[i]:SetButton(self.list[i+offset]);
end
end
-- this call is made when toggling. supplying fresh list.
f.SetItemList = function(self, list, val, additionalClickFunc)
self.value = val;
self.clickFunc = additionalClickFunc;
self:ClearButtons();
self.list = list;
if(#self.list > #self.buttons) then
self.scroll:Show();
self.scroll:SetValue(0);
self.scroll:SetMinMaxValues(0, _G.math.max(#self.list - #self.buttons, 1));
self.scroll:SetWidth(5);
-- add code to jump to selected offset.
else
self.scroll:SetValue(0);
self.scroll:Hide();
self.scroll:SetWidth(1);
end
-- set appropriate height
self.buttonsShown = _G.math.min(#self.list, #self.buttons);
self:SetHeight((self.buttonsShown * self.buttons[1]:GetHeight()) + 18);
-- set appropriate width
local maxWidth, tIndex = 20;
for index, tbl in pairs(self.list) do
self.testString:SetText(tbl.text or "");
maxWidth = _G.math.max(maxWidth, (self.testString:GetWidth() or 0) + (not tbl.notCheckable and 30 or 0));
tIndex = self.value == tbl.value and index or tIndex;
end
self:SetWidth(maxWidth + self.scroll:GetWidth() + 25)
if(self.scroll:IsShown() and tIndex and tIndex > self.buttonsShown) then
self.scroll:SetValue(tIndex - self.buttonsShown);
end
-- set up button visiblity;
for i=1, #self.buttons do
if i > self.buttonsShown then
self.buttons[i]:Hide();
else
self.buttons[i]:Show();
end
end
self:Refresh();
return self; -- allow for Chained actions;
end
f.ToggleDropDownMenu = function(self, parent, point, relativePoint, xOffset, yOffset)
if(f.prevParent == parent) then
f.prevParent = nil;
f:Hide();
return;
end
self:SetParent(parent);
point = point or "TOPLEFT";
relativePoint = relativePoint or "BOTTOMLEFT";
if( not xOffset and not yOffset ) then
xOffset = 8;
yOffset = -22;
end
xOffset = xOffset or 0;
yOffset = yOffset or 0;
self:ClearAllPoints();
self:SetPoint(point, parent, relativePoint, xOffset, yOffset);
f.prevParent = parent;
f:Show();
end
f:SetScript("OnClick", function(self) self:Hide(); end);
f:SetScript("OnEnter", _G.UIDropDownMenu_StopCounting);
f:SetScript("OnLeave", _G.UIDropDownMenu_StartCounting);
f:SetScript("OnUpdate", _G.UIDropDownMenu_OnUpdate);
f:SetScript("OnHide", function(self)
_G.UIDropDownMenu_OnHide(self);
self.prevParent = nil;
end);
f:SetScript("OnMouseWheel", DropDown_OnMouseWheel);
dropDownFrame = f;
return f;
end