Initial commit.
14
MogIt/Bindings.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<Bindings>
|
||||
<Binding name="MogIt" header="MogIt">
|
||||
MogIt:ToggleFrame()
|
||||
</Binding>
|
||||
<Binding name="MogItPreview">
|
||||
MogIt:TogglePreview()
|
||||
</Binding>
|
||||
<Binding name="MogIt_TooltipScrollUp" hidden="true">
|
||||
MogIt.tooltip.model:SetFacing(MogIt.tooltip.model:GetFacing()+0.3);
|
||||
</Binding>
|
||||
<Binding name="MogIt_TooltipScrollDown" hidden="true">
|
||||
MogIt.tooltip.model:SetFacing(MogIt.tooltip.model:GetFacing()-0.3);
|
||||
</Binding>
|
||||
</Bindings>
|
||||
393
MogIt/Core/Core.lua
Normal file
@@ -0,0 +1,393 @@
|
||||
local MogIt,mog = ...;
|
||||
_G["MogIt"] = mog;
|
||||
local L = mog.L;
|
||||
|
||||
local ItemInfo = LibStub("LibItemInfo-1.0");
|
||||
|
||||
LibStub("Libra"):EmbedWidgets(mog);
|
||||
|
||||
local character = DataStore_Containers and DataStore:GetCharacter();
|
||||
|
||||
mog.frame = CreateFrame("Frame","MogItFrame",UIParent,"ButtonFrameTemplate");
|
||||
mog.list = {};
|
||||
|
||||
function mog:Error(msg)
|
||||
DEFAULT_CHAT_FRAME:AddMessage("MogIt: "..msg,0.9,0.5,0.9);
|
||||
end
|
||||
|
||||
--// Slash Commands
|
||||
function mog:ToggleFrame()
|
||||
ToggleFrame(mog.frame);
|
||||
end
|
||||
|
||||
function mog:TogglePreview()
|
||||
ToggleFrame(mog.view);
|
||||
end
|
||||
--//
|
||||
|
||||
|
||||
--// Bindings
|
||||
SLASH_MOGIT1 = "/mog";
|
||||
SLASH_MOGIT2 = "/mogit";
|
||||
SlashCmdList["MOGIT"] = mog.ToggleFrame;
|
||||
|
||||
BINDING_HEADER_MogIt = "MogIt";
|
||||
BINDING_NAME_MogIt = L["Toggle Mogit"];
|
||||
BINDING_NAME_MogItPreview = L["Toggle Preview"];
|
||||
--//
|
||||
|
||||
|
||||
--// LibDataBroker
|
||||
mog.LDBI = LibStub("LibDBIcon-1.0");
|
||||
mog.mmb = LibStub("LibDataBroker-1.1"):NewDataObject("MogIt",{
|
||||
type = "launcher",
|
||||
icon = "Interface\\Icons\\INV_Enchant_EssenceCosmicGreater",
|
||||
OnClick = function(self,btn)
|
||||
if btn == "RightButton" then
|
||||
mog:TogglePreview();
|
||||
else
|
||||
mog:ToggleFrame();
|
||||
end
|
||||
end,
|
||||
OnTooltipShow = function(self)
|
||||
if not self or not self.AddLine then return end
|
||||
self:AddLine("MogIt");
|
||||
self:AddLine(L["Left click to toggle MogIt"],1,1,1);
|
||||
self:AddLine(L["Right click to toggle the preview"],1,1,1);
|
||||
end,
|
||||
});
|
||||
--//
|
||||
|
||||
|
||||
--// Module API
|
||||
mog.moduleVersion = 2;
|
||||
mog.modules = {};
|
||||
mog.moduleList = {};
|
||||
|
||||
function mog:GetModule(name)
|
||||
return mog.modules[name];
|
||||
end
|
||||
|
||||
function mog:GetActiveModule()
|
||||
return mog.active;
|
||||
end
|
||||
|
||||
function mog:RegisterModule(name,version,data)
|
||||
if mog.modules[name] then
|
||||
--mog:Error(L["The \124cFFFFFFFF%s\124r module is already loaded."]:format(name));
|
||||
return mog.modules[name];
|
||||
elseif type(version) ~= "number" or version < mog.moduleVersion then
|
||||
mog:Error(L["The \124cFFFFFFFF%s\124r module needs to be updated to work with this version of MogIt."]:format(name));
|
||||
return;
|
||||
elseif version > mog.moduleVersion then
|
||||
mog:Error(L["The \124cFFFFFFFF%s\124r module requires you to update MogIt for it to work."]:format(name));
|
||||
return;
|
||||
end
|
||||
data = data or {};
|
||||
data.name = name;
|
||||
mog.modules[name] = data;
|
||||
table.insert(mog.moduleList,data);
|
||||
if mog.menu.active == mog.menu.modules then
|
||||
mog.menu:Rebuild(1);
|
||||
end
|
||||
return data;
|
||||
end
|
||||
|
||||
function mog:SetModule(module,text)
|
||||
if mog.active and mog.active ~= module and mog.active.Unlist then
|
||||
mog.active:Unlist(module);
|
||||
end
|
||||
mog.active = module;
|
||||
mog:BuildList(true);
|
||||
mog:FilterUpdate();
|
||||
mog.frame.path:SetText(text or module.label or module.name or "");
|
||||
end
|
||||
|
||||
function mog:BuildList(top,module)
|
||||
if (module and mog.active and mog.active.name ~= module) then return end;
|
||||
mog.list = mog.active and mog.active.BuildList and mog.active:BuildList() or {};
|
||||
mog:SortList(nil,true);
|
||||
mog.scroll:update(top and 1);
|
||||
mog.filt.models:SetText(#mog.list);
|
||||
end
|
||||
--//
|
||||
|
||||
--// Item Cache
|
||||
local itemCacheCallbacks = {
|
||||
BuildList = mog.BuildList;
|
||||
ModelOnEnter = function()
|
||||
local owner = GameTooltip:GetOwner();
|
||||
if owner and GameTooltip[mog] then
|
||||
owner:OnEnter();
|
||||
end
|
||||
end,
|
||||
ItemMenu = function()
|
||||
mog.Item_Menu:Rebuild(1);
|
||||
end,
|
||||
SetMenu = function()
|
||||
mog.Set_Menu:Rebuild(1);
|
||||
end,
|
||||
};
|
||||
|
||||
local pendingCallbacks = {};
|
||||
|
||||
for k in pairs(itemCacheCallbacks) do
|
||||
pendingCallbacks[k] = {};
|
||||
end
|
||||
|
||||
function mog:AddItemCacheCallback(name, func)
|
||||
itemCacheCallbacks[name] = func;
|
||||
pendingCallbacks[name] = {};
|
||||
end
|
||||
|
||||
function mog:GetItemInfo(id, type)
|
||||
if not type then return ItemInfo[id] end
|
||||
if ItemInfo[id] then
|
||||
-- clear pending items when they are cached
|
||||
pendingCallbacks[type][id] = nil;
|
||||
return ItemInfo[id];
|
||||
elseif itemCacheCallbacks[type] then
|
||||
-- add to pending items for this callback if not cached
|
||||
pendingCallbacks[type][id] = true;
|
||||
end
|
||||
end
|
||||
|
||||
function mog.ItemInfoReceived()
|
||||
for k, callback in pairs(pendingCallbacks) do
|
||||
-- execute the callback if any items are pending for it
|
||||
if next(callback) then
|
||||
itemCacheCallbacks[k]();
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ItemInfo.RegisterCallback(mog, "OnItemInfoReceivedBatch", "ItemInfoReceived");
|
||||
--//
|
||||
|
||||
function mog:HasItem(itemID)
|
||||
return TransmogTipList and tContains(TransmogTipList, itemID)
|
||||
-- return GetItemCount(itemID, true) > 0 or (character and select(3, DataStore:GetContainerItemCount(character, itemID)) > 0)
|
||||
end
|
||||
|
||||
|
||||
--// Events
|
||||
local defaults = {
|
||||
profile = {
|
||||
sortWishlist = false,
|
||||
dressupPreview = false,
|
||||
singlePreview = false,
|
||||
previewUIPanel = false,
|
||||
previewFixedSize = false,
|
||||
noAnim = false,
|
||||
minimap = {},
|
||||
url = "Battle.net",
|
||||
|
||||
point = "CENTER",
|
||||
gridWidth = 600,
|
||||
gridHeight = 400,
|
||||
rows = 2;
|
||||
columns = 3,
|
||||
gridDress = "preview",
|
||||
sync = true,
|
||||
previewProps = {
|
||||
["*"] = {
|
||||
w = 335,
|
||||
h = 385,
|
||||
point = "CENTER",
|
||||
}
|
||||
},
|
||||
|
||||
tooltip = true,
|
||||
tooltipWidth = 300,
|
||||
tooltipHeight = 300,
|
||||
tooltipMouse = false,
|
||||
tooltipDress = false,
|
||||
tooltipRotate = true,
|
||||
tooltipMog = true,
|
||||
tooltipMod = "None",
|
||||
tooltipCustomModel = false,
|
||||
}
|
||||
}
|
||||
|
||||
function mog.LoadSettings()
|
||||
mog:UpdateGUI();
|
||||
|
||||
if mog.db.profile.minimap.hide then
|
||||
mog.LDBI:Hide("MogIt");
|
||||
else
|
||||
mog.LDBI:Show("MogIt");
|
||||
end
|
||||
|
||||
mog.tooltip:SetSize(mog.db.profile.tooltipWidth, mog.db.profile.tooltipHeight);
|
||||
if mog.db.profile.tooltipRotate then mog.tooltip.rotate:Show() else mog.tooltip.rotate:Hide() end
|
||||
|
||||
mog.scroll:update();
|
||||
|
||||
mog:SetSinglePreview(mog.db.profile.singlePreview);
|
||||
end
|
||||
|
||||
mog.frame:RegisterEvent("ADDON_LOADED");
|
||||
mog.frame:RegisterEvent("PLAYER_LOGIN");
|
||||
mog.frame:RegisterEvent("GET_ITEM_INFO_RECEIVED");
|
||||
mog.frame:RegisterEvent("PLAYER_EQUIPMENT_CHANGED");
|
||||
mog.frame:SetScript("OnEvent", function(self, event, ...)
|
||||
return mog[event] and mog[event](mog, ...)
|
||||
end);
|
||||
|
||||
function mog:ADDON_LOADED(addon)
|
||||
if addon == MogIt then
|
||||
local AceDB = LibStub("AceDB-3.0")
|
||||
mog.db = AceDB:New("MogItDB", defaults, true)
|
||||
mog.db.RegisterCallback(mog, "OnProfileChanged", "LoadSettings")
|
||||
mog.db.RegisterCallback(mog, "OnProfileCopied", "LoadSettings")
|
||||
mog.db.RegisterCallback(mog, "OnProfileReset", "LoadSettings")
|
||||
|
||||
if not mog.db.global.version then
|
||||
end
|
||||
mog.db.global.version = GetAddOnMetadata(MogIt,"Version");
|
||||
|
||||
mog.LDBI:Register("MogIt",mog.mmb,mog.db.profile.minimap);
|
||||
|
||||
|
||||
for name,module in pairs(mog.moduleList) do
|
||||
if module.MogItLoaded then
|
||||
module:MogItLoaded()
|
||||
end
|
||||
end
|
||||
elseif mog.modules[addon] then
|
||||
mog.modules[addon].loaded = true;
|
||||
if mog.menu.active == mog.menu.modules then
|
||||
mog.menu:Rebuild(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mog:PLAYER_LOGIN()
|
||||
mog:LoadSettings()
|
||||
self.frame:SetScript("OnSizeChanged", function(self, width, height)
|
||||
mog.db.profile.gridWidth = width;
|
||||
mog.db.profile.gridHeight = height;
|
||||
mog:UpdateGUI(true);
|
||||
end)
|
||||
end
|
||||
|
||||
function mog:PLAYER_EQUIPMENT_CHANGED(slot, hasItem)
|
||||
-- don't do anything if the slot is not visible (necklace, ring, trinket)
|
||||
if mog.db.profile.gridDress == "equipped" then
|
||||
for i, frame in ipairs(mog.models) do
|
||||
local item = frame.data.item
|
||||
if item then
|
||||
local slotName = mog.mogSlots[slot];
|
||||
if hasItem then
|
||||
if (slot ~= INVSLOT_HEAD or ShowingHelm()) and (slot ~= INVSLOT_BACK or ShowingCloak()) then
|
||||
frame:TryOn(mog.mogSlots[slot] and select(6, GetTransmogrifySlotInfo(slot)) or GetInventoryItemID("player", slot), slotName);
|
||||
end
|
||||
else
|
||||
frame:UndressSlot(slot);
|
||||
end
|
||||
frame:TryOn(item);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
--//
|
||||
|
||||
|
||||
--// Data API
|
||||
mog.data = {};
|
||||
|
||||
function mog:AddData(data,id,key,value)
|
||||
if not data and id and key then return end;
|
||||
if not mog.data[data] then
|
||||
mog.data[data] = {};
|
||||
end
|
||||
if not mog.data[data][key] then
|
||||
mog.data[data][key] = {};
|
||||
end
|
||||
mog.data[data][key][id] = value;
|
||||
return value;
|
||||
end
|
||||
|
||||
function mog:DeleteData(data,id,key)
|
||||
if not mog.data[data] then return end;
|
||||
if id and key then
|
||||
mog.data[data][key][id] = nil;
|
||||
elseif id then
|
||||
for k,v in pairs(mog.data[data]) do
|
||||
v[id] = nil;
|
||||
end
|
||||
elseif key then
|
||||
mog.data[data][key] = nil;
|
||||
else
|
||||
mog.data[data] = nil;
|
||||
end
|
||||
end
|
||||
|
||||
function mog:GetData(data,id,key)
|
||||
return mog.data[data] and mog.data[data][key] and mog.data[data][key][id];
|
||||
end
|
||||
--//
|
||||
|
||||
|
||||
--// Slot Conversion
|
||||
mog.slots = {
|
||||
"HeadSlot",
|
||||
"ShoulderSlot",
|
||||
"BackSlot",
|
||||
"ChestSlot",
|
||||
"ShirtSlot",
|
||||
"TabardSlot",
|
||||
"WristSlot",
|
||||
"HandsSlot",
|
||||
"WaistSlot",
|
||||
"LegsSlot",
|
||||
"FeetSlot",
|
||||
"MainHandSlot",
|
||||
"SecondaryHandSlot",
|
||||
};
|
||||
|
||||
mog.slotsType = {
|
||||
INVTYPE_HEAD = "HeadSlot",
|
||||
INVTYPE_SHOULDER = "ShoulderSlot",
|
||||
INVTYPE_CLOAK = "BackSlot",
|
||||
INVTYPE_CHEST = "ChestSlot",
|
||||
INVTYPE_ROBE = "ChestSlot",
|
||||
INVTYPE_BODY = "ShirtSlot",
|
||||
INVTYPE_TABARD = "TabardSlot",
|
||||
INVTYPE_WRIST = "WristSlot",
|
||||
INVTYPE_HAND = "HandsSlot",
|
||||
INVTYPE_WAIST = "WaistSlot",
|
||||
INVTYPE_LEGS = "LegsSlot",
|
||||
INVTYPE_FEET = "FeetSlot",
|
||||
INVTYPE_2HWEAPON = "MainHandSlot",
|
||||
INVTYPE_WEAPON = "MainHandSlot",
|
||||
INVTYPE_WEAPONMAINHAND = "MainHandSlot",
|
||||
INVTYPE_WEAPONOFFHAND = "SecondaryHandSlot",
|
||||
INVTYPE_RANGED = "MainHandSlot",
|
||||
INVTYPE_RANGEDRIGHT = "MainHandSlot",
|
||||
INVTYPE_SHIELD = "SecondaryHandSlot",
|
||||
INVTYPE_HOLDABLE = "SecondaryHandSlot",
|
||||
INVTYPE_THROWN = "MainHandSlot"
|
||||
};
|
||||
|
||||
-- all slot IDs that can be transmogrified
|
||||
mog.mogSlots = {
|
||||
[INVSLOT_HEAD] = "HeadSlot",
|
||||
[INVSLOT_SHOULDER] = "ShoulderSlot",
|
||||
[INVSLOT_BACK] = "BackSlot",
|
||||
[INVSLOT_CHEST] = "ChestSlot",
|
||||
[INVSLOT_BODY] = "ShirtSlot",
|
||||
[INVSLOT_TABARD] = "TabardSlot",
|
||||
[INVSLOT_WRIST] = "WristSlot",
|
||||
[INVSLOT_HAND] = "HandsSlot",
|
||||
[INVSLOT_WAIST] = "WaistSlot",
|
||||
[INVSLOT_LEGS] = "LegsSlot",
|
||||
[INVSLOT_FEET] = "FeetSlot",
|
||||
[INVSLOT_MAINHAND] = "MainHandSlot",
|
||||
[INVSLOT_OFFHAND] = "SecondaryHandSlot",
|
||||
}
|
||||
|
||||
function mog:GetSlot(id)
|
||||
return mog.slots[id] or mog.slotsType[id];
|
||||
end
|
||||
--//
|
||||
432
MogIt/Core/Core.xml
Normal file
@@ -0,0 +1,432 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Ui xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.blizzard.com/wow/ui/" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
..\FrameXML\UI.xsd">
|
||||
|
||||
<!-- if find textures "Interface\FrameGeneral\_UI-Frame" and "Interface\FrameGeneral\UI-Frame"-->
|
||||
<Texture name="_UI-Frame-TitleTileBg" file="Interface\AddOns\MogIt\FrameGeneral\_UI-Frame" virtual="true" horizTile="true" >
|
||||
<Size x="256" y="17"/>
|
||||
<TexCoords left="0.00000000" right="1.00000000" top="0.28906250" bottom="0.42187500"/>
|
||||
</Texture>
|
||||
|
||||
<Texture name="UI-Frame-Portrait" file="Interface\AddOns\MogIt\FrameGeneral\UI-Frame" virtual="true">
|
||||
<Size x="78" y="78"/>
|
||||
<TexCoords left="0.00781250" right="0.61718750" top="0.00781250" bottom="0.61718750"/>
|
||||
</Texture>
|
||||
|
||||
<Texture name="UI-Frame-TopCornerRight" file="Interface\AddOns\MogIt\FrameGeneral\UI-Frame" virtual="true">
|
||||
<Size x="33" y="33"/>
|
||||
<TexCoords left="0.63281250" right="0.89062500" top="0.00781250" bottom="0.26562500"/>
|
||||
</Texture>
|
||||
|
||||
<Texture name="UI-Frame-TopLeftCorner" file="Interface\AddOns\MogIt\FrameGeneral\UI-Frame" virtual="true">
|
||||
<Size x="32" y="32"/>
|
||||
<TexCoords left="0.63281250" right="0.88281250" top="0.28125000" bottom="0.53125000"/>
|
||||
</Texture>
|
||||
|
||||
<Texture name="_UI-Frame-TitleTile" file="Interface\AddOns\MogIt\FrameGeneral\_UI-Frame" virtual="true" horizTile="true" >
|
||||
<Size x="256" y="28"/>
|
||||
<TexCoords left="0.00000000" right="1.00000000" top="0.43750000" bottom="0.65625000"/>
|
||||
</Texture>
|
||||
|
||||
<Texture name="_UI-Frame-TopTileStreaks" file="Interface\AddOns\MogIt\FrameGeneral\_UI-Frame" virtual="true" horizTile="true" >
|
||||
<Size x="256" y="37"/>
|
||||
<TexCoords left="0.00000000" right="1.00000000" top="0.67187500" bottom="0.96093750"/>
|
||||
</Texture>
|
||||
<Texture name="UI-Frame-BotCornerLeft" file="Interface\AddOns\MogIt\FrameGeneral\UI-Frame" virtual="true">
|
||||
<Size x="14" y="14"/>
|
||||
<TexCoords left="0.00781250" right="0.11718750" top="0.63281250" bottom="0.74218750"/>
|
||||
</Texture>
|
||||
<Texture name="UI-Frame-BotCornerRight" file="Interface\AddOns\MogIt\FrameGeneral\UI-Frame" virtual="true">
|
||||
<Size x="11" y="11"/>
|
||||
<TexCoords left="0.13281250" right="0.21875000" top="0.89843750" bottom="0.98437500"/>
|
||||
</Texture>
|
||||
<Texture name="_UI-Frame-Bot" file="Interface\AddOns\MogIt\FrameGeneral\_UI-Frame" virtual="true" horizTile="true" >
|
||||
<Size x="256" y="9"/>
|
||||
<TexCoords left="0.00000000" right="1.00000000" top="0.20312500" bottom="0.27343750"/>
|
||||
</Texture>
|
||||
<Texture name="!UI-Frame-LeftTile" file="Interface\AddOns\MogIt\FrameGeneral\!UI-Frame" virtual="true" vertTile="true" >
|
||||
<Size x="16" y="256"/>
|
||||
<TexCoords left="0.35937500" right="0.60937500" top="0.00000000" bottom="1.00000000"/>
|
||||
</Texture>
|
||||
<Texture name="!UI-Frame-RightTile" file="Interface\AddOns\MogIt\FrameGeneral\!UI-Frame" virtual="true" vertTile="true" >
|
||||
<Size x="10" y="256"/>
|
||||
<TexCoords left="0.17187500" right="0.32812500" top="0.00000000" bottom="1.00000000"/>
|
||||
</Texture>
|
||||
|
||||
|
||||
<Frame name="PortraitFrameTemplate" virtual="true">
|
||||
<Size x="338" y="424"/>
|
||||
<Layers>
|
||||
<Layer level="BACKGROUND" textureSubLevel="-6">
|
||||
<Texture name="$parentBg" file="Interface\AddOns\MogIt\FrameGeneral\UI-Background-Rock" horizTile="true" vertTile="true">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" x="2" y="-21"/>
|
||||
<Anchor point="BOTTOMRIGHT" x="-2" y="2"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture name="$parentTitleBg" inherits="_UI-Frame-TitleTileBG">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" x="2" y="-3"/>
|
||||
<Anchor point="TOPRIGHT" x="-25" y="-3"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
</Layer>
|
||||
<Layer level="OVERLAY" textureSubLevel="-1">
|
||||
<Texture name="$parentPortrait" parentKey="portrait">
|
||||
<Size x="60" y="60"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" x="-6" y="7" />
|
||||
</Anchors>
|
||||
</Texture>
|
||||
</Layer>
|
||||
<Layer level="OVERLAY">
|
||||
<Texture name="$parentPortraitFrame" inherits="UI-Frame-Portrait" parentKey="portraitFrame">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" x="-14" y="11"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture name="$parentTopRightCorner" inherits="UI-Frame-TopCornerRight">
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT" x="0" y="1"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture name="$parentTopLeftCorner" inherits="UI-Frame-TopLeftCorner" hidden="true" parentKey="topLeftCorner">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" x="-6" y="1"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture name="$parentTopBorder" inherits="_UI-Frame-TitleTile" parentKey="topBorderBar">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentPortraitFrame" relativePoint="TOPRIGHT" x="0" y="-10" />
|
||||
<Anchor point="TOPRIGHT" relativeTo="$parentTopRightCorner" relativePoint="TOPLEFT"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<FontString name="$parentTitleText" inherits="GameFontNormal" text="" parentKey="TitleText">
|
||||
<Anchors>
|
||||
<Anchor point="TOP" x="0" y="-4"/>
|
||||
<Anchor point="LEFT" x="60"/>
|
||||
<Anchor point="RIGHT" x="-60"/>
|
||||
</Anchors>
|
||||
</FontString>
|
||||
</Layer>
|
||||
<Layer level="BORDER">
|
||||
<Texture name="$parentTopTileStreaks" inherits="_UI-Frame-TopTileStreaks" parentKey="TopTileStreaks">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" x="0" y="-21"/>
|
||||
<Anchor point="TOPRIGHT" x="-2" y="-21"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture name="$parentBotLeftCorner" inherits="UI-Frame-BotCornerLeft">
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMLEFT" x="-6" y="-5"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture name="$parentBotRightCorner" inherits="UI-Frame-BotCornerRight">
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMRIGHT" x="0" y="-5"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture name="$parentBottomBorder" inherits="_UI-Frame-Bot">
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMLEFT" relativeTo="$parentBotLeftCorner" relativePoint="BOTTOMRIGHT" y="0"/>
|
||||
<Anchor point="BOTTOMRIGHT" relativeTo="$parentBotRightCorner" relativePoint="BOTTOMLEFT" y="0"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture name="$parentLeftBorder" inherits="!UI-Frame-LeftTile" parentKey="leftBorderBar">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentPortraitFrame" relativePoint="BOTTOMLEFT" x="8" y="0" />
|
||||
<Anchor point="BOTTOMLEFT" relativeTo="$parentBotLeftCorner" relativePoint="TOPLEFT"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture name="$parentRightBorder" inherits="!UI-Frame-RightTile">
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT" relativeTo="$parentTopRightCorner" relativePoint="BOTTOMRIGHT" x="1"/>
|
||||
<Anchor point="BOTTOMRIGHT" relativeTo="$parentBotRightCorner" relativePoint="TOPRIGHT"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Frames>
|
||||
<Button name="$parentCloseButton" inherits="UIPanelCloseButton">
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT" relativePoint="TOPRIGHT">
|
||||
<Offset x="4" y="5"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</Button>
|
||||
</Frames>
|
||||
</Frame>
|
||||
|
||||
<Frame name="ButtonFrameTemplate" inherits="PortraitFrameTemplate" virtual="true">
|
||||
<Layers>
|
||||
<Layer level="BORDER">
|
||||
<Texture name="$parentBtnCornerLeft" inherits="UI-Frame-BtnCornerLeft">
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMLEFT" x="-2" y="-1"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture name="$parentBtnCornerRight" inherits="UI-Frame-BtnCornerRight">
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMRIGHT" x="0" y="-1"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture name="$parentButtonBottomBorder" inherits="_UI-Frame-BtnBotTile">
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMLEFT" relativeTo="$parentBtnCornerLeft" relativePoint="BOTTOMRIGHT" y="3"/>
|
||||
<Anchor point="BOTTOMRIGHT" relativeTo="$parentBtnCornerRight" relativePoint="BOTTOMLEFT"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Frames>
|
||||
<Frame name="$parentInset" useParentLevel="true" inherits="InsetFrameTemplate" parentKey="Inset">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" x="4" y="-60" />
|
||||
<Anchor point="BOTTOMRIGHT" x="-6" y="26" />
|
||||
</Anchors>
|
||||
</Frame>
|
||||
</Frames>
|
||||
</Frame>
|
||||
|
||||
<Button name="MagicButtonTemplate" inherits="UIPanelButtonTemplate2" virtual="true">
|
||||
<Size x="80" y="22"/>
|
||||
<Scripts>
|
||||
<OnLoad function="MagicButton_OnLoad" />
|
||||
</Scripts>
|
||||
</Button>
|
||||
|
||||
<Slider name="UIPanelScrollBarTrimTemplate" virtual="true">
|
||||
<Size>
|
||||
<AbsDimension x="20" y="0"/>
|
||||
</Size>
|
||||
<Layers>
|
||||
<Layer level="BACKGROUND">
|
||||
<Texture name="$parentBG" setAllPoints="true" hidden="true">
|
||||
<Color r="0" g="0" b="0" a=".85"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
<Layer level="ARTWORK">
|
||||
<Texture name="$parentTop" file="Interface\PaperDollInfoFrame\UI-Character-ScrollBar">
|
||||
<Size>
|
||||
<AbsDimension x="24" y="48"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT">
|
||||
<Offset>
|
||||
<AbsDimension x="-4" y="17"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<TexCoords left="0" right="0.45" top="0" bottom=".20"/>
|
||||
</Texture>
|
||||
<Texture name="$parentBottom" file="Interface\PaperDollInfoFrame\UI-Character-ScrollBar">
|
||||
<Size>
|
||||
<AbsDimension x="24" y="64"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMLEFT">
|
||||
<Offset>
|
||||
<AbsDimension x="-4" y="-15"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<TexCoords left="0.515625" right="0.97" top="0.1440625" bottom="0.4140625"/>
|
||||
</Texture>
|
||||
<Texture name="$parentMiddle" file="Interface\PaperDollInfoFrame\UI-Character-ScrollBar">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentTop" relativePoint="BOTTOMLEFT"/>
|
||||
<Anchor point="BOTTOMRIGHT" relativeTo="$parentBottom" relativePoint="TOPRIGHT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0" right="0.45" top="0.1640625" bottom="1"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Frames>
|
||||
<Button name="$parentScrollUpButton" inherits="UIPanelScrollUpButtonTemplate">
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOM" relativePoint="TOP" x="0" y="-2"/>
|
||||
</Anchors>
|
||||
<Scripts>
|
||||
<OnClick>
|
||||
local parent = self:GetParent();
|
||||
local scrollStep = self:GetParent().scrollStep or (parent:GetHeight() / 2);
|
||||
parent:SetValue(parent:GetValue() - scrollStep);
|
||||
PlaySound("UChatScrollButton");
|
||||
</OnClick>
|
||||
</Scripts>
|
||||
</Button>
|
||||
<Button name="$parentScrollDownButton" inherits="UIPanelScrollDownButtonTemplate">
|
||||
<Anchors>
|
||||
<Anchor point="TOP" relativePoint="BOTTOM" x="0" y="2"/>
|
||||
</Anchors>
|
||||
<Scripts>
|
||||
<OnClick>
|
||||
local parent = self:GetParent();
|
||||
local scrollStep = self:GetParent().scrollStep or (parent:GetHeight() / 2);
|
||||
parent:SetValue(parent:GetValue() + scrollStep);
|
||||
PlaySound("UChatScrollButton");
|
||||
</OnClick>
|
||||
</Scripts>
|
||||
</Button>
|
||||
</Frames>
|
||||
<Scripts>
|
||||
<OnValueChanged>
|
||||
self:GetParent():SetVerticalScroll(value);
|
||||
</OnValueChanged>
|
||||
</Scripts>
|
||||
<ThumbTexture name="$parentThumbTexture" inherits="UIPanelScrollBarButton" file="Interface\Buttons\UI-ScrollBar-Knob">
|
||||
<Size>
|
||||
<AbsDimension x="18" y="24"/>
|
||||
</Size>
|
||||
<TexCoords left="0.20" right="0.80" top="0.125" bottom="0.875"/>
|
||||
</ThumbTexture>
|
||||
</Slider>
|
||||
|
||||
<EditBox name="SearchBoxTemplate" inherits="InputBoxTemplate" autoFocus="false" virtual="true">
|
||||
<Layers>
|
||||
<Layer level="OVERLAY">
|
||||
<Texture name="$parentSearchIcon" file="Interface\Common\UI-Searchbox-Icon" parentKey="searchIcon">
|
||||
<Size x="14" y="14"/>
|
||||
<Anchors>
|
||||
<Anchor point="LEFT" x="-" y="-2"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Frames>
|
||||
<Button name="$parentClearButton" parentKey="clearButton" hidden="true">
|
||||
<Size x="17" y="17"/>
|
||||
<Anchors>
|
||||
<Anchor point="RIGHT" x="-3" y="0"/>
|
||||
</Anchors>
|
||||
<Layers>
|
||||
<Layer level="ARTWORK">
|
||||
<Texture file="Interface\FriendsFrame\ClearBroadcastIcon" alpha="0.5" parentKey="texture">
|
||||
<Size>
|
||||
<AbsDimension x="17" y="17"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" x="0" y="0"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Scripts>
|
||||
<OnEnter>
|
||||
self.texture:SetAlpha(1.0);
|
||||
</OnEnter>
|
||||
<OnLeave>
|
||||
self.texture:SetAlpha(0.5);
|
||||
</OnLeave>
|
||||
<OnMouseDown>
|
||||
if self:IsEnabled() then
|
||||
self.texture:SetPoint("TOPLEFT", 1, -1);
|
||||
end
|
||||
</OnMouseDown>
|
||||
<OnMouseUp>
|
||||
self.texture:SetPoint("TOPLEFT", 0, 0);
|
||||
</OnMouseUp>
|
||||
<OnClick>
|
||||
PlaySound("igMainMenuOptionCheckBoxOn");
|
||||
local editBox = self:GetParent();
|
||||
if editBox.clearFunc then
|
||||
editBox.clearFunc(editBox);
|
||||
end
|
||||
|
||||
editBox:SetText("");
|
||||
if not editBox:HasFocus() then
|
||||
editBox:GetScript("OnEditFocusLost")(editBox);
|
||||
end
|
||||
editBox:ClearFocus();
|
||||
</OnClick>
|
||||
</Scripts>
|
||||
</Button>
|
||||
</Frames>
|
||||
<Scripts>
|
||||
<OnLoad function="SearchBoxTemplate_OnLoad"/>
|
||||
<OnEscapePressed function="EditBox_ClearFocus"/>
|
||||
<OnEditFocusLost function="SearchBoxTemplate_OnEditFocusLost"/>
|
||||
<OnEditFocusGained function="SerachBoxTemplate_OnEditFocusGained"/>
|
||||
</Scripts>
|
||||
</EditBox>
|
||||
|
||||
<Frame name="TooltipBorderedFrameTemplate" virtual="true">
|
||||
<Layers>
|
||||
<Layer level="BACKGROUND">
|
||||
<Texture parentKey="BorderTopLeft" file="Interface\Tooltips\UI-Tooltip-TL">
|
||||
<Size x="8" y="8"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture parentKey="BorderTopRight" file="Interface\Tooltips\UI-Tooltip-TR">
|
||||
<Size x="8" y="8"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture parentKey="BorderBottomRight" file="Interface\Tooltips\UI-Tooltip-BR">
|
||||
<Size x="8" y="8"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMRIGHT"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture parentKey="BorderBottomLeft" file="Interface\Tooltips\UI-Tooltip-BL">
|
||||
<Size x="8" y="8"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMLEFT"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture parentKey="BorderTop" file="Interface\Tooltips\UI-Tooltip-T">
|
||||
<Size x="8" y="8"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeKey="$parent.BorderTopLeft" relativePoint="TOPRIGHT"/>
|
||||
<Anchor point="TOPRIGHT" relativeKey="$parent.BorderTopRight" relativePoint="TOPLEFT"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture parentKey="BorderRight" file="Interface\Tooltips\UI-Tooltip-R">
|
||||
<Size x="8" y="8"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT" relativeKey="$parent.BorderTopRight" relativePoint="BOTTOMRIGHT"/>
|
||||
<Anchor point="BOTTOMRIGHT" relativeKey="$parent.BorderBottomRight" relativePoint="TOPRIGHT"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture parentKey="BorderBottom" file="Interface\Tooltips\UI-Tooltip-B">
|
||||
<Size x="8" y="8"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMLEFT" relativeKey="$parent.BorderBottomLeft" relativePoint="BOTTOMRIGHT"/>
|
||||
<Anchor point="BOTTOMRIGHT" relativeKey="$parent.BorderBottomRight" relativePoint="BOTTOMLEFT"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture parentKey="BorderLeft" file="Interface\Tooltips\UI-Tooltip-L">
|
||||
<Size x="8" y="8"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeKey="$parent.BorderTopLeft" relativePoint="BOTTOMLEFT"/>
|
||||
<Anchor point="BOTTOMLEFT" relativeKey="$parent.BorderBottomLeft" relativePoint="TOPLEFT"/>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture parentKey="Background">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeKey="$parent.BorderTopLeft" relativePoint="BOTTOMRIGHT"/>
|
||||
<Anchor point="BOTTOMRIGHT" relativeKey="$parent.BorderBottomRight" relativePoint="TOPLEFT"/>
|
||||
</Anchors>
|
||||
<Color r="0" g="0" b="0" a="0.8"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
</Frame>
|
||||
|
||||
<Script file="Core.lua"/>
|
||||
<Script file="GUI.lua"/>
|
||||
<Script file="Preview.lua"/>
|
||||
<Script file="Links.lua"/>
|
||||
<Script file="URL.lua"/>
|
||||
<Script file="Tooltip.lua"/>
|
||||
<Script file="Options.lua"/>
|
||||
<Script file="Templates.lua"/>
|
||||
<Script file="Enchants.lua"/>
|
||||
|
||||
<Include file="Filters\Filters.xml"/>
|
||||
<Include file="Sorting\Sorting.xml"/>
|
||||
|
||||
</Ui>
|
||||
316
MogIt/Core/Enchants.lua
Normal file
@@ -0,0 +1,316 @@
|
||||
local _, MogIt = ...
|
||||
|
||||
MogIt.enchants = {
|
||||
{
|
||||
{
|
||||
id = 2564,
|
||||
name = "Agility",
|
||||
},
|
||||
{
|
||||
id = 2646,
|
||||
name = "Agility (2H)",
|
||||
},
|
||||
{
|
||||
id = 1900,
|
||||
name = "Crusader",
|
||||
},
|
||||
{
|
||||
id = 912,
|
||||
name = "Demonslaying",
|
||||
},
|
||||
{
|
||||
id = 803,
|
||||
name = "Fiery Weapon",
|
||||
},
|
||||
{
|
||||
id = 963,
|
||||
name = "Greater Impact (2H)",
|
||||
},
|
||||
{
|
||||
id = 805,
|
||||
name = "Greater Striking",
|
||||
},
|
||||
{
|
||||
id = 2505,
|
||||
name = "Healing power",
|
||||
},
|
||||
{
|
||||
id = 1894,
|
||||
name = "Icy Chill",
|
||||
},
|
||||
{
|
||||
id = 1897,
|
||||
name = "Impact (2H)",
|
||||
},
|
||||
{
|
||||
id = 853,
|
||||
name = "Lesser Beastslayer",
|
||||
},
|
||||
{
|
||||
id = 854,
|
||||
name = "Lesser Elemental Slayer",
|
||||
},
|
||||
{
|
||||
id = 943,
|
||||
name = "Lesser Impact (2H)",
|
||||
},
|
||||
{
|
||||
id = 723,
|
||||
name = "Lesser Intellect (2H)",
|
||||
},
|
||||
{
|
||||
id = 255,
|
||||
name = "Lesser Spirit (2H)",
|
||||
},
|
||||
{
|
||||
id = 241,
|
||||
name = "Lesser Striking",
|
||||
},
|
||||
{
|
||||
id = 1898,
|
||||
name = "Lifestealing",
|
||||
},
|
||||
{
|
||||
id = 1904,
|
||||
name = "Major Intellect (2H)",
|
||||
},
|
||||
{
|
||||
id = 1903,
|
||||
name = "Major Spirit (2H)",
|
||||
},
|
||||
{
|
||||
id = 2568,
|
||||
name = "Mighty Intellect",
|
||||
},
|
||||
{
|
||||
id = 2567,
|
||||
name = "Mighty Spirit",
|
||||
},
|
||||
{
|
||||
id = 249,
|
||||
name = "Minor Beastslayer",
|
||||
},
|
||||
{
|
||||
id = 241,
|
||||
name = "Minor Impact (2H)",
|
||||
},
|
||||
{
|
||||
id = 250,
|
||||
name = "Minor Striking",
|
||||
},
|
||||
{
|
||||
id = 2504,
|
||||
name = "Spellpower",
|
||||
},
|
||||
{
|
||||
id = 2563,
|
||||
name = "Strength",
|
||||
},
|
||||
{
|
||||
id = 943,
|
||||
name = "Striking",
|
||||
},
|
||||
{
|
||||
id = 1896,
|
||||
name = "Superior Impact (2H)",
|
||||
},
|
||||
{
|
||||
id = 1897,
|
||||
name = "Superior Striking",
|
||||
},
|
||||
{
|
||||
id = 1899,
|
||||
name = "Unholy Weapon",
|
||||
},
|
||||
{
|
||||
id = 2443,
|
||||
name = "Winter's Might",
|
||||
},
|
||||
name = "Classic",
|
||||
},
|
||||
{
|
||||
{
|
||||
id = 2675,
|
||||
name = "Battlemaster",
|
||||
},
|
||||
{
|
||||
id = 3225,
|
||||
name = "Executioner",
|
||||
},
|
||||
{
|
||||
id = 2670,
|
||||
name = "Major Agility (2H)",
|
||||
},
|
||||
{
|
||||
id = 3846,
|
||||
name = "Major Healing",
|
||||
},
|
||||
{
|
||||
id = 2666,
|
||||
name = "Major Intellect",
|
||||
},
|
||||
{
|
||||
id = 2669,
|
||||
name = "Major Spellpower",
|
||||
},
|
||||
{
|
||||
id = 963,
|
||||
name = "Major Striking",
|
||||
},
|
||||
{
|
||||
id = 2673,
|
||||
name = "Mongoose",
|
||||
},
|
||||
{
|
||||
id = 2668,
|
||||
name = "Potency",
|
||||
},
|
||||
{
|
||||
id = 2667,
|
||||
name = "Savagery (2H)",
|
||||
},
|
||||
{
|
||||
id = 2672,
|
||||
name = "Soulfrost",
|
||||
},
|
||||
{
|
||||
id = 2674,
|
||||
name = "Spellsurge",
|
||||
},
|
||||
{
|
||||
id = 2671,
|
||||
name = "Sunfire",
|
||||
},
|
||||
name = "The Burning Crusade",
|
||||
},
|
||||
{
|
||||
{
|
||||
id = 3788,
|
||||
name = "Accuracy",
|
||||
},
|
||||
{
|
||||
id = 3789,
|
||||
name = "Beserking",
|
||||
},
|
||||
{
|
||||
id = 3790,
|
||||
name = "Black Magic",
|
||||
},
|
||||
{
|
||||
id = 3869,
|
||||
name = "Blade Ward",
|
||||
},
|
||||
{
|
||||
id = 3870,
|
||||
name = "Blood Draining",
|
||||
},
|
||||
{
|
||||
id = 3273,
|
||||
name = "Deathfrost",
|
||||
},
|
||||
{
|
||||
id = 1103,
|
||||
name = "Exceptional Agility",
|
||||
},
|
||||
{
|
||||
id = 3830,
|
||||
name = "Exceptional Spellpower",
|
||||
},
|
||||
{
|
||||
id = 3844,
|
||||
name = "Exceptional Spirit",
|
||||
},
|
||||
{
|
||||
id = 3251,
|
||||
name = "Giant Slayer",
|
||||
},
|
||||
{
|
||||
id = 3222,
|
||||
name = "Greater Agility",
|
||||
},
|
||||
{
|
||||
id = 1606,
|
||||
name = "Greater Potency",
|
||||
},
|
||||
{
|
||||
id = 3828,
|
||||
name = "Greater Savagery (2H)",
|
||||
},
|
||||
{
|
||||
id = 3854,
|
||||
name = "Greater Spellpower (Staff)",
|
||||
},
|
||||
{
|
||||
id = 3239,
|
||||
name = "Icebreaker",
|
||||
},
|
||||
{
|
||||
id = 3241,
|
||||
name = "Lifeward",
|
||||
},
|
||||
{
|
||||
id = 3827,
|
||||
name = "Massacre (2H)",
|
||||
},
|
||||
{
|
||||
id = 3834,
|
||||
name = "Mighty Spellpower",
|
||||
},
|
||||
{
|
||||
id = 3247,
|
||||
name = "Scourgebane (2H)",
|
||||
},
|
||||
{
|
||||
id = 3855,
|
||||
name = "Spellpower (Staff)",
|
||||
},
|
||||
{
|
||||
id = 3833,
|
||||
name = "Superior Potency",
|
||||
},
|
||||
name = "Wrath of the Lich King",
|
||||
},
|
||||
{
|
||||
{
|
||||
id = 3369,
|
||||
name = "Rune of Cinderglacier",
|
||||
},
|
||||
{
|
||||
id = 3366,
|
||||
name = "Rune of Lichbane",
|
||||
},
|
||||
{
|
||||
id = 3370,
|
||||
name = "Rune of Razorice",
|
||||
},
|
||||
{
|
||||
id = 3595,
|
||||
name = "Rune of Spellbreaking (1H)",
|
||||
},
|
||||
{
|
||||
id = 3367,
|
||||
name = "Rune of Spellshattering (2H)",
|
||||
},
|
||||
{
|
||||
id = 3594,
|
||||
name = "Rune of Swordbreaking (1H)",
|
||||
},
|
||||
{
|
||||
id = 3365,
|
||||
name = "Rune of Swordshattering (2H)",
|
||||
},
|
||||
{
|
||||
id = 3368,
|
||||
name = "Rune of the Fallen Crusader",
|
||||
},
|
||||
{
|
||||
id = 3883,
|
||||
name = "Rune of the Nerubian Carapace (1H)",
|
||||
},
|
||||
{
|
||||
id = 3847,
|
||||
name = "Rune of the Stoneskin Gargoyle (2H)",
|
||||
},
|
||||
name = "Runeforging",
|
||||
},
|
||||
}
|
||||
174
MogIt/Core/Filters/Filters.lua
Normal file
@@ -0,0 +1,174 @@
|
||||
local MogIt,mog = ...;
|
||||
local L = mog.L;
|
||||
|
||||
mog.filters = {};
|
||||
|
||||
function mog:CreateFilter(name,frame)
|
||||
if not name or mog.filters[name] then return end;
|
||||
if frame then
|
||||
frame:SetParent(mog.filt.frame);
|
||||
else
|
||||
frame = CreateFrame("Frame",nil,mog.filt.frame);
|
||||
end
|
||||
frame:Hide();
|
||||
mog.filters[name] = frame;
|
||||
return frame;
|
||||
end
|
||||
|
||||
function mog:GetFilter(name)
|
||||
return mog.filters[name];
|
||||
end
|
||||
|
||||
mog.filt = CreateFrame("Frame","MogItFilters",mog.frame,"ButtonFrameTemplate");
|
||||
mog.filt:Hide();
|
||||
mog.filt:SetPoint("TOPLEFT",mog.frame,"TOPRIGHT");
|
||||
mog.filt:SetSize(200,300);
|
||||
mog.filt:SetClampedToScreen(true);
|
||||
mog.filt:EnableMouse(true);
|
||||
--MogItFiltersCloseButton:SetNormalTexture("Interface\\BUTTONS\\UI-Panel-HideButton-Up");
|
||||
--MogItFiltersCloseButton:SetPushedTexture("Interface\\BUTTONS\\UI-Panel-HideButton-Down");
|
||||
MogItFiltersBg:SetTexture("Interface\\AddOns\\MogIt\\FrameGeneral\\UI-Background-Rock",true);
|
||||
MogItFiltersBg:SetVertexColor(0.8,0.3,0.8);
|
||||
MogItFiltersTitleText:SetText(FILTERS);
|
||||
|
||||
mog.filt.portrait:Hide();
|
||||
mog.filt.portraitFrame:Hide();
|
||||
mog.filt.topLeftCorner:Show();
|
||||
mog.filt.topBorderBar:SetPoint("TOPLEFT", mog.filt.topLeftCorner, "TOPRIGHT", 0, 0);
|
||||
mog.filt.leftBorderBar:SetPoint("TOPLEFT", mog.filt.topLeftCorner, "BOTTOMLEFT", 0, 0);
|
||||
--ButtonFrameTemplate_HidePortrait(mog.filt);
|
||||
|
||||
mog.filt.results = mog.filt:CreateFontString(nil,"ARTWORK","GameFontNormal");
|
||||
mog.filt.results:SetPoint("TOPLEFT",mog.filt,"TOPLEFT",10,-35);
|
||||
mog.filt.results:SetText(L["Results"]..":");
|
||||
|
||||
mog.filt.models = mog.filt:CreateFontString(nil,"ARTWORK","GameFontHighlight");
|
||||
mog.filt.models:SetPoint("LEFT",mog.filt.results,"RIGHT",5,0);
|
||||
|
||||
mog.filt.defaults = CreateFrame("Button","MogItFrameFiltersDefaults",mog.filt,"MagicButtonTemplate");
|
||||
mog.filt.defaults:SetPoint("BOTTOMLEFT",mog.filt,"BOTTOMLEFT",5,5);
|
||||
mog.filt.defaults:SetWidth(100);
|
||||
mog.filt.defaults:SetText(DEFAULTS);
|
||||
mog.filt.defaults:SetScript("OnClick",function(self,btn)
|
||||
if mog.active and mog.active.filters then
|
||||
for k,v in ipairs(mog.active.filters) do
|
||||
if mog.filters[v] and mog.filters[v].Default then
|
||||
mog.filters[v].Default();
|
||||
end
|
||||
end
|
||||
mog:BuildList();
|
||||
end
|
||||
end);
|
||||
|
||||
mog.filt.scroll = CreateFrame("ScrollFrame","MogItFiltersScroll",mog.filt,"UIPanelScrollFrameTemplate");
|
||||
mog.filt.scroll:SetPoint("TOPLEFT",mog.filt.Inset,"TOPLEFT",0,-3);
|
||||
mog.filt.scroll:SetPoint("BOTTOMRIGHT",mog.filt.Inset,"BOTTOMRIGHT",-23,2);
|
||||
mog.filt.scroll:Hide();
|
||||
mog.filt.scroll.ScrollBar = MogItFiltersScrollScrollBar
|
||||
mog.filt.scroll.ScrollBar.top = mog.filt.scroll.ScrollBar:CreateTexture(nil,"ARTWORK");
|
||||
mog.filt.scroll.ScrollBar.top:SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-ScrollBar");
|
||||
mog.filt.scroll.ScrollBar.top:SetSize(24,48);
|
||||
mog.filt.scroll.ScrollBar.top:SetPoint("TOPLEFT",mog.filt.scroll.ScrollBar,"TOPLEFT",-6,19);
|
||||
mog.filt.scroll.ScrollBar.top:SetTexCoord(0,0.45,0,0.2);
|
||||
|
||||
mog.filt.scroll.ScrollBar.bottom = mog.filt.scroll.ScrollBar:CreateTexture(nil,"ARTWORK");
|
||||
mog.filt.scroll.ScrollBar.bottom:SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-ScrollBar");
|
||||
mog.filt.scroll.ScrollBar.bottom:SetSize(24,64);
|
||||
mog.filt.scroll.ScrollBar.bottom:SetPoint("BOTTOMLEFT",mog.filt.scroll.ScrollBar,"BOTTOMLEFT",-6,-17);
|
||||
mog.filt.scroll.ScrollBar.bottom:SetTexCoord(0.515625,0.97,0.1440625,0.4140625);
|
||||
|
||||
mog.filt.scroll.ScrollBar.middle = mog.filt.scroll.ScrollBar:CreateTexture(nil,"ARTWORK");
|
||||
mog.filt.scroll.ScrollBar.middle:SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-ScrollBar");
|
||||
mog.filt.scroll.ScrollBar.middle:SetPoint("TOPLEFT",mog.filt.scroll.ScrollBar.top,"BOTTOMLEFT");
|
||||
mog.filt.scroll.ScrollBar.middle:SetPoint("BOTTOMRIGHT",mog.filt.scroll.ScrollBar.bottom,"TOPRIGHT");
|
||||
mog.filt.scroll.ScrollBar.middle:SetTexCoord(0,0.45,0.1640625,1);
|
||||
|
||||
mog.filt.frame = CreateFrame("Frame","MogItFiltersScrollFrame",mog.filt);
|
||||
mog.filt.scroll:SetScrollChild(mog.filt.frame);
|
||||
mog.filt.frame:SetWidth(180);
|
||||
|
||||
mog.filt.error = mog.filt:CreateFontString(nil,"ARTWORK","GameFontRed");
|
||||
mog.filt.error:SetPoint("TOPLEFT",mog.filt.Inset,"TOPLEFT",7,-5);
|
||||
mog.filt.error:SetPoint("BOTTOMRIGHT",mog.filt.Inset,"BOTTOMRIGHT",-7,5);
|
||||
--mog.filt.error:SetJustifyV("TOP");
|
||||
mog.filt.error:SetText(L["No module is selected"]);
|
||||
|
||||
function mog:FilterUpdate()
|
||||
if not mog.active then
|
||||
mog.filt.scroll:Hide();
|
||||
mog.filt.error:SetText(L["No module is selected"]);
|
||||
mog.filt.error:Show();
|
||||
return;
|
||||
elseif not mog.active.filters then
|
||||
mog.filt.scroll:Hide();
|
||||
mog.filt.error:SetText(L["This module has no filters"]);
|
||||
mog.filt.error:Show();
|
||||
return;
|
||||
end
|
||||
|
||||
mog.filt.scroll:Show();
|
||||
mog.filt.error:Hide();
|
||||
for k,v in pairs(mog.filters) do
|
||||
v:Hide();
|
||||
end
|
||||
|
||||
local height = 20;
|
||||
local last;
|
||||
for k,v in ipairs(mog.active.filters) do
|
||||
local filter = mog.filters[v];
|
||||
if filter and (not filter.slot or (mog.active.active and filter.slot == mog.active.active.label)) then
|
||||
filter:ClearAllPoints();
|
||||
if last then
|
||||
filter:SetPoint("TOPLEFT",last,"BOTTOMLEFT",0,-14);
|
||||
else
|
||||
filter:SetPoint("TOPLEFT",mog.filt.frame,"TOPLEFT",12,-10);
|
||||
end
|
||||
filter:SetPoint("RIGHT",mog.filt.frame,"RIGHT",-19,0);
|
||||
if not filter.bg then
|
||||
filter.bg = mog.filters[v]:CreateTexture(nil,"BACKGROUND");
|
||||
filter.bg:SetPoint("TOPLEFT",mog.filters[v],"TOPLEFT",-5,5);
|
||||
filter.bg:SetPoint("BOTTOMRIGHT",mog.filters[v],"BOTTOMRIGHT",5,-5);
|
||||
filter.bg:SetTexture(0.3,0.3,0.3,0.2);
|
||||
end
|
||||
height = height + filter:GetHeight() + (last and 14 or 0);
|
||||
last = filter;
|
||||
filter:Show();
|
||||
end
|
||||
end
|
||||
mog.filt.frame:SetHeight(height);
|
||||
end
|
||||
|
||||
function mog:CheckFilters(module,value)
|
||||
if module.filters and module.GetFilterArgs then
|
||||
for _,filter in ipairs(module.filters) do
|
||||
local filterObject = mog:GetFilter(filter);
|
||||
if (not filterObject.slot or (module.active and filterObject.slot == module.active.label)) and not filterObject.Filter(module.GetFilterArgs(filter,value)) then
|
||||
return;
|
||||
end
|
||||
end
|
||||
end
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
VENDOR?
|
||||
Valor Points
|
||||
Justice Points
|
||||
Conquest Points
|
||||
Honor Points
|
||||
Tier Tokens
|
||||
--> Tier 1
|
||||
--> Tier 2
|
||||
--> etc
|
||||
Gold
|
||||
Other
|
||||
|
||||
ZONES
|
||||
-- current zone
|
||||
|
||||
NAME
|
||||
|
||||
QUEST/ACHI
|
||||
- complete?
|
||||
--]]
|
||||
20
MogIt/Core/Filters/Filters.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Ui xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.blizzard.com/wow/ui/" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
..\FrameXML\UI.xsd">
|
||||
|
||||
<Script file="Filters.lua"/>
|
||||
|
||||
<Script file="name.lua"/>
|
||||
<Script file="level.lua"/>
|
||||
<Script file="itemLevel.lua"/>
|
||||
<Script file="faction.lua"/>
|
||||
<Script file="class.lua"/>
|
||||
<Script file="source.lua"/>
|
||||
<Script file="slot.lua"/>
|
||||
<Script file="quality.lua"/>
|
||||
<Script file="bind.lua"/>
|
||||
<Script file="hasItem.lua"/>
|
||||
<Script file="chestType.lua"/>
|
||||
<Script file="sheath.lua"/>
|
||||
|
||||
</Ui>
|
||||
80
MogIt/Core/Filters/bind.lua
Normal file
@@ -0,0 +1,80 @@
|
||||
local MogIt,mog = ...;
|
||||
local L = mog.L;
|
||||
|
||||
local f = mog:CreateFilter("bind");
|
||||
local selected;
|
||||
local num;
|
||||
local all;
|
||||
|
||||
f:SetHeight(41);
|
||||
|
||||
f.bind = f:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall");
|
||||
f.bind:SetPoint("TOPLEFT",f,"TOPLEFT",0,0);
|
||||
f.bind:SetPoint("RIGHT",f,"RIGHT",0,0);
|
||||
f.bind:SetText(L["Bind"]..":");
|
||||
f.bind:SetJustifyH("LEFT");
|
||||
|
||||
f.dd = CreateFrame("Frame","MogItFiltersBindDropdown",f,"UIDropDownMenuTemplate");
|
||||
f.dd:SetPoint("TOPLEFT",f.bind,"BOTTOMLEFT",-16,-2);
|
||||
UIDropDownMenu_SetWidth(f.dd,125);
|
||||
UIDropDownMenu_SetButtonWidth(f.dd,140);
|
||||
UIDropDownMenu_JustifyText(f.dd,"LEFT");
|
||||
|
||||
function f.dd.SelectAll(self)
|
||||
num = 0;
|
||||
for k,v in ipairs(L.bind) do
|
||||
selected[k] = all;
|
||||
num = num + (all and 1 or 0);
|
||||
end
|
||||
all = not all;
|
||||
UIDropDownMenu_SetText(f.dd,L["%d selected"]:format(num));
|
||||
ToggleDropDownMenu(1,nil,f.dd);
|
||||
mog:BuildList();
|
||||
end
|
||||
|
||||
function f.dd.Tier1(self)
|
||||
if selected[self.value] and (not self.checked) then
|
||||
num = num - 1;
|
||||
elseif (not selected[self.value]) and self.checked then
|
||||
num = num + 1;
|
||||
end
|
||||
selected[self.value] = self.checked;
|
||||
UIDropDownMenu_SetText(f.dd,L["%d selected"]:format(num));
|
||||
mog:BuildList();
|
||||
end
|
||||
|
||||
function f.dd.initialize(self)
|
||||
local info;
|
||||
info = UIDropDownMenu_CreateInfo();
|
||||
info.text = all and L["Select All"] or L["Select None"];
|
||||
info.func = f.dd.SelectAll;
|
||||
info.notCheckable = true;
|
||||
UIDropDownMenu_AddButton(info);
|
||||
|
||||
for k,v in ipairs(L.bind) do
|
||||
info = UIDropDownMenu_CreateInfo();
|
||||
info.text = v;
|
||||
info.value = k;
|
||||
info.func = f.dd.Tier1;
|
||||
info.keepShownOnClick = true;
|
||||
info.isNotRadio = true;
|
||||
info.checked = selected[k];
|
||||
UIDropDownMenu_AddButton(info);
|
||||
end
|
||||
end
|
||||
|
||||
function f.Filter(bind)
|
||||
return ((not bind) and selected[1]) or selected[bind];
|
||||
end
|
||||
|
||||
function f.Default()
|
||||
selected = {};
|
||||
num = 0;
|
||||
all = nil;
|
||||
for k,v in ipairs(L.bind) do
|
||||
selected[k] = true;
|
||||
num = num + 1;
|
||||
end
|
||||
UIDropDownMenu_SetText(f.dd,L["%d selected"]:format(num));
|
||||
end
|
||||
f.Default();
|
||||
62
MogIt/Core/Filters/chestType.lua
Normal file
@@ -0,0 +1,62 @@
|
||||
local MogIt,mog = ...;
|
||||
local L = mog.L;
|
||||
|
||||
local f = mog:CreateFilter("chestType");
|
||||
local selected;
|
||||
|
||||
f:SetHeight(41);
|
||||
f.slot = "Chest";
|
||||
|
||||
f.chestType = f:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall");
|
||||
f.chestType:SetPoint("TOPLEFT",f,"TOPLEFT",0,0);
|
||||
f.chestType:SetPoint("RIGHT",f,"RIGHT",0,0);
|
||||
f.chestType:SetText(L["Chest type"]..":");
|
||||
f.chestType:SetJustifyH("LEFT");
|
||||
|
||||
local function onClick(self, invType)
|
||||
selected = invType;
|
||||
f.dd:SetText(self.value);
|
||||
mog:BuildList();
|
||||
end
|
||||
|
||||
local labels = {
|
||||
L["Any"],
|
||||
L["Tunic"],
|
||||
L["Robe"],
|
||||
}
|
||||
|
||||
local invTypes = {
|
||||
nil,
|
||||
"INVTYPE_CHEST",
|
||||
"INVTYPE_ROBE",
|
||||
}
|
||||
|
||||
f.dd = mog:CreateDropdown("Frame", f);
|
||||
f.dd:SetPoint("TOPLEFT",f.chestType,"BOTTOMLEFT",-16,-2);
|
||||
f.dd:SetWidth(125);
|
||||
f.dd:SetButtonWidth(140);
|
||||
f.dd:JustifyText("LEFT");
|
||||
f.dd.initialize = function(self)
|
||||
for i,v in ipairs(labels) do
|
||||
local info = UIDropDownMenu_CreateInfo();
|
||||
info.text = v;
|
||||
info.func = onClick;
|
||||
info.arg1 = invTypes[i]
|
||||
info.checked = invTypes[i] == selected;
|
||||
UIDropDownMenu_AddButton(info);
|
||||
end
|
||||
end
|
||||
|
||||
function f.Filter(item)
|
||||
if not selected then
|
||||
return true;
|
||||
end
|
||||
local item = mog:GetItemInfo(item, "BuildList");
|
||||
return not item or selected == item.invType;
|
||||
end
|
||||
|
||||
function f.Default()
|
||||
selected = nil;
|
||||
f.dd:SetText(L["Any"]);
|
||||
end
|
||||
f.Default();
|
||||
98
MogIt/Core/Filters/class.lua
Normal file
@@ -0,0 +1,98 @@
|
||||
local MogIt,mog = ...;
|
||||
local L = mog.L;
|
||||
|
||||
local f = mog:CreateFilter("class");
|
||||
local coords = CLASS_ICON_TCOORDS;
|
||||
local colours = RAID_CLASS_COLORS;
|
||||
local class;
|
||||
local selected;
|
||||
local num;
|
||||
local all;
|
||||
|
||||
f:SetHeight(41);
|
||||
|
||||
f.class = f:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall");
|
||||
f.class:SetPoint("TOPLEFT",f,"TOPLEFT",0,0);
|
||||
f.class:SetPoint("RIGHT",f,"RIGHT",0,0);
|
||||
f.class:SetText(CLASS..":");
|
||||
f.class:SetJustifyH("LEFT");
|
||||
|
||||
f.dd = CreateFrame("Frame","MogItFiltersClassDropdown",f,"UIDropDownMenuTemplate");
|
||||
f.dd:SetPoint("TOPLEFT",f.class,"BOTTOMLEFT",-16,-2);
|
||||
UIDropDownMenu_SetWidth(f.dd,125);
|
||||
UIDropDownMenu_SetButtonWidth(f.dd,140);
|
||||
UIDropDownMenu_JustifyText(f.dd,"LEFT");
|
||||
|
||||
function f.dd.SelectAll(self)
|
||||
num = 0;
|
||||
class = 0;
|
||||
for k,v in pairs(LOCALIZED_CLASS_NAMES_MALE) do
|
||||
selected[k] = all;
|
||||
num = num + (all and 1 or 0);
|
||||
class = class + (all and L.classBits[k] or 0);
|
||||
end
|
||||
all = not all;
|
||||
UIDropDownMenu_SetText(f.dd,L["%d selected"]:format(num));
|
||||
ToggleDropDownMenu(1,nil,f.dd);
|
||||
mog:BuildList();
|
||||
end
|
||||
|
||||
function f.dd.Tier1(self)
|
||||
if selected[self.value] and (not self.checked) then
|
||||
class = class - L.classBits[self.value];
|
||||
num = num - 1;
|
||||
elseif (not selected[self.value]) and self.checked then
|
||||
class = class + L.classBits[self.value];
|
||||
num = num + 1;
|
||||
end
|
||||
selected[self.value] = self.checked;
|
||||
UIDropDownMenu_SetText(f.dd,L["%d selected"]:format(num));
|
||||
mog:BuildList();
|
||||
end
|
||||
|
||||
function f.dd.initialize(self)
|
||||
local info;
|
||||
info = UIDropDownMenu_CreateInfo();
|
||||
info.text = all and L["Select All"] or L["Select None"];
|
||||
info.func = f.dd.SelectAll;
|
||||
info.notCheckable = true;
|
||||
UIDropDownMenu_AddButton(info);
|
||||
|
||||
for k,v in pairs(LOCALIZED_CLASS_NAMES_MALE) do
|
||||
info = UIDropDownMenu_CreateInfo();
|
||||
info.text = v;
|
||||
info.value = k;
|
||||
info.colorCode = string.format("\124cff%.2x%.2x%.2x",colours[k].r*255,colours[k].g*255,colours[k].b*255);
|
||||
info.func = f.dd.Tier1;
|
||||
info.keepShownOnClick = true;
|
||||
info.isNotRadio = true;
|
||||
info.checked = selected[k];
|
||||
info.icon = "Interface\\Glues\\CharacterCreate\\UI-CharacterCreate-Classes";
|
||||
info.tCoordLeft = coords[k][1];
|
||||
info.tCoordRight = coords[k][2];
|
||||
info.tCoordTop = coords[k][3];
|
||||
info.tCoordBottom = coords[k][4];
|
||||
UIDropDownMenu_AddButton(info);
|
||||
end
|
||||
end
|
||||
|
||||
function f.Filter(input)
|
||||
return (not input) or (bit.band(class,input)>0);
|
||||
end
|
||||
|
||||
function f.Default()
|
||||
--[[
|
||||
class = L.classBits[select(2,UnitClass("PLAYER"))];
|
||||
selected = {[select(2,UnitClass("PLAYER"))] = true};
|
||||
num = 1;
|
||||
all = true;
|
||||
UIDropDownMenu_SetText(f.dd,L["%d selected"]:format(num));
|
||||
--]]
|
||||
class = 1535
|
||||
selected = {}
|
||||
for i=1,10 do selected[CLASS_SORT_ORDER[i]] = true end
|
||||
num = 10;
|
||||
all = false;
|
||||
UIDropDownMenu_SetText(f.dd,L["%d selected"]:format(num));
|
||||
end
|
||||
f.Default();
|
||||
59
MogIt/Core/Filters/faction.lua
Normal file
@@ -0,0 +1,59 @@
|
||||
local MogIt,mog = ...;
|
||||
local L = mog.L;
|
||||
|
||||
local f = mog:CreateFilter("faction");
|
||||
local alliance;
|
||||
local horde;
|
||||
|
||||
local factions = {
|
||||
[1] = "Alliance",
|
||||
[2] = "Horde",
|
||||
}
|
||||
|
||||
-- Disabled default faction check, with faction check enabled, these need to be false.
|
||||
local settings = {
|
||||
Alliance = true,
|
||||
Horde = true,
|
||||
}
|
||||
|
||||
f:SetHeight(69);
|
||||
|
||||
f.faction = f:CreateFontString(nil,nil,"GameFontHighlightSmall");
|
||||
f.faction:SetPoint("TOPLEFT");
|
||||
f.faction:SetPoint("RIGHT");
|
||||
f.faction:SetText(L["Faction"]..":");
|
||||
f.faction:SetJustifyH("LEFT");
|
||||
|
||||
local function onClick(self)
|
||||
settings[self.value] = self:GetChecked() == 1;
|
||||
mog:BuildList();
|
||||
end
|
||||
|
||||
f.Alliance = CreateFrame("CheckButton","MogItCoreFiltersFactionAlliance",f,"UICheckButtonTemplate");
|
||||
f.Alliance.text = MogItCoreFiltersFactionAllianceText
|
||||
f.Alliance.text:SetText(FACTION_ALLIANCE);
|
||||
f.Alliance:SetPoint("TOPLEFT",f.faction,"BOTTOMLEFT");
|
||||
f.Alliance:SetScript("OnClick",onClick);
|
||||
f.Alliance.value = "Alliance";
|
||||
|
||||
f.Horde = CreateFrame("CheckButton","MogItCoreFiltersFactionHorde",f,"UICheckButtonTemplate");
|
||||
f.Horde.text = MogItCoreFiltersFactionHordeText
|
||||
f.Horde.text:SetText(FACTION_HORDE);
|
||||
f.Horde:SetPoint("TOPLEFT",f.Alliance,"BOTTOMLEFT");
|
||||
f.Horde:SetScript("OnClick",onClick);
|
||||
f.Horde.value = "Horde";
|
||||
|
||||
function f.Filter(faction)
|
||||
return (not faction) or (settings[factions[faction]]);
|
||||
end
|
||||
|
||||
function f.Default()
|
||||
-- for i, faction in ipairs(factions) do
|
||||
-- local value = UnitFactionGroup("PLAYER") == faction;
|
||||
-- settings[faction] = value;
|
||||
-- f[faction]:SetChecked(value);
|
||||
-- end
|
||||
f.Alliance:SetChecked(true);
|
||||
f.Horde:SetChecked(true);
|
||||
end
|
||||
f.Default();
|
||||
32
MogIt/Core/Filters/hasItem.lua
Normal file
@@ -0,0 +1,32 @@
|
||||
local MogIt,mog = ...;
|
||||
local L = mog.L;
|
||||
|
||||
local f = mog:CreateFilter("hasItem");
|
||||
local enabled;
|
||||
|
||||
f:SetHeight(41);
|
||||
|
||||
f.label = f:CreateFontString(nil,nil,"GameFontHighlightSmall");
|
||||
f.label:SetPoint("TOPLEFT");
|
||||
f.label:SetPoint("RIGHT");
|
||||
f.label:SetText(L["Owned items"]..":");
|
||||
f.label:SetJustifyH("LEFT");
|
||||
|
||||
f.hasItem = CreateFrame("CheckButton","MogItCoreFiltersHasItem",f,"UICheckButtonTemplate");
|
||||
f.hasItem.text = MogItCoreFiltersHasItemText
|
||||
f.hasItem.text:SetText(L["Only items you own"]);
|
||||
f.hasItem:SetPoint("TOPLEFT",f.label,"BOTTOMLEFT");
|
||||
f.hasItem:SetScript("OnClick",function(self)
|
||||
enabled = self:GetChecked() == 1;
|
||||
mog:BuildList();
|
||||
end);
|
||||
|
||||
function f.Filter(itemID)
|
||||
return not enabled or mog:HasItem(itemID);
|
||||
end
|
||||
|
||||
function f.Default()
|
||||
f.hasItem:SetChecked(false);
|
||||
enabled = false;
|
||||
end
|
||||
f.Default();
|
||||
66
MogIt/Core/Filters/itemLevel.lua
Normal file
@@ -0,0 +1,66 @@
|
||||
local MogIt,mog = ...;
|
||||
local L = mog.L;
|
||||
|
||||
local f = mog:CreateFilter("itemLevel");
|
||||
local minlvl;
|
||||
local maxlvl;
|
||||
|
||||
f:SetHeight(35);
|
||||
|
||||
f.label = f:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall");
|
||||
f.label:SetPoint("TOPLEFT",f,"TOPLEFT",0,0);
|
||||
f.label:SetPoint("RIGHT",f,"RIGHT",0,0);
|
||||
f.label:SetText("Item level"..":");
|
||||
f.label:SetJustifyH("LEFT");
|
||||
|
||||
f.min = CreateFrame("EditBox","MogItFiltersItemLevelMin",f,"InputBoxTemplate");
|
||||
f.min:SetSize(32,16);
|
||||
f.min:SetPoint("TOPLEFT",f.label,"BOTTOMLEFT",8,-5);
|
||||
f.min:SetNumeric(true);
|
||||
f.min:SetMaxLetters(3);
|
||||
f.min:SetAutoFocus(false);
|
||||
f.min:SetScript("OnEnterPressed",EditBox_ClearFocus);
|
||||
f.min:SetScript("OnTabPressed",function(self)
|
||||
f.max:SetFocus();
|
||||
end);
|
||||
f.min:SetScript("OnTextChanged",function(self,user)
|
||||
if user then
|
||||
minlvl = self:GetNumber() or 0;
|
||||
mog:BuildList();
|
||||
end
|
||||
end);
|
||||
|
||||
f.dash = f:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall");
|
||||
f.dash:SetPoint("LEFT",f.min,"RIGHT",0,1);
|
||||
f.dash:SetText("-");
|
||||
|
||||
f.max = CreateFrame("EditBox","MogItFiltersItemLevelMax",f,"InputBoxTemplate");
|
||||
f.max:SetSize(32,16);
|
||||
f.max:SetPoint("LEFT",f.min,"RIGHT",12,0);
|
||||
f.max:SetNumeric(true);
|
||||
f.max:SetMaxLetters(3);
|
||||
f.max:SetAutoFocus(false);
|
||||
f.max:SetScript("OnEnterPressed",EditBox_ClearFocus);
|
||||
f.max:SetScript("OnTabPressed",function(self)
|
||||
f.min:SetFocus();
|
||||
end);
|
||||
|
||||
f.max:SetScript("OnTextChanged",function(self,user)
|
||||
if user then
|
||||
maxlvl = self:GetNumber() or 0;
|
||||
mog:BuildList();
|
||||
end
|
||||
end);
|
||||
|
||||
function f.Filter(lvl)
|
||||
local lvl = lvl or 0;
|
||||
return (minlvl <= 0 or lvl >= minlvl) and (maxlvl <= 0 or lvl <= maxlvl);
|
||||
end
|
||||
|
||||
function f.Default()
|
||||
minlvl = 0;
|
||||
f.min:SetNumber(minlvl);
|
||||
maxlvl = 0;
|
||||
f.max:SetNumber(maxlvl);
|
||||
end
|
||||
f.Default();
|
||||
98
MogIt/Core/Filters/level.lua
Normal file
@@ -0,0 +1,98 @@
|
||||
local MogIt,mog = ...;
|
||||
local L = mog.L;
|
||||
|
||||
local f = mog:CreateFilter("level");
|
||||
local minlvl;
|
||||
local maxlvl;
|
||||
|
||||
f:SetHeight(35);
|
||||
|
||||
f.label = f:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall");
|
||||
f.label:SetPoint("TOPLEFT",f,"TOPLEFT",0,0);
|
||||
f.label:SetPoint("RIGHT",f,"RIGHT",0,0);
|
||||
f.label:SetText(LEVEL_RANGE..":");
|
||||
f.label:SetJustifyH("LEFT");
|
||||
|
||||
f.min = CreateFrame("EditBox","MogItFiltersLevelMin",f,"InputBoxTemplate");
|
||||
f.min:SetSize(25,16);
|
||||
f.min:SetPoint("TOPLEFT",f.label,"BOTTOMLEFT",8,-5);
|
||||
f.min:SetNumeric(true);
|
||||
f.min:SetMaxLetters(2);
|
||||
f.min:SetAutoFocus(false);
|
||||
f.min:SetScript("OnEnterPressed",EditBox_ClearFocus);
|
||||
f.min:SetScript("OnTabPressed",function(self)
|
||||
f.max:SetFocus();
|
||||
end);
|
||||
f.min:SetScript("OnTextChanged",function(self,user)
|
||||
if user then
|
||||
minlvl = self:GetNumber() or 0;
|
||||
mog:BuildList();
|
||||
end
|
||||
end);
|
||||
|
||||
f.dash = f:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall");
|
||||
f.dash:SetPoint("LEFT",f.min,"RIGHT",0,1);
|
||||
f.dash:SetText("-");
|
||||
|
||||
f.max = CreateFrame("EditBox","MogItFiltersLevelMax",f,"InputBoxTemplate");
|
||||
f.max:SetSize(25,16);
|
||||
f.max:SetPoint("LEFT",f.min,"RIGHT",12,0);
|
||||
f.max:SetNumeric(true);
|
||||
f.max:SetMaxLetters(2);
|
||||
f.max:SetAutoFocus(false);
|
||||
f.max:SetScript("OnEnterPressed",EditBox_ClearFocus);
|
||||
f.max:SetScript("OnTabPressed",function(self)
|
||||
f.min:SetFocus();
|
||||
end);
|
||||
f.max:SetScript("OnTextChanged",function(self,user)
|
||||
if user then
|
||||
maxlvl = self:GetNumber() or PLAYER_MAX_LEVEL;
|
||||
mog:BuildList();
|
||||
end
|
||||
end);
|
||||
|
||||
function f.Filter(lvl)
|
||||
lvl = lvl or 0;
|
||||
return (lvl >= minlvl) and (lvl <= maxlvl);
|
||||
end
|
||||
|
||||
function f.Default()
|
||||
minlvl = 0;
|
||||
f.min:SetNumber(minlvl);
|
||||
maxlvl = UnitLevel("PLAYER");
|
||||
f.max:SetNumber(maxlvl);
|
||||
end
|
||||
f.Default();
|
||||
|
||||
|
||||
--[[
|
||||
f.min:SetScript("OnEnterPressed",function(self)
|
||||
self:ClearFocus();
|
||||
minlvl = self:GetNumber() or 0;
|
||||
mog:BuildList();
|
||||
end);
|
||||
f.min:SetScript("OnEscapePressed",function(self)
|
||||
self:ClearFocus();
|
||||
self:SetNumber(minlvl);
|
||||
end);
|
||||
f.min:SetScript("OnTabPressed",function(self)
|
||||
f.max:SetFocus();
|
||||
minlvl = self:GetNumber() or 0;
|
||||
mog:BuildList();
|
||||
end);
|
||||
|
||||
f.max:SetScript("OnEnterPressed",function(self)
|
||||
self:ClearFocus();
|
||||
maxlvl = self:GetNumber() or MAX_PLAYER_LEVEL;
|
||||
mog:BuildList();
|
||||
end);
|
||||
f.max:SetScript("OnEscapePressed",function(self)
|
||||
self:ClearFocus();
|
||||
self:SetNumber(maxlvl);
|
||||
end);
|
||||
f.max:SetScript("OnTabPressed",function(self)
|
||||
f.min:SetFocus();
|
||||
maxlvl = self:GetNumber() or MAX_PLAYER_LEVEL;
|
||||
mog:BuildList();
|
||||
end);
|
||||
--]]
|
||||
45
MogIt/Core/Filters/name.lua
Normal file
@@ -0,0 +1,45 @@
|
||||
local MogIt,mog = ...;
|
||||
local L = mog.L;
|
||||
|
||||
local f = mog:CreateFilter("name");
|
||||
local name;
|
||||
|
||||
f:SetHeight(35);
|
||||
|
||||
f.label = f:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall");
|
||||
f.label:SetPoint("TOPLEFT",f,"TOPLEFT",0,0);
|
||||
f.label:SetPoint("RIGHT",f,"RIGHT",0,0);
|
||||
f.label:SetText(NAME..":");
|
||||
f.label:SetJustifyH("LEFT");
|
||||
|
||||
f.edit = CreateFrame("EditBox","MogItFiltersName",f,"SearchBoxTemplate");
|
||||
f.edit:SetHeight(16);
|
||||
f.edit:SetPoint("TOPLEFT",f.label,"BOTTOMLEFT",8,-5);
|
||||
f.edit:SetPoint("RIGHT",f.label,"RIGHT",-2,0);
|
||||
f.edit:SetAutoFocus(false);
|
||||
--[[f.edit:SetScript("OnFocusGained",function(self)
|
||||
|
||||
end);--]]
|
||||
f.edit:SetScript("OnEnterPressed",EditBox_ClearFocus);
|
||||
f.edit:SetScript("OnTextChanged",function(self,user)
|
||||
if user then
|
||||
name = self:GetText() or "";
|
||||
name = name:lower();
|
||||
mog:BuildList();
|
||||
end
|
||||
end);
|
||||
function f.edit.clearFunc(self)
|
||||
name = "";
|
||||
mog:BuildList();
|
||||
end
|
||||
|
||||
function f.Filter(item)
|
||||
item = item or "";
|
||||
return (name == "") or (item:lower():find(name,nil,true));
|
||||
end
|
||||
|
||||
function f.Default()
|
||||
name = "";
|
||||
f.edit:SetText(name);
|
||||
end
|
||||
f.Default();
|
||||
82
MogIt/Core/Filters/quality.lua
Normal file
@@ -0,0 +1,82 @@
|
||||
local MogIt,mog = ...;
|
||||
local L = mog.L;
|
||||
|
||||
local f = mog:CreateFilter("quality");
|
||||
local colours = ITEM_QUALITY_COLORS;
|
||||
local selected;
|
||||
local num;
|
||||
local all;
|
||||
|
||||
f:SetHeight(41);
|
||||
|
||||
f.quality = f:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall");
|
||||
f.quality:SetPoint("TOPLEFT",f,"TOPLEFT",0,0);
|
||||
f.quality:SetPoint("RIGHT",f,"RIGHT",0,0);
|
||||
f.quality:SetText(QUALITY..":");
|
||||
f.quality:SetJustifyH("LEFT");
|
||||
|
||||
f.dd = CreateFrame("Frame","MogItFiltersQualityDropdown",f,"UIDropDownMenuTemplate");
|
||||
f.dd:SetPoint("TOPLEFT",f.quality,"BOTTOMLEFT",-16,-2);
|
||||
UIDropDownMenu_SetWidth(f.dd,125);
|
||||
UIDropDownMenu_SetButtonWidth(f.dd,140);
|
||||
UIDropDownMenu_JustifyText(f.dd,"LEFT");
|
||||
|
||||
function f.dd.SelectAll(self)
|
||||
num = 0;
|
||||
for k,v in ipairs(L.quality) do
|
||||
selected[v] = all;
|
||||
num = num + (all and 1 or 0);
|
||||
end
|
||||
all = not all;
|
||||
UIDropDownMenu_SetText(f.dd,L["%d selected"]:format(num));
|
||||
ToggleDropDownMenu(1,nil,f.dd);
|
||||
mog:BuildList();
|
||||
end
|
||||
|
||||
function f.dd.Tier1(self)
|
||||
if selected[self.value] and (not self.checked) then
|
||||
num = num - 1;
|
||||
elseif (not selected[self.value]) and self.checked then
|
||||
num = num + 1;
|
||||
end
|
||||
selected[self.value] = self.checked;
|
||||
UIDropDownMenu_SetText(f.dd,L["%d selected"]:format(num));
|
||||
mog:BuildList();
|
||||
end
|
||||
|
||||
function f.dd.initialize(self)
|
||||
local info;
|
||||
info = UIDropDownMenu_CreateInfo();
|
||||
info.text = all and L["Select All"] or L["Select None"];
|
||||
info.func = f.dd.SelectAll;
|
||||
info.notCheckable = true;
|
||||
UIDropDownMenu_AddButton(info);
|
||||
|
||||
for i,v in ipairs(L.quality) do
|
||||
info = UIDropDownMenu_CreateInfo();
|
||||
info.text = _G["ITEM_QUALITY"..v.."_DESC"];
|
||||
info.value = v;
|
||||
info.colorCode = colours[v].hex;
|
||||
info.func = f.dd.Tier1;
|
||||
info.keepShownOnClick = true;
|
||||
info.isNotRadio = true;
|
||||
info.checked = selected[v];
|
||||
UIDropDownMenu_AddButton(info);
|
||||
end
|
||||
end
|
||||
|
||||
function f.Filter(qual)
|
||||
return (not qual) or selected[qual];
|
||||
end
|
||||
|
||||
function f.Default()
|
||||
selected = {};
|
||||
num = 0;
|
||||
all = nil;
|
||||
for i,v in ipairs(L.quality) do
|
||||
selected[v] = true;
|
||||
num = num + 1;
|
||||
end
|
||||
UIDropDownMenu_SetText(f.dd,L["%d selected"]:format(num));
|
||||
end
|
||||
f.Default();
|
||||
83
MogIt/Core/Filters/sheath.lua
Normal file
@@ -0,0 +1,83 @@
|
||||
local MogIt,mog = ...;
|
||||
local L = mog.L;
|
||||
|
||||
local f = mog:CreateFilter("sheath");
|
||||
local selected;
|
||||
local num;
|
||||
local all;
|
||||
|
||||
f:SetHeight(41);
|
||||
|
||||
--f.slot = "Sword";
|
||||
--f.slot = "Axe";
|
||||
|
||||
f.sheath = f:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall");
|
||||
f.sheath:SetPoint("TOPLEFT",f,"TOPLEFT",0,0);
|
||||
f.sheath:SetPoint("RIGHT",f,"RIGHT",0,0);
|
||||
f.sheath:SetText(L["Sheath type"]..":");
|
||||
f.sheath:SetJustifyH("LEFT");
|
||||
|
||||
f.dd = mog:CreateDropdown("Frame", f);
|
||||
f.dd:SetPoint("TOPLEFT",f.sheath,"BOTTOMLEFT",-16,-2);
|
||||
f.dd:SetWidth(125);
|
||||
f.dd:SetButtonWidth(140);
|
||||
f.dd:JustifyText("LEFT");
|
||||
|
||||
function f.dd.SelectAll(self)
|
||||
num = 0;
|
||||
for k,v in ipairs(L.sheath) do
|
||||
selected[k] = all;
|
||||
num = num + (all and 1 or 0);
|
||||
end
|
||||
all = not all;
|
||||
UIDropDownMenu_SetText(f.dd,L["%d selected"]:format(num));
|
||||
ToggleDropDownMenu(1,nil,f.dd);
|
||||
mog:BuildList();
|
||||
end
|
||||
|
||||
function f.dd.Tier1(self)
|
||||
if selected[self.value] and (not self.checked) then
|
||||
num = num - 1;
|
||||
elseif (not selected[self.value]) and self.checked then
|
||||
num = num + 1;
|
||||
end
|
||||
selected[self.value] = self.checked;
|
||||
UIDropDownMenu_SetText(f.dd,L["%d selected"]:format(num));
|
||||
mog:BuildList();
|
||||
end
|
||||
|
||||
function f.dd.initialize(self)
|
||||
local info;
|
||||
info = UIDropDownMenu_CreateInfo();
|
||||
info.text = all and L["Select All"] or L["Select None"];
|
||||
info.func = f.dd.SelectAll;
|
||||
info.notCheckable = true;
|
||||
UIDropDownMenu_AddButton(info);
|
||||
|
||||
for k,v in ipairs(L.sheath) do
|
||||
info = UIDropDownMenu_CreateInfo();
|
||||
info.text = v;
|
||||
info.value = k;
|
||||
info.func = f.dd.Tier1;
|
||||
info.keepShownOnClick = true;
|
||||
info.isNotRadio = true;
|
||||
info.checked = selected[k];
|
||||
UIDropDownMenu_AddButton(info);
|
||||
end
|
||||
end
|
||||
|
||||
function f.Filter(sheath)
|
||||
return (not sheath) or selected[sheath];
|
||||
end
|
||||
|
||||
function f.Default()
|
||||
selected = {};
|
||||
num = 0;
|
||||
all = nil;
|
||||
for k,v in ipairs(L.sheath) do
|
||||
selected[k] = true;
|
||||
num = num + 1;
|
||||
end
|
||||
UIDropDownMenu_SetText(f.dd,L["%d selected"]:format(num));
|
||||
end
|
||||
f.Default();
|
||||
80
MogIt/Core/Filters/slot.lua
Normal file
@@ -0,0 +1,80 @@
|
||||
local MogIt,mog = ...;
|
||||
local L = mog.L;
|
||||
|
||||
local f = mog:CreateFilter("slot");
|
||||
local selected;
|
||||
local num;
|
||||
local all;
|
||||
|
||||
f:SetHeight(41);
|
||||
|
||||
local slotLabel = f:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall");
|
||||
slotLabel:SetPoint("TOPLEFT",f,"TOPLEFT",0,0);
|
||||
slotLabel:SetPoint("RIGHT",f,"RIGHT",0,0);
|
||||
slotLabel:SetText("Slots:");
|
||||
slotLabel:SetJustifyH("LEFT");
|
||||
|
||||
f.dd = mog:CreateDropdown("Frame",f);
|
||||
f.dd:SetPoint("TOPLEFT",slotLabel,"BOTTOMLEFT",-16,-2);
|
||||
f.dd:SetWidth(125);
|
||||
f.dd:SetButtonWidth(140);
|
||||
f.dd:JustifyText("LEFT");
|
||||
|
||||
function f.dd.SelectAll(self)
|
||||
num = 0;
|
||||
for k,v in ipairs(L.slots) do
|
||||
selected[k] = all;
|
||||
num = num + (all and 1 or 0);
|
||||
end
|
||||
all = not all;
|
||||
UIDropDownMenu_SetText(f.dd,L["%d selected"]:format(num));
|
||||
ToggleDropDownMenu(1,nil,f.dd);
|
||||
mog:BuildList();
|
||||
end
|
||||
|
||||
function f.dd.Tier1(self)
|
||||
if selected[self.value] and (not self.checked) then
|
||||
num = num - 1;
|
||||
elseif (not selected[self.value]) and self.checked then
|
||||
num = num + 1;
|
||||
end
|
||||
selected[self.value] = self.checked;
|
||||
UIDropDownMenu_SetText(f.dd,L["%d selected"]:format(num));
|
||||
mog:BuildList();
|
||||
end
|
||||
|
||||
function f.dd.initialize(self)
|
||||
local info;
|
||||
info = UIDropDownMenu_CreateInfo();
|
||||
info.text = all and L["Select All"] or L["Select None"];
|
||||
info.func = f.dd.SelectAll;
|
||||
info.notCheckable = true;
|
||||
UIDropDownMenu_AddButton(info);
|
||||
|
||||
for k,v in ipairs(L.slots) do
|
||||
info = UIDropDownMenu_CreateInfo();
|
||||
info.text = v;
|
||||
info.value = k;
|
||||
info.func = f.dd.Tier1;
|
||||
info.keepShownOnClick = true;
|
||||
info.isNotRadio = true;
|
||||
info.checked = selected[k];
|
||||
UIDropDownMenu_AddButton(info);
|
||||
end
|
||||
end
|
||||
|
||||
function f.Filter(slot)
|
||||
return (not slot) or selected[slot];
|
||||
end
|
||||
|
||||
function f.Default()
|
||||
selected = {};
|
||||
num = 0;
|
||||
all = nil;
|
||||
for k,v in ipairs(L.slots) do
|
||||
selected[k] = true;
|
||||
num = num + 1;
|
||||
end
|
||||
UIDropDownMenu_SetText(f.dd,L["%d selected"]:format(num));
|
||||
end
|
||||
f.Default();
|
||||
129
MogIt/Core/Filters/source.lua
Normal file
@@ -0,0 +1,129 @@
|
||||
local MogIt,mog = ...;
|
||||
local L = mog.L;
|
||||
|
||||
local f = mog:CreateFilter("source");
|
||||
local selected;
|
||||
local sub;
|
||||
local num;
|
||||
local all;
|
||||
|
||||
f:SetHeight(41);
|
||||
|
||||
f.source = f:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall");
|
||||
f.source:SetPoint("TOPLEFT",f,"TOPLEFT",0,0);
|
||||
f.source:SetPoint("RIGHT",f,"RIGHT",0,0);
|
||||
f.source:SetText(L["Source"]..":");
|
||||
f.source:SetJustifyH("LEFT");
|
||||
|
||||
f.dd = CreateFrame("Frame","MogItFiltersSourceDropdown",f,"UIDropDownMenuTemplate");
|
||||
f.dd:SetPoint("TOPLEFT",f.source,"BOTTOMLEFT",-16,-2);
|
||||
UIDropDownMenu_SetWidth(f.dd,125);
|
||||
UIDropDownMenu_SetButtonWidth(f.dd,140);
|
||||
UIDropDownMenu_JustifyText(f.dd,"LEFT");
|
||||
|
||||
function f.dd.SelectAll(self)
|
||||
num = 0;
|
||||
for k,v in ipairs(L.source) do
|
||||
selected[k] = all;
|
||||
num = num + (all and 1 or 0);
|
||||
end
|
||||
all = not all;
|
||||
UIDropDownMenu_SetText(f.dd,L["%d selected"]:format(num));
|
||||
ToggleDropDownMenu(1,nil,f.dd);
|
||||
mog:BuildList();
|
||||
end
|
||||
|
||||
function f.dd.Tier1(self)
|
||||
if selected[self.value] and (not self.checked) then
|
||||
num = num - 1;
|
||||
elseif (not selected[self.value]) and self.checked then
|
||||
num = num + 1;
|
||||
end
|
||||
selected[self.value] = self.checked;
|
||||
UIDropDownMenu_SetText(f.dd,L["%d selected"]:format(num));
|
||||
mog:BuildList();
|
||||
end
|
||||
|
||||
function f.dd.Tier2(self)
|
||||
sub[self.arg1][self.value] = self.checked;
|
||||
if selected[self.arg1] then
|
||||
mog:BuildList();
|
||||
end
|
||||
end
|
||||
|
||||
function f.dd.initialize(self,tier)
|
||||
local info;
|
||||
if tier == 1 then
|
||||
info = UIDropDownMenu_CreateInfo();
|
||||
info.text = all and L["Select All"] or L["Select None"];
|
||||
info.func = f.dd.SelectAll;
|
||||
info.notCheckable = true;
|
||||
UIDropDownMenu_AddButton(info);
|
||||
|
||||
for k,v in ipairs(L.source) do
|
||||
info = UIDropDownMenu_CreateInfo();
|
||||
info.text = v;
|
||||
info.value = k;
|
||||
info.func = f.dd.Tier1;
|
||||
info.keepShownOnClick = true;
|
||||
info.isNotRadio = true;
|
||||
info.checked = selected[k];
|
||||
info.hasArrow = sub[k] and true;
|
||||
UIDropDownMenu_AddButton(info);
|
||||
end
|
||||
elseif tier == 2 then
|
||||
local parent = UIDROPDOWNMENU_MENU_VALUE;
|
||||
if parent == 1 then
|
||||
for k,v in ipairs(L.difficulties) do
|
||||
info = UIDropDownMenu_CreateInfo();
|
||||
info.text = v;
|
||||
info.value = k;
|
||||
info.func = f.dd.Tier2;
|
||||
info.keepShownOnClick = true;
|
||||
info.isNotRadio = true;
|
||||
info.checked = sub[parent][k];
|
||||
info.arg1 = parent;
|
||||
UIDropDownMenu_AddButton(info,tier);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function f.Filter(src1,sub1)
|
||||
if not src1 then
|
||||
return true;
|
||||
elseif selected[src1] then
|
||||
if src1 == 1 then
|
||||
if not sub1 then
|
||||
return sub[1][8];
|
||||
elseif sub1 == 7 then
|
||||
return sub[1][3] or sub[1][5];
|
||||
elseif sub1 == 8 then
|
||||
return sub[1][4] or sub[1][6];
|
||||
elseif sub1 == 9 then
|
||||
return sub[1][7];
|
||||
else
|
||||
return sub[1][sub1];
|
||||
end
|
||||
end
|
||||
return true;
|
||||
end
|
||||
end
|
||||
|
||||
function f.Default()
|
||||
selected = {};
|
||||
sub = {
|
||||
[1] = {},
|
||||
};
|
||||
num = 0;
|
||||
all = nil;
|
||||
for k,v in ipairs(L.source) do
|
||||
selected[k] = true;
|
||||
num = num + 1;
|
||||
end
|
||||
for k,v in ipairs(L.difficulties) do
|
||||
sub[1][k] = true;
|
||||
end
|
||||
UIDropDownMenu_SetText(f.dd,L["%d selected"]:format(num));
|
||||
end
|
||||
f.Default();
|
||||
914
MogIt/Core/GUI.lua
Normal file
@@ -0,0 +1,914 @@
|
||||
local MogIt,mog = ...;
|
||||
local L = mog.L;
|
||||
|
||||
local useModel = {
|
||||
[0] = TARGET,
|
||||
[1] = PLAYER,
|
||||
}
|
||||
|
||||
local myuseModel = UnitIsPlayer("PLAYER")
|
||||
mog.playeruseModel = myuseModel;
|
||||
mog.displayuseModel = myuseModel
|
||||
|
||||
local ModelFramePrototype = CreateFrame("Button")
|
||||
local ModelFrame_MT = {__index = ModelFramePrototype}
|
||||
|
||||
--// mog.frame
|
||||
mog.frame:SetPoint("CENTER");
|
||||
mog.frame:SetSize(252,108);
|
||||
mog.frame:SetToplevel(true);
|
||||
mog.frame:SetClampedToScreen(true);
|
||||
mog.frame:EnableMouse(true);
|
||||
mog.frame:EnableMouseWheel(true);
|
||||
mog.frame:SetMovable(true);
|
||||
mog.frame:SetResizable(true);
|
||||
mog.frame:SetDontSavePosition(true);
|
||||
mog.frame:SetScript("OnMouseDown", mog.frame.StartMoving);
|
||||
local function stopMovingOrSizing(self)
|
||||
self:StopMovingOrSizing();
|
||||
local profile = mog.db.profile;
|
||||
profile.point, profile.x, profile.y = select(3, self:GetPoint());
|
||||
end
|
||||
mog.frame:SetScript("OnMouseUp", stopMovingOrSizing);
|
||||
mog.frame:SetScript("OnHide", stopMovingOrSizing);
|
||||
tinsert(UISpecialFrames,"MogItFrame");
|
||||
|
||||
mog.frame.TitleText:SetText("MogIt");
|
||||
mog.frame.TitleText:SetPoint("RIGHT",mog.frame,"RIGHT",-28,0);
|
||||
mog.frame.portrait:SetTexture("Interface\\AddOns\\MogIt\\Images\\MogIt");
|
||||
mog.frame.portrait:SetTexCoord(0,106/128,0,105/128);
|
||||
MogItFrameBg:SetTexture("Interface\\AddOns\\MogIt\\FrameGeneral\\UI-Background-Rock",true);
|
||||
MogItFrameBg:SetVertexColor(0.8,0.3,0.8);
|
||||
|
||||
mog.frame.resize = CreateFrame("Button",nil,mog.frame);
|
||||
mog.frame.resize:SetSize(16,16);
|
||||
mog.frame.resize:SetPoint("BOTTOMRIGHT",-4,3);
|
||||
mog.frame.resize:SetHitRectInsets(0, -4, 0, -3)
|
||||
mog.frame.resize:SetScript("OnMouseDown", function(self)
|
||||
mog.frame:SetMinResize(510,350);
|
||||
mog.frame:SetMaxResize(GetScreenWidth(), GetScreenHeight());
|
||||
mog.frame:StartSizing();
|
||||
end);
|
||||
local function stopMovingOrSizing()
|
||||
mog.frame:StopMovingOrSizing();
|
||||
end
|
||||
mog.frame.resize:SetScript("OnMouseUp", stopMovingOrSizing);
|
||||
mog.frame.resize:SetScript("OnHide", stopMovingOrSizing);
|
||||
mog.frame.resize:SetNormalTexture([[Interface\ChatFrame\UI-ChatIM-SizeGrabber-Up]]);
|
||||
mog.frame.resize:SetPushedTexture([[Interface\ChatFrame\UI-ChatIM-SizeGrabber-Down]])
|
||||
mog.frame.resize:SetHighlightTexture([[Interface\ChatFrame\UI-ChatIM-SizeGrabber-Highlight]])
|
||||
|
||||
mog.frame.path = mog.frame:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall");
|
||||
mog.frame.path:SetPoint("BOTTOMLEFT",mog.frame,"BOTTOMLEFT",17,10);
|
||||
|
||||
mog.frame.page = mog.frame:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall");
|
||||
mog.frame.page:SetPoint("BOTTOMRIGHT",mog.frame,"BOTTOMRIGHT",-17,10);
|
||||
--//
|
||||
|
||||
|
||||
--// Model Frames
|
||||
mog.models = {};
|
||||
mog.modelBin = {};
|
||||
mog.posX = 0;
|
||||
mog.posY = 0;
|
||||
mog.posZ = 0;
|
||||
mog.face = 0;
|
||||
|
||||
function mog:CreateModelFrame(parent)
|
||||
if mog.modelBin[1] then
|
||||
local f = mog.modelBin[1];
|
||||
f.parent = parent;
|
||||
f:SetParent(parent);
|
||||
--f:Show();
|
||||
tremove(mog.modelBin,1);
|
||||
return f;
|
||||
end
|
||||
|
||||
local f = setmetatable(CreateFrame("Button",nil,parent), ModelFrame_MT);
|
||||
f:Hide();
|
||||
|
||||
f.parent = parent;
|
||||
f.data = {};
|
||||
f.indicators = {};
|
||||
|
||||
f.model = CreateFrame("DressUpModel",nil,f);
|
||||
f.model:SetAllPoints(f);
|
||||
f.model:SetModelScale(2);
|
||||
f.model:SetUnit("PLAYER");
|
||||
f.model:SetPosition(0,0,0);
|
||||
|
||||
f.bg = f:CreateTexture(nil,"BACKGROUND");
|
||||
f.bg:SetAllPoints(f);
|
||||
f.bg:SetTexture(0.3,0.3,0.3,0.2);
|
||||
|
||||
f:RegisterForClicks("AnyUp");
|
||||
f:RegisterForDrag("LeftButton","RightButton");
|
||||
f:SetScript("OnShow",f.OnShow);
|
||||
f:SetScript("OnHide",f.OnHide);
|
||||
f:SetScript("OnUpdate",f.OnUpdate);
|
||||
f:SetScript("OnDragStart",f.OnDragStart);
|
||||
f:SetScript("OnDragStop",f.OnDragStop);
|
||||
|
||||
return f;
|
||||
end
|
||||
|
||||
function mog:DeleteModelFrame(f)
|
||||
f:Hide();
|
||||
f:ClearAllPoints();
|
||||
f:SetScript("OnClick",nil);
|
||||
f:SetScript("OnEnter",nil);
|
||||
f:SetScript("OnLeave",nil);
|
||||
f:SetScript("OnMouseWheel",nil);
|
||||
f:EnableMouseWheel(false);
|
||||
for ind,frame in pairs(f.indicators) do
|
||||
frame:Hide();
|
||||
end
|
||||
wipe(f.data);
|
||||
f:SetAlpha(1);
|
||||
f:Enable();
|
||||
tinsert(mog.modelBin, f);
|
||||
end
|
||||
|
||||
function mog:CreateCatalogueModel()
|
||||
local f = mog:CreateModelFrame(mog.frame);
|
||||
f.type = "catalogue";
|
||||
f:SetScript("OnClick", f.OnClick);
|
||||
f:SetScript("OnEnter", f.OnEnter);
|
||||
f:SetScript("OnLeave", f.OnLeave);
|
||||
tinsert(mog.models, f);
|
||||
return f;
|
||||
end
|
||||
|
||||
function mog:DeleteCatalogueModel(n)
|
||||
mog:DeleteModelFrame(mog.models[n]);
|
||||
tremove(mog.models, n);
|
||||
end
|
||||
|
||||
|
||||
function ModelFramePrototype:OnClick(button, ...)
|
||||
if mog.active and mog.active.OnClick then
|
||||
mog.active:OnClick(self, button, self.data.value, ...);
|
||||
end
|
||||
end
|
||||
|
||||
function ModelFramePrototype:OnEnter()
|
||||
if mog.active and mog.active.OnEnter then
|
||||
mog.active:OnEnter(self, self.data.value);
|
||||
end
|
||||
end
|
||||
|
||||
function ModelFramePrototype:OnLeave(...)
|
||||
if mog.active and mog.active.OnLeave then
|
||||
mog.active:OnLeave(self, self.data.value, ...);
|
||||
else
|
||||
GameTooltip:Hide();
|
||||
end
|
||||
end
|
||||
|
||||
function ModelFramePrototype:OnShow()
|
||||
local lvl = self:GetParent():GetFrameLevel();
|
||||
if self:GetFrameLevel() <= lvl then
|
||||
self:SetFrameLevel(lvl+1);
|
||||
end
|
||||
self:ResetModel();
|
||||
if self.type == "preview" then
|
||||
self:Undress();
|
||||
mog.DressFromPreview(self, self.parent);
|
||||
else
|
||||
if not self.data.value then
|
||||
-- hack for models becoming visible OnShow, only do this if the frame is supposed to be hidden
|
||||
self:SetAlpha(1)
|
||||
self:SetAlpha(0)
|
||||
end
|
||||
mog:ModelUpdate(self, self.data.value);
|
||||
end
|
||||
end
|
||||
|
||||
function ModelFramePrototype:OnHide()
|
||||
if mog.modelUpdater.model == self then
|
||||
mog:StopModelUpdater();
|
||||
end
|
||||
self.model:SetPosition(0,0,0);
|
||||
end
|
||||
|
||||
function ModelFramePrototype:OnUpdate()
|
||||
--56, 108, 237, 238, 239, 243, 249, 250, 251, 252, 253, 254, 255
|
||||
if mog.db.profile.noAnim then
|
||||
self.model:SetSequence(3);
|
||||
end
|
||||
end
|
||||
|
||||
function ModelFramePrototype:OnDragStart(button)
|
||||
mog:StartModelUpdater(self, button);
|
||||
end
|
||||
|
||||
function ModelFramePrototype:OnDragStop(button)
|
||||
mog:StopModelUpdater();
|
||||
end
|
||||
|
||||
function ModelFramePrototype:ShowIndicator(name)
|
||||
if not mog.indicators[name] then return end;
|
||||
if not self.indicators[name] then
|
||||
self.indicators[name] = mog.indicators[name](self.model);
|
||||
end
|
||||
self.indicators[name]:Show();
|
||||
end
|
||||
|
||||
function ModelFramePrototype:SetText(text)
|
||||
if not self.indicators.label then
|
||||
self.indicators.label = mog.indicators.label(self.model);
|
||||
end
|
||||
self.indicators.label:SetText(text);
|
||||
end
|
||||
|
||||
local tryOnSlots = {
|
||||
MainHandSlot = "mainhand",
|
||||
SecondaryHandSlot = "offhand",
|
||||
}
|
||||
|
||||
function ModelFramePrototype:TryOn(item, slot)
|
||||
self.model:TryOn(item, tryOnSlots[slot]);
|
||||
end
|
||||
|
||||
function ModelFramePrototype:Undress()
|
||||
self.model:Undress()
|
||||
end
|
||||
|
||||
function ModelFramePrototype:UndressSlot(slot)
|
||||
self.model:UndressSlot(slot)
|
||||
end
|
||||
|
||||
function ModelFramePrototype:ApplyDress()
|
||||
if mog.db.profile.gridDress == "equipped" then
|
||||
self:ResetModel();
|
||||
else
|
||||
self:Undress();
|
||||
if mog.db.profile.gridDress == "preview" then
|
||||
mog.DressFromPreview(self, mog.activePreview);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ModelFramePrototype:ResetModel()
|
||||
local model = self.model;
|
||||
model:SetPosition(0, 0, 0);
|
||||
local info = self.type == "preview" and self.parent.data or mog;
|
||||
-- :Dress resets the custom race, and :SetCustomRace does :Dress, so if we're using a custom race, just :SetCustomRace again instead of :Dress
|
||||
if info.displayuseModel == myuseModel then
|
||||
model:SetUnit("PLAYER");
|
||||
model:Dress()
|
||||
elseif UnitIsPlayer("TARGET") then
|
||||
model:SetUnit("TARGET");
|
||||
model:Dress();
|
||||
end
|
||||
self:PositionModel();
|
||||
end
|
||||
|
||||
function ModelFramePrototype:PositionModel()
|
||||
local model = self.model
|
||||
if model:IsVisible() then
|
||||
local sync = (mog.db.profile.sync or self.type == "catalogue");
|
||||
local modelData = sync and mog or self.parent.data
|
||||
model:SetPosition(modelData.posZ or 0, modelData.posX or 0, modelData.posY or 0);
|
||||
model:SetFacing(modelData.face or 0);
|
||||
end
|
||||
end
|
||||
|
||||
function mog.DressFromPreview(model, previewFrame)
|
||||
if not previewFrame then
|
||||
return;
|
||||
end
|
||||
|
||||
for id, slot in pairs(previewFrame.slots) do
|
||||
if slot.item then
|
||||
model:TryOn("item:" ..slot.item .. (previewFrame.data.weaponEnchant and ":" .. previewFrame.data.weaponEnchant or ""), slot.slot);
|
||||
end
|
||||
end
|
||||
end
|
||||
--//
|
||||
|
||||
|
||||
--// Model Updater
|
||||
mog.modelUpdater = CreateFrame("Frame",nil,UIParent);
|
||||
mog.modelUpdater:Hide();
|
||||
mog.modelUpdater:SetScript("OnUpdate",function(self,elapsed)
|
||||
local cX,cY = GetCursorPosition();
|
||||
local dX = (cX-self.pX)/50;
|
||||
local dY = (cY-self.pY)/50;
|
||||
|
||||
if (mog.db.profile.sync or self.model.type == "catalogue") then
|
||||
if self.btn == "LeftButton" then
|
||||
mog.posZ = mog.posZ + dY;
|
||||
mog.face = mog.face + dX;
|
||||
elseif self.btn == "RightButton" then
|
||||
mog.posX = mog.posX + dX;
|
||||
mog.posY = mog.posY + dY;
|
||||
end
|
||||
for id,model in ipairs(mog.models) do
|
||||
model:PositionModel();
|
||||
end
|
||||
if mog.db.profile.sync then
|
||||
for id, preview in ipairs(mog.previews) do
|
||||
preview.model:PositionModel();
|
||||
end
|
||||
end
|
||||
else
|
||||
local modelData = self.model.parent.data
|
||||
if self.btn == "LeftButton" then
|
||||
modelData.posZ = (modelData.posZ or mog.posZ or 0) + dY;
|
||||
modelData.face = (modelData.face or mog.face or 0) + dX;
|
||||
elseif self.btn == "RightButton" then
|
||||
modelData.posX = (modelData.posX or mog.posX or 0) + dX;
|
||||
modelData.posY = (modelData.posY or mog.posY or 0) + dY;
|
||||
end
|
||||
self.model:PositionModel();
|
||||
end
|
||||
|
||||
self.pX,self.pY = cX,cY;
|
||||
end);
|
||||
|
||||
function mog:StartModelUpdater(model, btn)
|
||||
mog.modelUpdater.btn = btn;
|
||||
mog.modelUpdater.model = model;
|
||||
mog.modelUpdater.pX,mog.modelUpdater.pY = GetCursorPosition();
|
||||
mog.modelUpdater:Show();
|
||||
end
|
||||
|
||||
function mog:StopModelUpdater()
|
||||
mog.modelUpdater:Hide();
|
||||
mog.modelUpdater.btn = nil;
|
||||
mog.modelUpdater.model = nil;
|
||||
end
|
||||
--//
|
||||
|
||||
|
||||
--// Indicators
|
||||
mog.indicators = {};
|
||||
|
||||
function mog:CreateIndicator(name,func)
|
||||
if mog.indicators[name] then return end;
|
||||
mog.indicators[name] = func;
|
||||
end
|
||||
--//
|
||||
|
||||
|
||||
--// Scroll Frame
|
||||
local updater = CreateFrame("Frame");
|
||||
updater:Hide();
|
||||
updater:SetScript("OnUpdate", function(self)
|
||||
self:Hide();
|
||||
mog:UpdateScroll();
|
||||
mog.doModelUpdate = nil;
|
||||
end);
|
||||
|
||||
mog.scroll = CreateFrame("Slider","MogItScroll",mog.frame,"UIPanelScrollBarTrimTemplate");
|
||||
mog.scroll:Hide();
|
||||
mog.scroll:SetPoint("TOPRIGHT",mog.frame.Inset,"TOPRIGHT",1,-17);
|
||||
mog.scroll:SetPoint("BOTTOMRIGHT",mog.frame.Inset,"BOTTOMRIGHT",1,16);
|
||||
mog.scroll:SetValueStep(1);
|
||||
mog.scroll:SetScript("OnValueChanged",function(self,value,isUserInput)
|
||||
if isUserInput then
|
||||
self:SetValue(value);
|
||||
value = self:GetValue();
|
||||
end
|
||||
self:update(nil,nil,value);
|
||||
end);
|
||||
|
||||
mog.scroll.up = MogItScrollScrollUpButton;
|
||||
mog.scroll.down = MogItScrollScrollDownButton;
|
||||
mog.scroll.up:SetScript("OnClick",function(self)
|
||||
mog.scroll:update(nil,-1);
|
||||
end);
|
||||
mog.scroll.down:SetScript("OnClick",function(self)
|
||||
mog.scroll:update(nil,1);
|
||||
end);
|
||||
|
||||
function mog.scroll.update(self, value, offset, onscroll)
|
||||
local models = #mog.models;
|
||||
local total = ceil(#mog.list/models);
|
||||
|
||||
if onscroll then
|
||||
value = onscroll;
|
||||
else
|
||||
if total > 0 then
|
||||
self:SetMinMaxValues(1, total);
|
||||
end
|
||||
if total > 1 then
|
||||
self:Show();
|
||||
else
|
||||
self:Hide();
|
||||
end
|
||||
|
||||
local old = self:GetValue();
|
||||
value = (value or old or 1) + (offset or 0);
|
||||
if value ~= old then
|
||||
self:SetValue(value);
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
if value == 1 then
|
||||
self.up:Disable();
|
||||
else
|
||||
self.up:Enable();
|
||||
end
|
||||
if value == total then
|
||||
self.down:Disable();
|
||||
else
|
||||
self.down:Enable();
|
||||
end
|
||||
|
||||
if mog.Item_Menu:IsShown() or mog.Set_Menu:IsShown() then
|
||||
HideDropDownMenu(1);
|
||||
end
|
||||
|
||||
if mog.active and mog.active.OnScroll then
|
||||
mog.active:OnScroll();
|
||||
end
|
||||
|
||||
for id, frame in ipairs(mog.models) do
|
||||
local index = ((value-1)*models)+id;
|
||||
local value = mog.list[index];
|
||||
wipe(frame.data);
|
||||
if value then
|
||||
frame.data.value = value;
|
||||
frame.data.frame = frame;
|
||||
frame.data.index = index;
|
||||
for k, v in pairs(frame.indicators) do
|
||||
v:Hide();
|
||||
end
|
||||
if frame:IsShown() then
|
||||
mog:ModelUpdate(frame, value);
|
||||
if GameTooltip:IsOwned(frame) then
|
||||
frame:OnEnter();
|
||||
end
|
||||
else
|
||||
frame:Show();
|
||||
end
|
||||
frame:SetAlpha(1);
|
||||
frame:Enable();
|
||||
else
|
||||
if mog.modelUpdater.model == frame then
|
||||
mog:StopModelUpdater();
|
||||
end
|
||||
frame:SetAlpha(0);
|
||||
frame:Disable();
|
||||
end
|
||||
end
|
||||
|
||||
if total > 0 then
|
||||
mog.frame.page:SetText(MERCHANT_PAGE_NUMBER:format(value, total));
|
||||
mog.frame.page:Show();
|
||||
else
|
||||
mog.frame.page:Hide();
|
||||
end
|
||||
|
||||
-- incorrect models may be tried on when items aren't cached, this queues another update if uncached items were found
|
||||
if mog.doModelUpdate then
|
||||
updater:Show();
|
||||
end
|
||||
end
|
||||
|
||||
mog.frame:SetScript("OnMouseWheel", function(self, offset)
|
||||
mog.scroll:update(nil, offset > 0 and -1 or 1);
|
||||
end);
|
||||
|
||||
function mog:UpdateScroll(value, offset)
|
||||
mog.scroll:update(value, offset);
|
||||
end
|
||||
|
||||
function mog:ModelUpdate(frame, value)
|
||||
if mog.active and mog.active.FrameUpdate and value then
|
||||
mog.active:FrameUpdate(frame, value);
|
||||
end
|
||||
end
|
||||
--//
|
||||
|
||||
|
||||
--// GUI
|
||||
function mog:GetModelSize()
|
||||
local x = floor((mog.db.profile.gridWidth+5-(4+10)-(10+18+4))/mog.db.profile.columns)-5;
|
||||
local y = floor((mog.db.profile.gridHeight+5-(60+10)-(10+26))/mog.db.profile.rows)-5;
|
||||
return x,y;
|
||||
end
|
||||
|
||||
function mog:UpdateGUI(resize)
|
||||
local profile = mog.db.profile;
|
||||
local rows,columns = profile.rows,profile.columns;
|
||||
local total = rows*columns;
|
||||
local current = #mog.models;
|
||||
local modelWidth,modelHeight = mog:GetModelSize();
|
||||
|
||||
if not resize then
|
||||
if current > total then
|
||||
for i=current,(total+1),-1 do
|
||||
mog:DeleteCatalogueModel(i);
|
||||
end
|
||||
elseif current < total then
|
||||
for i=(current+1),total,1 do
|
||||
mog:CreateCatalogueModel();
|
||||
end
|
||||
end
|
||||
mog.frame:SetPoint(profile.point, profile.x, profile.y);
|
||||
mog.frame:SetSize(profile.gridWidth,profile.gridHeight);
|
||||
if mog.frame:IsShown() then
|
||||
mog.scroll:update();
|
||||
end
|
||||
end
|
||||
|
||||
for row=1,rows do
|
||||
for column=1,columns do
|
||||
local n = ((row-1)*columns)+column;
|
||||
if not resize then
|
||||
if n==1 then
|
||||
mog.models[n]:SetPoint("TOPLEFT",mog.frame.Inset,"TOPLEFT",10,-10);
|
||||
elseif column==1 then
|
||||
mog.models[n]:SetPoint("TOPLEFT",mog.models[n-columns],"BOTTOMLEFT",0,-5);
|
||||
else
|
||||
mog.models[n]:SetPoint("TOPLEFT",mog.models[n-1],"TOPRIGHT",5,0);
|
||||
end
|
||||
end
|
||||
mog.models[n]:SetSize(modelWidth,modelHeight);
|
||||
end
|
||||
end
|
||||
end
|
||||
--//
|
||||
|
||||
|
||||
--// Toolbar
|
||||
local function menuBarInitialize(self, level)
|
||||
if self.active and self.active.func then
|
||||
self.tier[level] = UIDROPDOWNMENU_MENU_VALUE;
|
||||
self.active.func(self, level);
|
||||
end
|
||||
end
|
||||
|
||||
local function menuOnClick(self, btn)
|
||||
if self.menuBar.active ~= self then
|
||||
HideDropDownMenu(1);
|
||||
end
|
||||
self.menuBar.active = self;
|
||||
if self.func then
|
||||
self.menuBar:ToggleMenu(nil, self);
|
||||
end
|
||||
end
|
||||
|
||||
local function menuOnEnter(self)
|
||||
if self.menuBar.active ~= self and self.menuBar:IsShown() then
|
||||
HideDropDownMenu(1);
|
||||
if self.func then
|
||||
self.menuBar.active = self;
|
||||
self.menuBar:ToggleMenu(nil, self);
|
||||
end
|
||||
end
|
||||
self.nt:SetTexture(1,0.82,0,1);
|
||||
end
|
||||
|
||||
local function menuOnLeave(self)
|
||||
self.nt:SetTexture(0,0,0,0);
|
||||
end
|
||||
|
||||
local function createMenu(menuBar, label, func)
|
||||
local f = CreateFrame("Button", nil, menuBar.parent);
|
||||
f:SetText(label);
|
||||
f:SetNormalFontObject(GameFontNormal);
|
||||
f:SetHighlightFontObject(GameFontBlack);
|
||||
f:SetSize(f:GetFontString():GetStringWidth()+10, f:GetFontString():GetStringHeight()+10);
|
||||
f.menuBar = menuBar
|
||||
f.menuBar.xOffset = 0
|
||||
f.menuBar.yOffset = 0
|
||||
|
||||
f.nt = f:CreateTexture(nil,"BACKGROUND");
|
||||
--nt:SetTexture(0.8,0.3,0.8,1);
|
||||
f.nt:SetTexture(0,0,0,0);
|
||||
f.nt:SetAllPoints(f);
|
||||
f:SetNormalTexture(f.nt);
|
||||
|
||||
f.func = func;
|
||||
f:SetScript("OnClick",menuOnClick);
|
||||
f:SetScript("OnEnter",menuOnEnter);
|
||||
f:SetScript("OnLeave",menuOnLeave);
|
||||
|
||||
return f;
|
||||
end
|
||||
|
||||
function mog.CreateMenuBar(parent)
|
||||
local menuBar = mog:CreateDropdown("Menu");
|
||||
menuBar.initialize = menuBarInitialize
|
||||
menuBar.CreateMenu = createMenu;
|
||||
menuBar.parent = parent
|
||||
menuBar.tier = {};
|
||||
return menuBar;
|
||||
end
|
||||
|
||||
mog.menu = mog.CreateMenuBar(mog.frame);
|
||||
--//
|
||||
|
||||
|
||||
--// Module Menu
|
||||
mog.menu.modules = mog.menu:CreateMenu(L["Modules"], function(self, tier)
|
||||
if tier == 1 then
|
||||
local info;
|
||||
info = UIDropDownMenu_CreateInfo();
|
||||
info.text = L["Base Modules"];
|
||||
info.isTitle = true;
|
||||
info.notCheckable = true;
|
||||
info.justifyH = "CENTER";
|
||||
UIDropDownMenu_AddButton(info,tier);
|
||||
|
||||
for k,v in ipairs(mog.moduleList) do
|
||||
if v.base and v.Dropdown then
|
||||
v:Dropdown(tier);
|
||||
end
|
||||
end
|
||||
|
||||
info = UIDropDownMenu_CreateInfo();
|
||||
info.isTitle = true;
|
||||
info.notCheckable = true;
|
||||
UIDropDownMenu_AddButton(info,tier);
|
||||
|
||||
info = UIDropDownMenu_CreateInfo();
|
||||
info.text = L["Extra Modules"];
|
||||
info.isTitle = true;
|
||||
info.notCheckable = true;
|
||||
info.justifyH = "CENTER";
|
||||
UIDropDownMenu_AddButton(info,tier);
|
||||
|
||||
for k,v in ipairs(mog.moduleList) do
|
||||
if (not v.base) and v.Dropdown then
|
||||
v:Dropdown(tier);
|
||||
end
|
||||
end
|
||||
elseif self.tier[2] and self.tier[2].Dropdown then
|
||||
self.tier[2]:Dropdown(tier);
|
||||
end
|
||||
end);
|
||||
mog.menu.modules:SetPoint("TOPLEFT", mog.frame, "TOPLEFT", 62, -31);
|
||||
--//
|
||||
|
||||
|
||||
--// Catalogue Menu
|
||||
local function setWeaponEnchant(self, enchant)
|
||||
mog.weaponEnchant = enchant;
|
||||
mog.menu:Rebuild(2);
|
||||
mog.scroll:update();
|
||||
end
|
||||
|
||||
local function setDisplayModel(self, arg1, value)
|
||||
mog[arg1] = value;
|
||||
for i, model in ipairs(mog.models) do
|
||||
-- reset positions first since they tend to go nuts when manipulating the model
|
||||
local modelData = model.parent.data
|
||||
mog.posX = 0;
|
||||
mog.posY = 0;
|
||||
mog.posZ = 0;
|
||||
model:ResetModel();
|
||||
if model:IsEnabled() then
|
||||
mog:ModelUpdate(model, model.data.value);
|
||||
end
|
||||
end
|
||||
CloseDropDownMenus(1);
|
||||
end
|
||||
|
||||
function mog:CreateuseModelMenu(dropdown, level, func, selecteduseModel)
|
||||
for i = 0, 1 do
|
||||
local info = UIDropDownMenu_CreateInfo();
|
||||
info.text = useModel[i];
|
||||
info.func = func;
|
||||
info.checked = selecteduseModel == i;
|
||||
info.arg1 = "displayuseModel";
|
||||
info.arg2 = i;
|
||||
dropdown:AddButton(info, level);
|
||||
end
|
||||
end
|
||||
local dressOptions = {
|
||||
none = NONE,
|
||||
preview = L["Preview"],
|
||||
equipped = L["Equipped"],
|
||||
}
|
||||
|
||||
local function setGridDress(self)
|
||||
mog.db.profile.gridDress = self.value;
|
||||
for i, model in ipairs(mog.models) do
|
||||
model.model:SetPosition(0, 0, 0)
|
||||
end
|
||||
mog.scroll:update();
|
||||
for i, model in ipairs(mog.models) do
|
||||
model:PositionModel()
|
||||
end
|
||||
CloseDropDownMenus(1);
|
||||
end
|
||||
|
||||
function mog:ToggleFilters()
|
||||
if not mog.filt:IsShown() then mog.filt:Show() else mog.filt:Hide() end
|
||||
--mog.filt:SetShown(not mog.filt:IsShown());
|
||||
end
|
||||
|
||||
mog.sorting = {};
|
||||
|
||||
mog.menu.catalogue = mog.menu:CreateMenu(L["Catalogue"], function(self, tier)
|
||||
if tier == 1 then
|
||||
local info = UIDropDownMenu_CreateInfo();
|
||||
info.text = mog.filt:IsShown() and L["Hide Filters"] or L["Show Filters"];
|
||||
info.notCheckable = true;
|
||||
info.func = mog.ToggleFilters;
|
||||
UIDropDownMenu_AddButton(info,tier);
|
||||
|
||||
local info = UIDropDownMenu_CreateInfo();
|
||||
info.text = L["Sorting"];
|
||||
info.value = "sorting";
|
||||
info.notCheckable = true;
|
||||
info.hasArrow = true;
|
||||
info.disabled = not (mog.active and mog.active.sorting and #mog.active.sorting > 0);
|
||||
UIDropDownMenu_AddButton(info,tier);
|
||||
|
||||
local info = UIDropDownMenu_CreateInfo();
|
||||
info.text = "Use Model";
|
||||
info.value = "useModel";
|
||||
info.notCheckable = true;
|
||||
info.hasArrow = true;
|
||||
UIDropDownMenu_AddButton(info,tier);
|
||||
|
||||
local info = UIDropDownMenu_CreateInfo();
|
||||
info.text = L["Dress models"];
|
||||
info.value = "gridDress";
|
||||
info.notCheckable = true;
|
||||
info.hasArrow = true;
|
||||
UIDropDownMenu_AddButton(info,tier);
|
||||
|
||||
local info = UIDropDownMenu_CreateInfo();
|
||||
info.text = L["Weapon enchant"];
|
||||
info.value = "weaponEnchant";
|
||||
info.notCheckable = true;
|
||||
info.hasArrow = true;
|
||||
UIDropDownMenu_AddButton(info,tier);
|
||||
|
||||
elseif self.tier[2] == "sorting" then
|
||||
if tier == 2 then
|
||||
if mog.active and mog.active.sorting then
|
||||
for k,v in ipairs(mog.active.sorting) do
|
||||
if mog.sorting[v] and mog.sorting[v].Dropdown then
|
||||
mog.sorting[v].Dropdown(self,mog.active,tier);
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif self.tier[3] and self.tier[3].Dropdown then
|
||||
self.tier[3].Dropdown(mog.active,tier);
|
||||
end
|
||||
elseif self.tier[2] == "useModel" then
|
||||
mog:CreateuseModelMenu(self, tier, setDisplayModel, mog.displayuseModel)
|
||||
elseif self.tier[2] == "weaponEnchant" then
|
||||
if tier == 2 then
|
||||
local info = UIDropDownMenu_CreateInfo();
|
||||
info.text = NONE;
|
||||
info.func = setWeaponEnchant;
|
||||
info.arg1 = nil;
|
||||
info.checked = mog.weaponEnchant == nil;
|
||||
info.keepShownOnClick = true;
|
||||
self:AddButton(info, tier);
|
||||
|
||||
for i, enchantCategory in ipairs(mog.enchants) do
|
||||
local info = UIDropDownMenu_CreateInfo();
|
||||
info.text = enchantCategory.name;
|
||||
info.value = enchantCategory;
|
||||
info.notCheckable = true;
|
||||
info.hasArrow = true;
|
||||
info.keepShownOnClick = true;
|
||||
self:AddButton(info, tier);
|
||||
end
|
||||
elseif tier == 3 then
|
||||
for i, enchant in ipairs(self.tier[3]) do
|
||||
local info = UIDropDownMenu_CreateInfo();
|
||||
info.text = enchant.name;
|
||||
info.func = setWeaponEnchant;
|
||||
info.arg1 = enchant.id;
|
||||
info.checked = mog.weaponEnchant == enchant.id;
|
||||
info.keepShownOnClick = true;
|
||||
self:AddButton(info, tier);
|
||||
end
|
||||
end
|
||||
elseif self.tier[2] == "gridDress" then
|
||||
if tier == 2 then
|
||||
for k, v in pairs(dressOptions) do
|
||||
local info = UIDropDownMenu_CreateInfo();
|
||||
info.text = v;
|
||||
info.value = k;
|
||||
info.func = setGridDress;
|
||||
info.checked = mog.db.profile.gridDress == k;
|
||||
info.keepShownOnClick = true;
|
||||
self:AddButton(info,tier);
|
||||
end
|
||||
end
|
||||
end
|
||||
end);
|
||||
mog.menu.catalogue:SetPoint("LEFT", mog.menu.modules, "RIGHT", 5, 0);
|
||||
--//
|
||||
|
||||
|
||||
--// Preview Menu
|
||||
local function newPreview()
|
||||
mog:CreatePreview();
|
||||
ShowUIPanel(mog.view);
|
||||
end
|
||||
|
||||
local function syncPreviews()
|
||||
mog.db.profile.sync = not mog.db.profile.sync;
|
||||
end
|
||||
|
||||
mog.menu.preview = mog.menu:CreateMenu(L["Preview"], function(self, tier)
|
||||
if not mog.db.profile.singlePreview then
|
||||
local info = UIDropDownMenu_CreateInfo();
|
||||
info.text = L["New Preview"];
|
||||
info.notCheckable = true;
|
||||
info.func = newPreview;
|
||||
UIDropDownMenu_AddButton(info,tier);
|
||||
end
|
||||
|
||||
local info = UIDropDownMenu_CreateInfo();
|
||||
info.text = mog.view:IsShown() and L["Hide Previews"] or L["Show Previews"];
|
||||
info.notCheckable = true;
|
||||
info.func = mog.TogglePreview;
|
||||
UIDropDownMenu_AddButton(info,tier);
|
||||
|
||||
local info = UIDropDownMenu_CreateInfo();
|
||||
info.text = L["Synchronize Positioning"];
|
||||
info.checked = mog.db.profile.sync;
|
||||
info.func = syncPreviews;
|
||||
info.isNotRadio = true;
|
||||
UIDropDownMenu_AddButton(info,tier);
|
||||
end);
|
||||
mog.menu.preview:SetPoint("LEFT", mog.menu.catalogue, "RIGHT", 5, 0);
|
||||
--//
|
||||
|
||||
|
||||
--// Options Menu
|
||||
function mog:ToggleOptions()
|
||||
if not mog.options then
|
||||
mog.createOptions();
|
||||
end
|
||||
InterfaceOptionsFrame_OpenToCategory(MogIt);
|
||||
end
|
||||
|
||||
mog.menu.options = mog.menu:CreateMenu(L["Options"]);
|
||||
mog.menu.options:SetScript("OnClick", mog.ToggleOptions);
|
||||
mog.menu.options:SetPoint("LEFT", mog.menu.preview, "RIGHT", 5, 0);
|
||||
--//
|
||||
|
||||
local help = mog.menu:CreateMenu(L["Help"])
|
||||
-- help:SetNormalFontObject(GameFontHighlight)
|
||||
help:SetPoint("LEFT", mog.menu.options, "RIGHT", 5, 0)
|
||||
help:SetScript("OnClick", nil);
|
||||
help:SetScript("OnEnter", function(self)
|
||||
GameTooltip:SetOwner(self, "ANCHOR_BOTTOMRIGHT")
|
||||
GameTooltip:AddLine(L["How to use"]);
|
||||
GameTooltip:AddLine(" ");
|
||||
GameTooltip:AddLine(L["Model controls"]);
|
||||
GameTooltip:AddLine(L["Left click and drag horizontally to rotate"], 1, 1, 1);
|
||||
GameTooltip:AddLine(L["Left click and drag vertically to zoom"], 1, 1, 1);
|
||||
GameTooltip:AddLine(L["Right click and drag to move"], 1, 1, 1);
|
||||
local info = mog.active and mog.active.Help
|
||||
if info then
|
||||
GameTooltip:AddLine(" ");
|
||||
GameTooltip:AddLine(L["Module controls"]);
|
||||
for i, v in ipairs(info) do
|
||||
GameTooltip:AddLine(v, 1, 1, 1);
|
||||
end
|
||||
end
|
||||
GameTooltip:AddLine(" ");
|
||||
GameTooltip:AddLine("Alt + Mouseover item = GameTooltip");
|
||||
GameTooltip:Show()
|
||||
self.nt:SetTexture(1, 0.82, 0, 1);
|
||||
end);
|
||||
help:SetScript("OnLeave", function(self)
|
||||
GameTooltip_Hide()
|
||||
self.nt:SetTexture(0, 0, 0, 0);
|
||||
end);
|
||||
|
||||
|
||||
--// Default Indicators
|
||||
mog:CreateIndicator("label", function(model)
|
||||
local label = model:CreateFontString(nil, "OVERLAY", "GameFontNormalMed3");
|
||||
label:SetPoint("TOPLEFT", 12, -12);
|
||||
label:SetPoint("BOTTOMRIGHT", -12, 12);
|
||||
label:SetJustifyV("BOTTOM");
|
||||
label:SetJustifyH("CENTER");
|
||||
label:SetNonSpaceWrap(true);
|
||||
return label;
|
||||
end)
|
||||
|
||||
mog:CreateIndicator("hasItem", function(model)
|
||||
local hasItem = model:CreateTexture(nil, "OVERLAY");
|
||||
hasItem:SetTexture("Interface\\RaidFrame\\ReadyCheck-Ready");
|
||||
hasItem:SetSize(32, 32);
|
||||
hasItem:SetPoint("BOTTOMRIGHT", -8, 8);
|
||||
return hasItem;
|
||||
end)
|
||||
|
||||
mog:CreateIndicator("wishlist", function(model)
|
||||
local wishlist = model:CreateTexture(nil, "OVERLAY");
|
||||
wishlist:SetTexture("Interface\\TargetingFrame\\UI-RaidTargetingIcon_1");
|
||||
wishlist:SetSize(32, 32);
|
||||
wishlist:SetPoint("TOPRIGHT", -8, -8);
|
||||
return wishlist;
|
||||
end)
|
||||
--//
|
||||
99
MogIt/Core/Links.lua
Normal file
@@ -0,0 +1,99 @@
|
||||
local MogIt,mog = ...;
|
||||
local L = mog.L;
|
||||
|
||||
local charset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
local base = #charset;
|
||||
local maxlen = 3;
|
||||
|
||||
local function toBase(num)
|
||||
local str;
|
||||
if num <= 0 then
|
||||
str = "0";
|
||||
else
|
||||
str = "";
|
||||
while num > 0 do
|
||||
str = charset:sub((num%base)+1,(num%base)+1)..str;
|
||||
num = math.floor(num/base);
|
||||
end
|
||||
end
|
||||
return str;
|
||||
end
|
||||
|
||||
local function fromBase(str)
|
||||
local num = 0;
|
||||
for i=1,#str do
|
||||
num = num + ((charset:find(str:sub(i,i))-1) * base^(#str-i));
|
||||
end
|
||||
return num;
|
||||
end
|
||||
|
||||
function mog:SetToLink(set,enchant)
|
||||
local link = "[MogIt:";
|
||||
for k,v in pairs(set) do
|
||||
link = link..("%0"..maxlen.."s"):format(toBase(v));
|
||||
end
|
||||
link = link..":";
|
||||
link = link..(enchant and toBase(enchant) or 0);
|
||||
link = link.."]";
|
||||
return link;
|
||||
end
|
||||
|
||||
function mog:LinkToSet(link)
|
||||
local set = {};
|
||||
--local items = link:match("MogIt:([^%]:]+)");
|
||||
local items,enchant = link:match("MogIt:(%w*):?(%w*)");
|
||||
if items then
|
||||
for i=1,#items/maxlen do
|
||||
table.insert(set,fromBase(items:sub((i-1)*maxlen+1,i*maxlen)));
|
||||
end
|
||||
end
|
||||
enchant = enchant ~= "" and fromBase(enchant) or nil;
|
||||
return set,enchant;
|
||||
end
|
||||
|
||||
local function filter(self,event,msg,...)
|
||||
msg = msg:gsub("%[(MogIt[^%]]+)%]","|cFFCC99FF|H%1|h[MogIt]|h|r");
|
||||
return false, msg, ...;
|
||||
end
|
||||
|
||||
ChatFrame_AddMessageEventFilter("CHAT_MSG_SAY",filter);
|
||||
ChatFrame_AddMessageEventFilter("CHAT_MSG_YELL",filter);
|
||||
ChatFrame_AddMessageEventFilter("CHAT_MSG_EMOTE",filter);
|
||||
ChatFrame_AddMessageEventFilter("CHAT_MSG_GUILD",filter);
|
||||
ChatFrame_AddMessageEventFilter("CHAT_MSG_OFFICER",filter);
|
||||
ChatFrame_AddMessageEventFilter("CHAT_MSG_PARTY",filter);
|
||||
ChatFrame_AddMessageEventFilter("CHAT_MSG_PARTY_LEADER",filter);
|
||||
ChatFrame_AddMessageEventFilter("CHAT_MSG_RAID",filter);
|
||||
ChatFrame_AddMessageEventFilter("CHAT_MSG_RAID_LEADER",filter);
|
||||
ChatFrame_AddMessageEventFilter("CHAT_MSG_RAID_WARNING",filter);
|
||||
ChatFrame_AddMessageEventFilter("CHAT_MSG_BATTLEGROUND",filter);
|
||||
ChatFrame_AddMessageEventFilter("CHAT_MSG_BATTLEGROUND_LEADER",filter);
|
||||
ChatFrame_AddMessageEventFilter("CHAT_MSG_WHISPER",filter);
|
||||
ChatFrame_AddMessageEventFilter("CHAT_MSG_WHISPER_INFORM",filter);
|
||||
ChatFrame_AddMessageEventFilter("CHAT_MSG_BN_WHISPER",filter);
|
||||
ChatFrame_AddMessageEventFilter("CHAT_MSG_BN_WHISPER_INFORM",filter);
|
||||
ChatFrame_AddMessageEventFilter("CHAT_MSG_BN_CONVERSATION",filter);
|
||||
ChatFrame_AddMessageEventFilter("CHAT_MSG_BN_INLINE_TOAST_BROADCAST",filter);
|
||||
ChatFrame_AddMessageEventFilter("CHAT_MSG_BN_INLINE_TOAST_BROADCAST_INFORM",filter);
|
||||
ChatFrame_AddMessageEventFilter("CHAT_MSG_CHANNEL",filter);
|
||||
|
||||
local SetHyperlink = ItemRefTooltip.SetHyperlink;
|
||||
function ItemRefTooltip:SetHyperlink(link)
|
||||
if link:find("^MogIt") then
|
||||
if IsModifiedClick("CHATLINK") then
|
||||
ChatEdit_InsertLink("["..link.."]")
|
||||
else
|
||||
local preview = mog:GetPreview();
|
||||
local set,enchant = mog:LinkToSet(link);
|
||||
--if race and gender then
|
||||
if enchant then
|
||||
preview.data.weaponEnchant = enchant
|
||||
preview.model:ResetModel();
|
||||
preview.model:Undress();
|
||||
end
|
||||
mog:AddToPreview(set,preview);
|
||||
end
|
||||
else
|
||||
SetHyperlink(self, link);
|
||||
end
|
||||
end
|
||||
325
MogIt/Core/Options.lua
Normal file
@@ -0,0 +1,325 @@
|
||||
local MogIt,mog = ...;
|
||||
local L = mog.L;
|
||||
|
||||
local LBR = LibStub("LibBabble-Race-3.0"):GetUnstrictLookupTable();
|
||||
|
||||
function mog.createOptions()
|
||||
local about = LibStub("LibAddonInfo-1.0"):CreateFrame(MogIt,nil,"Interface\\AddOns\\MogIt\\Images");
|
||||
|
||||
local config = LibStub("AceConfig-3.0");
|
||||
local dialog = LibStub("AceConfigDialog-3.0");
|
||||
local db = LibStub("AceDBOptions-3.0");
|
||||
|
||||
local function get(info)
|
||||
if info.arg == "minimap" then
|
||||
return mog.db.profile.minimap.hide;
|
||||
else
|
||||
return mog.db.profile[info.arg];
|
||||
end
|
||||
end
|
||||
|
||||
local function set(info,value)
|
||||
if info.arg == "minimap" then
|
||||
mog.db.profile.minimap.hide = value;
|
||||
if value then
|
||||
mog.LDBI:Hide("MogIt");
|
||||
else
|
||||
mog.LDBI:Show("MogIt");
|
||||
end
|
||||
else
|
||||
mog.db.profile[info.arg] = value;
|
||||
if info.arg == "tooltipRotate" then
|
||||
mog.tooltip.rotate:SetShown(value);
|
||||
elseif info.arg == "sortWishlist" then
|
||||
mog:BuildList(nil, "Wishlist");
|
||||
elseif info.arg == "singlePreview" then
|
||||
mog:SetSinglePreview(value);
|
||||
elseif info.arg == "previewUIPanel" then
|
||||
mog:SetPreviewUIPanel(value);
|
||||
-- elseif info.arg == "previewFixedSize" then
|
||||
-- mog:SetPreviewFixedSize(value);
|
||||
elseif info.arg == "tooltipWidth" then
|
||||
mog.tooltip:SetWidth(value);
|
||||
elseif info.arg == "tooltipHeight" then
|
||||
mog.tooltip:SetHeight(value);
|
||||
elseif info.arg == "rows" or info.arg == "columns" then
|
||||
mog:UpdateGUI();
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local options = {
|
||||
type = "group",
|
||||
name = MogIt,
|
||||
args = {},
|
||||
};
|
||||
|
||||
options.args.general = {
|
||||
type = "group",
|
||||
order = 1,
|
||||
name = GENERAL,
|
||||
get = get,
|
||||
set = set,
|
||||
args = {
|
||||
minimap = {
|
||||
type = "toggle",
|
||||
order = 1,
|
||||
name = L["Hide minimap button"],
|
||||
width = "full",
|
||||
arg = "minimap",
|
||||
},
|
||||
sortWishlist = {
|
||||
type = "toggle",
|
||||
order = 1.3,
|
||||
name = L["Sort wishlist sets alphabetically"],
|
||||
width = "full",
|
||||
arg = "sortWishlist",
|
||||
},
|
||||
dressupPreview = {
|
||||
type = "toggle",
|
||||
order = 1.4,
|
||||
name = L["Use preview frame to dress up"],
|
||||
width = "full",
|
||||
arg = "dressupPreview",
|
||||
},
|
||||
singlePreview = {
|
||||
type = "toggle",
|
||||
order = 1.5,
|
||||
name = L["Use a single preview frame"],
|
||||
width = "full",
|
||||
arg = "singlePreview",
|
||||
confirm = function()
|
||||
return L["This will close all your currently open previews."];
|
||||
end,
|
||||
},
|
||||
previewUIPanel = {
|
||||
type = "toggle",
|
||||
order = 1.75,
|
||||
name = L["Preview frame UI panel behaviour"],
|
||||
width = "full",
|
||||
arg = "previewUIPanel",
|
||||
disabled = function()
|
||||
return not mog.db.profile.singlePreview;
|
||||
end,
|
||||
},
|
||||
--[[previewFixedSize = {
|
||||
type = "toggle",
|
||||
order = 1.8,
|
||||
name = L["Preview frame fixed size"],
|
||||
width = "full",
|
||||
arg = "previewFixedSize",
|
||||
disabled = function()
|
||||
return not (mog.db.profile.singlePreview and mog.db.profile.previewUIPanel);
|
||||
end,
|
||||
},]]--
|
||||
catalogue = {
|
||||
type = "group",
|
||||
order = 2,
|
||||
name = L["Catalogue"],
|
||||
inline = true,
|
||||
args = {
|
||||
noAnim = {
|
||||
type = "toggle",
|
||||
order = 1,
|
||||
name = L["No animation"],
|
||||
width = "double",
|
||||
arg = "noAnim",
|
||||
},
|
||||
url = {
|
||||
type = "select",
|
||||
order = 2.5,
|
||||
name = L["URL website"],
|
||||
values = function()
|
||||
local tbl = {};
|
||||
for k,v in pairs(mog.url) do
|
||||
tbl[k] = (v.fav and "\124T"..v.fav..":16\124t " or "")..k;
|
||||
end
|
||||
return tbl;
|
||||
end,
|
||||
arg = "url",
|
||||
},
|
||||
rows = {
|
||||
type = "range",
|
||||
order = 4,
|
||||
name = L["Rows"],
|
||||
step = 1,
|
||||
min = 1,
|
||||
max = 10,
|
||||
arg = "rows",
|
||||
},
|
||||
columns = {
|
||||
type = "range",
|
||||
order = 5,
|
||||
name = L["Columns"],
|
||||
step = 1,
|
||||
min = 1,
|
||||
max = 15,
|
||||
arg = "columns",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
config:RegisterOptionsTable("MogIt_General",options.args.general);
|
||||
dialog:AddToBlizOptions("MogIt_General",options.args.general.name,MogIt);
|
||||
|
||||
options.args.tooltip = {
|
||||
type = "group",
|
||||
order = 1,
|
||||
name = L["Tooltip"],
|
||||
get = get,
|
||||
set = set,
|
||||
args = {
|
||||
tooltip = {
|
||||
type = "toggle",
|
||||
order = 1,
|
||||
name = L["Enable tooltip model"],
|
||||
width = "double",
|
||||
arg = "tooltip",
|
||||
},
|
||||
dress = {
|
||||
type = "toggle",
|
||||
order = 2,
|
||||
name = L["Dress model"],
|
||||
width = "double",
|
||||
arg = "tooltipDress",
|
||||
},
|
||||
mouse = {
|
||||
type = "toggle",
|
||||
order = 3,
|
||||
name = L["Rotate with mouse wheel"],
|
||||
width = "double",
|
||||
arg = "tooltipMouse",
|
||||
},
|
||||
rotate = {
|
||||
type = "toggle",
|
||||
order = 4,
|
||||
name = L["Auto rotate"],
|
||||
width = "full",
|
||||
arg = "tooltipRotate",
|
||||
},
|
||||
width = {
|
||||
type = "range",
|
||||
order = 5,
|
||||
name = L["Width"],
|
||||
step = 1,
|
||||
min = 100,
|
||||
max = 500,
|
||||
arg = "tooltipWidth",
|
||||
},
|
||||
height = {
|
||||
type = "range",
|
||||
order = 6,
|
||||
name = L["Height"],
|
||||
step = 1,
|
||||
min = 100,
|
||||
max = 500,
|
||||
arg = "tooltipHeight",
|
||||
},
|
||||
--[[ mog = {
|
||||
type = "toggle",
|
||||
order = 7,
|
||||
name = L["Only transmogrification items"],
|
||||
width = "double",
|
||||
arg = "tooltipMog",
|
||||
},]]--
|
||||
modifier = {
|
||||
type = "select",
|
||||
order = 8,
|
||||
name = L["Only show if modifier is pressed"],
|
||||
values = function()
|
||||
local tbl = {
|
||||
None = "None",
|
||||
};
|
||||
for k,v in pairs(mog.tooltip.mod) do
|
||||
tbl[k] = k;
|
||||
end
|
||||
return tbl;
|
||||
end,
|
||||
arg = "tooltipMod",
|
||||
},
|
||||
-- Custom race on tooltip models custom races broken throughout
|
||||
--[[ customModel = {
|
||||
type = "toggle",
|
||||
order = 9,
|
||||
name = L["Use custom model"],
|
||||
width = "full",
|
||||
arg = "tooltipCustomModel",
|
||||
},
|
||||
race = {
|
||||
type = "select",
|
||||
order = 10,
|
||||
name = L["Model race"],
|
||||
values = {
|
||||
[1] = LBR["Human"],
|
||||
[3] = LBR["Dwarf"],
|
||||
[4] = LBR["Night Elf"],
|
||||
[7] = LBR["Gnome"],
|
||||
[11] = LBR["Draenei"],
|
||||
[22] = LBR["Worgen"],
|
||||
[2] = LBR["Orc"],
|
||||
[5] = LBR["Undead"],
|
||||
[6] = LBR["Tauren"],
|
||||
[8] = LBR["Troll"],
|
||||
[10] = LBR["Blood Elf"],
|
||||
[9] = LBR["Goblin"],
|
||||
[24] = LBR["Pandaren"],
|
||||
},
|
||||
arg = "tooltipRace",
|
||||
disabled = function()
|
||||
return not mog.db.profile.tooltipCustomModel;
|
||||
end,
|
||||
},
|
||||
gender = {
|
||||
type = "select",
|
||||
order = 11,
|
||||
name = L["Model gender"],
|
||||
values = {
|
||||
[0] = MALE,
|
||||
[1] = FEMALE,
|
||||
},
|
||||
arg = "tooltipGender",
|
||||
disabled = function()
|
||||
return not mog.db.profile.tooltipCustomModel;
|
||||
end,
|
||||
}, --]]
|
||||
},
|
||||
};
|
||||
config:RegisterOptionsTable("MogIt_Tooltip",options.args.tooltip);
|
||||
dialog:AddToBlizOptions("MogIt_Tooltip",options.args.tooltip.name,MogIt);
|
||||
|
||||
--[[options.args.modules = {
|
||||
type = "group",
|
||||
order = 2,
|
||||
name = L["Modules"],
|
||||
--plugins
|
||||
args = {
|
||||
wishlist = db:GetOptionsTable(mog.wishlist.db),
|
||||
},
|
||||
};
|
||||
options.args.modules.args.wishlist.name = L["Wishlist"];
|
||||
config:RegisterOptionsTable("MogIt_Modules",options.args.modules);
|
||||
dialog:AddToBlizOptions("MogIt_Modules",options.args.modules.name,MogIt);--]]
|
||||
|
||||
options.args.options = db:GetOptionsTable(mog.db);
|
||||
options.args.options.name = L["Options profile"];
|
||||
options.args.options.order = 5;
|
||||
config:RegisterOptionsTable("MogIt_Options",options.args.options);
|
||||
dialog:AddToBlizOptions("MogIt_Options",options.args.options.name,MogIt);
|
||||
|
||||
options.args.wishlist = db:GetOptionsTable(mog.wishlist.db);
|
||||
options.args.wishlist.name = L["Wishlist profile"];
|
||||
options.args.wishlist.order = 6;
|
||||
config:RegisterOptionsTable("MogIt_Wishlist",options.args.wishlist);
|
||||
dialog:AddToBlizOptions("MogIt_Wishlist",options.args.wishlist.name,MogIt);
|
||||
|
||||
mog.options = options;
|
||||
end
|
||||
|
||||
local hook = CreateFrame("Frame",nil,InterfaceOptionsFrame);
|
||||
hook:SetScript("OnShow",function(self)
|
||||
if not mog.options then
|
||||
mog.createOptions();
|
||||
end
|
||||
self:SetScript("OnShow",nil);
|
||||
end);
|
||||
950
MogIt/Core/Preview.lua
Normal file
@@ -0,0 +1,950 @@
|
||||
local MogIt,mog = ...;
|
||||
local L = mog.L;
|
||||
|
||||
local LBI = LibStub("LibBabble-Inventory-3.0"):GetUnstrictLookupTable();
|
||||
|
||||
local TITANS_GRIP_SPELLID = 46917
|
||||
|
||||
mog.view = CreateFrame("Frame","MogItPreview",UIParent);
|
||||
mog.view:SetAllPoints();
|
||||
mog.view:SetScript("OnShow",function(self)
|
||||
if #mog.previews == 0 then
|
||||
mog:CreatePreview();
|
||||
end
|
||||
if mog.db.profile.singlePreview then
|
||||
ShowUIPanel(mog.previews[1]);
|
||||
end
|
||||
end);
|
||||
mog.view:SetScript("OnHide",function(self)
|
||||
if mog.db.profile.singlePreview then
|
||||
HideUIPanel(mog.previews[1]);
|
||||
end
|
||||
end);
|
||||
tinsert(UISpecialFrames,"MogItPreview");
|
||||
--ShowUIPanel(mog.view);
|
||||
|
||||
|
||||
function mog:ActivatePreview(preview)
|
||||
mog.activePreview = preview;
|
||||
preview.Bg:SetTexture("Interface\\AddOns\\MogIt\\FrameGeneral\\UI-Background-Rock",true);
|
||||
preview.Bg:SetVertexColor(0.8,0.3,0.8);
|
||||
preview.activate:Disable();
|
||||
for k,v in ipairs(mog.previews) do
|
||||
if v ~= preview then
|
||||
v.Bg:SetVertexColor(1,1,1);
|
||||
v.activate:Enable();
|
||||
end
|
||||
end
|
||||
if mog.db.profile.gridDress == "preview" then
|
||||
mog.scroll:update();
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--// Preview Functions
|
||||
local function raiseAll(self, ...)
|
||||
local newLevel = self:GetFrameLevel() + 1
|
||||
for i = 1, select("#", ...) do
|
||||
select(i, ...):SetFrameLevel(newLevel)
|
||||
end
|
||||
end
|
||||
|
||||
local function stopMovingOrSizing(self)
|
||||
self:StopMovingOrSizing();
|
||||
local frameProps = mog.db.profile.previewProps[self:GetID()];
|
||||
frameProps.point, frameProps.x, frameProps.y = select(3, self:GetPoint());
|
||||
end
|
||||
|
||||
local function resizeOnMouseDown(self)
|
||||
local f = self:GetParent();
|
||||
f:SetMinResize(335,385);
|
||||
f:SetMaxResize(GetScreenWidth(),GetScreenHeight());
|
||||
f:StartSizing();
|
||||
end
|
||||
|
||||
local function resizeOnMouseUp(self)
|
||||
if mog.db.profile.singlePreview and mog.db.profile.previewUIPanel and mog.db.profile.previewFixedSize then return end
|
||||
local f = self:GetParent();
|
||||
f:StopMovingOrSizing();
|
||||
local frameProps = mog.db.profile.previewProps[f:GetID()];
|
||||
frameProps.w, frameProps.h = f:GetSize();
|
||||
-- anchors may change from resizing
|
||||
if not (mog.db.profile.singlePreview and mog.db.profile.previewUIPanel) then
|
||||
frameProps.point, frameProps.x, frameProps.y = select(3, f:GetPoint());
|
||||
UpdateUIPanelPositions(f)
|
||||
end
|
||||
end
|
||||
|
||||
local function modelOnMouseWheel(self, v)
|
||||
local delta = ((v > 0 and 0.6) or -0.6);
|
||||
if mog.db.profile.sync then
|
||||
mog.posZ = mog.posZ + delta;
|
||||
for id,model in ipairs(mog.models) do
|
||||
model:PositionModel();
|
||||
end
|
||||
for id,preview in ipairs(mog.previews) do
|
||||
preview.model:PositionModel();
|
||||
end
|
||||
else
|
||||
self.parent.data.posZ = (self.parent.data.posZ or mog.posZ or 0) + delta;
|
||||
self:PositionModel();
|
||||
end
|
||||
end
|
||||
|
||||
local function slotTexture(f, slot, texture)
|
||||
f.slots[slot].icon:SetTexture(texture or select(2,GetInventorySlotInfo(slot)));
|
||||
end
|
||||
|
||||
local function slotOnEnter(self)
|
||||
if self.item then
|
||||
mog.ShowItemTooltip(self, self.item);
|
||||
else
|
||||
GameTooltip:SetOwner(self,"ANCHOR_RIGHT");
|
||||
GameTooltip:SetText(_G[strupper(self.slot)]);
|
||||
end
|
||||
end
|
||||
|
||||
local function slotOnLeave(self)
|
||||
GameTooltip:Hide();
|
||||
end
|
||||
|
||||
local function slotOnClick(self,btn)
|
||||
if btn == "RightButton" and IsControlKeyDown() then
|
||||
local preview = self:GetParent();
|
||||
mog.view.DelItem(self.slot,preview);
|
||||
if mog.db.profile.gridDress == "preview" and mog.activePreview == preview then
|
||||
mog.scroll:update();
|
||||
end
|
||||
slotOnEnter(self);
|
||||
else
|
||||
mog.Item_OnClick(self,btn,self);
|
||||
end
|
||||
end
|
||||
|
||||
local function previewOnClose(self)
|
||||
if mog.db.profile.singlePreview then
|
||||
mog.view:Hide();
|
||||
elseif mog.db.profile.previewConfirmClose then
|
||||
StaticPopup_Show("MOGIT_PREVIEW_CLOSE", nil, nil, self:GetParent());
|
||||
else
|
||||
mog:DeletePreview(self:GetParent());
|
||||
end
|
||||
end
|
||||
|
||||
local function previewActivate(self)
|
||||
mog:ActivatePreview(self:GetParent());
|
||||
end
|
||||
--//
|
||||
|
||||
|
||||
--// Preview Menu
|
||||
local currentPreview;
|
||||
|
||||
local function setDisplayModel(self, arg1, value)
|
||||
currentPreview.data[arg1] = value;
|
||||
local model = currentPreview.model;
|
||||
model:ResetModel();
|
||||
model:Undress();
|
||||
mog.DressFromPreview(model, currentPreview);
|
||||
CloseDropDownMenus();
|
||||
end
|
||||
|
||||
local function setWeaponEnchant(self, preview, enchant)
|
||||
preview.data.weaponEnchant = enchant;
|
||||
self.owner:Rebuild(2);
|
||||
mog.scroll:update();
|
||||
local mainHandItem = preview.slots["MainHandSlot"].item;
|
||||
local offHandItem = preview.slots["SecondaryHandSlot"].item;
|
||||
if mainHandItem then
|
||||
preview.model:TryOn(format("item:%d:%d", mainHandItem, preview.data.weaponEnchant), "MainHandSlot");
|
||||
end
|
||||
if offHandItem then
|
||||
preview.model:TryOn(format("item:%d:%d", offHandItem, preview.data.weaponEnchant), "SecondaryHandSlot");
|
||||
end
|
||||
end
|
||||
|
||||
local previewMenu = {
|
||||
{
|
||||
text = "Use Model",
|
||||
value = "useModel",
|
||||
notCheckable = true,
|
||||
hasArrow = true,
|
||||
},
|
||||
{
|
||||
text = L["Weapon enchant"],
|
||||
value = "weaponEnchant",
|
||||
notCheckable = true,
|
||||
hasArrow = true,
|
||||
},
|
||||
{
|
||||
text = L["Add Item"],
|
||||
notCheckable = true,
|
||||
func = function(self)
|
||||
StaticPopup_Show("MOGIT_PREVIEW_ADDITEM", nil, nil, currentPreview);
|
||||
end,
|
||||
},
|
||||
{
|
||||
text = L["Chat Link"],
|
||||
notCheckable = true,
|
||||
func = function(self)
|
||||
local tbl = {};
|
||||
for k, v in pairs(currentPreview.slots) do
|
||||
if v.item then
|
||||
table.insert(tbl, v.item);
|
||||
end
|
||||
end
|
||||
ChatEdit_InsertLink(mog:SetToLink(tbl, currentPreview.data.weaponEnchant));
|
||||
--ChatFrame_OpenChat(link);
|
||||
end,
|
||||
},
|
||||
{
|
||||
text = L["Import / Export"],
|
||||
notCheckable = true,
|
||||
func = function(self)
|
||||
StaticPopup_Show("MOGIT_PREVIEW_IMPORT", nil, nil, currentPreview);
|
||||
end,
|
||||
},
|
||||
{
|
||||
text = L["Equip current gear"],
|
||||
notCheckable = true,
|
||||
func = function(self)
|
||||
for k, v in pairs(currentPreview.slots) do
|
||||
mog.view.DelItem(k, currentPreview);
|
||||
local slotID = GetInventorySlotInfo(k);
|
||||
local item = GetInventoryItemID("player", slotID) --mog.mogSlots[slotID] and select(6, GetTransmogrifySlotInfo(slotID)) or
|
||||
-- print(item)
|
||||
if (k ~= "HeadSlot" or ShowingHelm()) and (k ~= "BackSlot" or ShowingCloak()) then
|
||||
mog.view.AddItem(item, currentPreview);
|
||||
end
|
||||
end
|
||||
if mog.activePreview == currentPreview and mog.db.profile.gridDress == "preview" then
|
||||
mog.scroll:update();
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
text = "Equip target's gear",
|
||||
func = function(self)
|
||||
for k, v in pairs(currentPreview.slots) do
|
||||
mog.view.DelItem(k, currentPreview);
|
||||
NotifyInspect("target")
|
||||
local slotID = GetInventorySlotInfo(k);
|
||||
local item = GetInventoryItemID("target", slotID) --mog.mogSlots[slotID] and select(6, GetTransmogrifySlotInfo(slotID)) or
|
||||
-- print(item)
|
||||
if (k ~= "HeadSlot" or ShowingHelm()) and (k ~= "BackSlot" or ShowingCloak()) then
|
||||
mog.view.AddItem(item, currentPreview);
|
||||
ClearInspectPlayer()
|
||||
end
|
||||
end
|
||||
if mog.activePreview == currentPreview and mog.db.profile.gridDress == "preview" then
|
||||
mog.scroll:update();
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
text = L["Clear"],
|
||||
notCheckable = true,
|
||||
func = function(self)
|
||||
mog.view:Undress(currentPreview);
|
||||
if mog.activePreview == currentPreview and mog.db.profile.gridDress == "preview" then
|
||||
mog.scroll:update();
|
||||
end
|
||||
end,
|
||||
},
|
||||
}
|
||||
|
||||
local function previewInitialize(self, level)
|
||||
if level == 1 then
|
||||
currentPreview = self.parent;
|
||||
|
||||
for i, info in ipairs(previewMenu) do
|
||||
UIDropDownMenu_AddButton(info, level);
|
||||
end
|
||||
elseif self.tier[2] == "useModel" then
|
||||
mog:CreateuseModelMenu(self, level, setDisplayModel, self.parent.data.displayuseModel)
|
||||
elseif self.tier[2] == "weaponEnchant" then
|
||||
if level == 2 then
|
||||
local info = UIDropDownMenu_CreateInfo();
|
||||
info.text = NONE;
|
||||
info.func = setWeaponEnchant;
|
||||
info.arg1 = self.parent;
|
||||
info.arg2 = nil;
|
||||
info.checked = self.parent.data.weaponEnchant == nil;
|
||||
info.keepShownOnClick = true;
|
||||
self:AddButton(info, level);
|
||||
|
||||
for i, enchantCategory in ipairs(mog.enchants) do
|
||||
local info = UIDropDownMenu_CreateInfo();
|
||||
info.text = enchantCategory.name;
|
||||
info.value = enchantCategory;
|
||||
info.notCheckable = true;
|
||||
info.hasArrow = true;
|
||||
info.keepShownOnClick = true;
|
||||
self:AddButton(info, level);
|
||||
end
|
||||
elseif level == 3 then
|
||||
for i, enchant in ipairs(self.tier[3]) do
|
||||
local info = UIDropDownMenu_CreateInfo();
|
||||
info.text = enchant.name;
|
||||
info.func = setWeaponEnchant;
|
||||
info.arg1 = self.parent;
|
||||
info.arg2 = enchant.id;
|
||||
info.checked = self.parent.data.weaponEnchant == enchant.id;
|
||||
info.keepShownOnClick = true;
|
||||
self:AddButton(info, level);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
--//
|
||||
|
||||
|
||||
--// Save Menu
|
||||
local newSet = {items = {}}
|
||||
|
||||
local function onClick(self, set)
|
||||
newSet.name = set
|
||||
wipe(newSet.items)
|
||||
for slot, v in pairs(currentPreview.slots) do
|
||||
newSet.items[slot] = v.item
|
||||
end
|
||||
StaticPopup_Show("MOGIT_WISHLIST_OVERWRITE_SET", set, nil, newSet)
|
||||
end
|
||||
|
||||
local function newSetOnClick(self)
|
||||
wipe(newSet.items)
|
||||
newSet.name = "Set "..(#mog.wishlist:GetSets() + 1)
|
||||
for slot, v in pairs(currentPreview.slots) do
|
||||
newSet.items[slot] = v.item
|
||||
end
|
||||
StaticPopup_Show("MOGIT_WISHLIST_CREATE_SET", nil, nil, newSet)
|
||||
end
|
||||
|
||||
local function saveInitialize(self, level)
|
||||
currentPreview = self.parent;
|
||||
|
||||
mog.wishlist:AddSetMenuItems(level, onClick)
|
||||
|
||||
local info = UIDropDownMenu_CreateInfo()
|
||||
info.text = L["New set"]
|
||||
info.func = newSetOnClick
|
||||
info.colorCode = GREEN_FONT_COLOR_CODE
|
||||
info.notCheckable = true
|
||||
self:AddButton(info, level)
|
||||
end
|
||||
--//
|
||||
|
||||
|
||||
--// Load Menu
|
||||
local function onClick(self, set, profile)
|
||||
mog.view:Undress(currentPreview);
|
||||
mog:AddToPreview(mog.wishlist:GetSetItems(set, profile), currentPreview)
|
||||
CloseDropDownMenus()
|
||||
end
|
||||
|
||||
local function loadInitialize(self, level)
|
||||
currentPreview = self.parent;
|
||||
|
||||
if level == 1 then
|
||||
mog.wishlist:AddSetMenuItems(level, onClick)
|
||||
|
||||
local info = UIDropDownMenu_CreateInfo()
|
||||
info.text = L["Other profiles"]
|
||||
info.hasArrow = true
|
||||
info.notCheckable = true
|
||||
self:AddButton(info, level)
|
||||
elseif level == 2 then
|
||||
local curProfile = mog.wishlist:GetCurrentProfile()
|
||||
for i, profile in ipairs(mog.wishlist:GetProfiles()) do
|
||||
if profile ~= curProfile and mog.wishlist:GetSets(profile) then
|
||||
local info = UIDropDownMenu_CreateInfo()
|
||||
info.text = profile
|
||||
info.hasArrow = true
|
||||
info.notCheckable = true
|
||||
self:AddButton(info, level)
|
||||
end
|
||||
end
|
||||
elseif level == 3 then
|
||||
mog.wishlist:AddSetMenuItems(level, onClick, UIDROPDOWNMENU_MENU_VALUE, UIDROPDOWNMENU_MENU_VALUE)
|
||||
end
|
||||
end;
|
||||
--//
|
||||
|
||||
|
||||
--// Toolbar
|
||||
local function helpOnEnter(self)
|
||||
self.nt:SetTexture(1,0.82,0,1);
|
||||
GameTooltip:SetOwner(self, "ANCHOR_BOTTOMRIGHT");
|
||||
GameTooltip:AddLine(L["How to use"]);
|
||||
GameTooltip:AddLine(" ");
|
||||
GameTooltip:AddLine(L["Basic Controls"]);
|
||||
GameTooltip:AddLine(L["Left click and drag horizontally to rotate"],1,1,1);
|
||||
GameTooltip:AddLine(L["Left click and drag vertically to zoom"],1,1,1);
|
||||
GameTooltip:AddLine(L["Right click and drag to move"],1,1,1);
|
||||
GameTooltip:AddLine(L["Click the bottom right corner and drag to resize"],1,1,1);
|
||||
GameTooltip:AddLine(L["Click the \"Activate\" button to set this as the active preview"],1,1,1);
|
||||
GameTooltip:AddLine(" ");
|
||||
GameTooltip:AddLine(L["Slot Controls"]);
|
||||
GameTooltip:AddLine(L["Shift + Left click to link an item to chat"],1,1,1);
|
||||
GameTooltip:AddLine(L["Ctrl + Left click to try on an item"],1,1,1);
|
||||
GameTooltip:AddLine(L["Right click to show the item menu"],1,1,1);
|
||||
GameTooltip:AddLine(L["Shift + Right click to show a URL for the item"],1,1,1);
|
||||
GameTooltip:AddLine(L["Ctrl + Right click to remove the item from the preview"],1,1,1);
|
||||
GameTooltip:Show();
|
||||
end
|
||||
|
||||
local function helpOnLeave(self)
|
||||
GameTooltip:Hide();
|
||||
self.nt:SetTexture(0,0,0,0);
|
||||
end
|
||||
|
||||
local function createMenuBar(parent)
|
||||
local menuBar = mog.CreateMenuBar(parent)
|
||||
|
||||
menuBar.preview = menuBar:CreateMenu(L["Preview"], previewInitialize);
|
||||
menuBar.preview:SetPoint("TOPLEFT", parent, 62, -31);
|
||||
|
||||
menuBar.load = menuBar:CreateMenu(L["Load"], loadInitialize);
|
||||
menuBar.load:SetPoint("LEFT", menuBar.preview, "RIGHT", 5, 0);
|
||||
|
||||
menuBar.save = menuBar:CreateMenu(L["Save"], saveInitialize);
|
||||
menuBar.save:SetPoint("LEFT", menuBar.load, "RIGHT", 5, 0);
|
||||
|
||||
menuBar.help = menuBar:CreateMenu(L["Help"]);
|
||||
menuBar.help:SetPoint("LEFT", menuBar.save, "RIGHT", 5, 0);
|
||||
menuBar.help:SetScript("OnEnter",helpOnEnter);
|
||||
menuBar.help:SetScript("OnLeave",helpOnLeave);
|
||||
end
|
||||
--//
|
||||
|
||||
|
||||
--// Preview Frame
|
||||
local function initPreview(frame, id)
|
||||
frame:SetID(id);
|
||||
local props = mog.db.profile.previewProps[id];
|
||||
frame:ClearAllPoints();
|
||||
frame:SetPoint(props.point, props.x, props.y);
|
||||
frame:SetSize(props.w, props.h);
|
||||
frame.TitleText:SetText(L["Preview %d"]:format(id));
|
||||
frame.data = {
|
||||
displayuseModel = mog.playeruseModel,
|
||||
};
|
||||
end
|
||||
|
||||
mog.previews = {};
|
||||
mog.previewBin = {};
|
||||
mog.previewNum = 0;
|
||||
|
||||
function mog:CreatePreview()
|
||||
if mog.previewBin[1] then
|
||||
local f = mog.previewBin[1];
|
||||
local leastIndex = #mog.previews + 1;
|
||||
-- find the lowest unused frame ID
|
||||
for i, v in ipairs(self.previewBin) do
|
||||
leastIndex = min(v:GetID(), leastIndex);
|
||||
end
|
||||
initPreview(f, leastIndex);
|
||||
f:Show();
|
||||
mog:ActivatePreview(f);
|
||||
tremove(mog.previewBin,1);
|
||||
tinsert(mog.previews, f);
|
||||
return f;
|
||||
end
|
||||
|
||||
mog.previewNum = mog.previewNum + 1;
|
||||
local id = mog.previewNum;
|
||||
local f = CreateFrame("Frame", "MogItPreview"..id, mog.view, "ButtonFrameTemplate");
|
||||
initPreview(f, id);
|
||||
|
||||
f:SetToplevel(true);
|
||||
f:SetClampedToScreen(true);
|
||||
f:EnableMouse(true);
|
||||
f:SetMovable(true);
|
||||
f:SetResizable(true);
|
||||
f:Raise();
|
||||
|
||||
f.onCloseCallback = previewOnClose;
|
||||
f.Bg = _G["MogItPreview"..id.."Bg"];
|
||||
--f.Bg:SetVertexColor(0.8,0.3,0.8);
|
||||
f.portrait:Hide();
|
||||
f.portraitFrame:Hide();
|
||||
f.topLeftCorner:Show();
|
||||
f.topBorderBar:SetPoint("TOPLEFT", f.topLeftCorner, "TOPRIGHT", 0, 0);
|
||||
f.leftBorderBar:SetPoint("TOPLEFT", f.topLeftCorner, "BOTTOMLEFT", 0, 0);
|
||||
|
||||
--ButtonFrameTemplate_HidePortrait(f);
|
||||
|
||||
f.resize = CreateFrame("Button", nil, f);
|
||||
f.resize:SetSize(16, 16);
|
||||
f.resize:SetPoint("BOTTOMRIGHT", -4, 3);
|
||||
f.resize:EnableMouse(true);
|
||||
f.resize:SetHitRectInsets(0, -4, 0, -3);
|
||||
f.resize:SetScript("OnMouseDown", resizeOnMouseDown);
|
||||
f.resize:SetScript("OnMouseUp", resizeOnMouseUp);
|
||||
f.resize:SetScript("OnHide", resizeOnMouseUp);
|
||||
f.resize:SetNormalTexture([[Interface\ChatFrame\UI-ChatIM-SizeGrabber-Up]]);
|
||||
f.resize:SetPushedTexture([[Interface\ChatFrame\UI-ChatIM-SizeGrabber-Down]])
|
||||
f.resize:SetHighlightTexture([[Interface\ChatFrame\UI-ChatIM-SizeGrabber-Highlight]])
|
||||
|
||||
f.slots = {};
|
||||
for i, slotIndex in ipairs(mog.slots) do
|
||||
local slot = CreateFrame("Button", "MogItCorePreviewSlot"..i, f, "ItemButtonTemplate");
|
||||
slot.slot = slotIndex;
|
||||
slot.icon = _G["MogItCorePreviewSlot"..i.."IconTexture"]
|
||||
if i == 1 then
|
||||
slot:SetPoint("TOPLEFT", f.Inset, "TOPLEFT", 8, -8);
|
||||
elseif i == 8 then
|
||||
slot:SetPoint("TOPRIGHT", f.Inset, "TOPRIGHT", -7, -8);
|
||||
elseif i == 12 then
|
||||
slot:SetPoint("TOP", f.slots[mog:GetSlot(i-1)], "BOTTOM", 0, -45);
|
||||
else
|
||||
slot:SetPoint("TOP", f.slots[mog:GetSlot(i-1)], "BOTTOM", 0, -4);
|
||||
end
|
||||
slot:RegisterForClicks("AnyUp");
|
||||
slot:SetScript("OnClick", slotOnClick);
|
||||
slot:SetScript("OnEnter", slotOnEnter);
|
||||
slot:SetScript("OnLeave", slotOnLeave);
|
||||
slot.OnEnter = slotOnEnter;
|
||||
f.slots[slotIndex] = slot;
|
||||
slotTexture(f, slotIndex);
|
||||
end
|
||||
|
||||
f.model = mog:CreateModelFrame(f);
|
||||
f.model.type = "preview";
|
||||
f.model:Show();
|
||||
f.model:EnableMouseWheel(true);
|
||||
f.model:SetScript("OnMouseWheel", modelOnMouseWheel);
|
||||
f.model:SetPoint("TOPLEFT", f.Inset, "TOPLEFT", 49, -8);
|
||||
f.model:SetPoint("BOTTOMRIGHT", f.Inset, "BOTTOMRIGHT", -49, 8);
|
||||
|
||||
f.activate = CreateFrame("Button", "MogItPreview"..id.."Activate", f, "MagicButtonTemplate");
|
||||
f.activate:SetText(L["Activate"]);
|
||||
f.activate:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", 5, 5);
|
||||
f.activate:SetWidth(100);
|
||||
f.activate:SetScript("OnClick", previewActivate);
|
||||
|
||||
f:SetScript("OnMouseDown", f.StartMoving);
|
||||
f:SetScript("OnMouseUp", stopMovingOrSizing);
|
||||
|
||||
createMenuBar(f);
|
||||
mog:ActivatePreview(f);
|
||||
|
||||
-- child frames occasionally appears behind the parent for whatever reason, so we raise them here
|
||||
raiseAll(f, f:GetChildren())
|
||||
|
||||
tinsert(mog.previews, f);
|
||||
return f;
|
||||
end
|
||||
|
||||
function mog:DeletePreview(f)
|
||||
HideUIPanel(f);
|
||||
f:ClearAllPoints();
|
||||
f:SetPoint("CENTER",mog.view,"CENTER");
|
||||
mog.view:Undress(f);
|
||||
wipe(f.data);
|
||||
tinsert(mog.previewBin,f);
|
||||
for k,v in ipairs(mog.previews) do
|
||||
if v == f then
|
||||
tremove(mog.previews,k);
|
||||
break;
|
||||
end
|
||||
end
|
||||
if mog.activePreview == f then
|
||||
mog.activePreview = nil;
|
||||
if mog.db.profile.gridDress == "preview" then
|
||||
mog.scroll:update();
|
||||
end
|
||||
end
|
||||
if #mog.previews == 0 then
|
||||
HideUIPanel(mog.view);
|
||||
end
|
||||
end
|
||||
|
||||
function mog:GetPreview(frame)
|
||||
if self.db.profile.singlePreview then
|
||||
frame = self.previews[1];
|
||||
end
|
||||
|
||||
return frame or self:CreatePreview();
|
||||
end
|
||||
|
||||
function mog:SetSinglePreview(isSinglePreview)
|
||||
for i = #mog.previews, 1, -1 do
|
||||
mog:DeletePreview(mog.previews[i]);
|
||||
end
|
||||
if isSinglePreview then
|
||||
-- hack to make sure CreatePreview gets the frame named MogItPreview1
|
||||
if #mog.previewBin > 1 and mog.previewBin[1] ~= MogItPreview1 then
|
||||
for i = 2, #mog.previewBin do
|
||||
if mog.previewBin[i] == MogItPreview1 then
|
||||
tremove(mog.previewBin, i);
|
||||
tinsert(mog.previewBin, 1, MogItPreview1);
|
||||
break;
|
||||
end
|
||||
end
|
||||
end
|
||||
mog:CreatePreview();
|
||||
end
|
||||
if MogItPreview1 then
|
||||
mog:SetPreviewUIPanel(mog.db.profile.previewUIPanel);
|
||||
end
|
||||
mog:SetPreviewMenu(isSinglePreview);
|
||||
end
|
||||
|
||||
function mog:SetPreviewUIPanel(isUIPanel)
|
||||
if isUIPanel and mog.db.profile.singlePreview then
|
||||
MogItPreview1:SetScript("OnMouseDown", nil);
|
||||
MogItPreview1:SetScript("OnMouseUp", nil);
|
||||
MogItPreview1:SetScript("OnHide", HideParentPanel);
|
||||
UIPanelWindows["MogItPreview1"] = {
|
||||
area = "left",
|
||||
pushable = 1,
|
||||
whileDead = true,
|
||||
}
|
||||
HideUIPanel(MogItPreview1);
|
||||
else
|
||||
local props = mog.db.profile.previewProps[1];
|
||||
local point, x, y = props.point, props.x, props.y;
|
||||
HideUIPanel(MogItPreview1);
|
||||
MogItPreview1:SetScript("OnMouseDown", MogItPreview1.StartMoving);
|
||||
MogItPreview1:SetScript("OnMouseUp", stopMovingOrSizing);
|
||||
MogItPreview1:SetScript("OnHide", nil);
|
||||
UIPanelWindows["MogItPreview1"] = nil;
|
||||
MogItPreview1:SetAttribute("UIPanelLayout-defined", nil);
|
||||
MogItPreview1:ClearAllPoints();
|
||||
MogItPreview1:SetPoint(point, x, y);
|
||||
end
|
||||
mog:SetPreviewFixedSize(mog.db.profile.previewFixedSize);
|
||||
end
|
||||
|
||||
function mog:SetPreviewFixedSize(isFixedSize)
|
||||
local isUIPanel = mog.db.profile.previewUIPanel;
|
||||
if isFixedSize and isUIPanel then
|
||||
MogItPreview1:SetSize(PANEL_DEFAULT_WIDTH, PANEL_DEFAULT_HEIGHT);
|
||||
else
|
||||
local props = mog.db.profile.previewProps[1];
|
||||
MogItPreview1:SetSize(props.w, props.h);
|
||||
end
|
||||
if not (isUIPanel and isFixedSize) then MogItPreview1.resize:Show() else MogItPreview1.resize:Hide() end
|
||||
--MogItPreview1.resize:SetShown(not ());
|
||||
UpdateUIPanelPositions(MogItPreview1);
|
||||
end
|
||||
|
||||
local cachedPreviews;
|
||||
local doCache = {};
|
||||
mog:AddItemCacheCallback("PreviewAddItem", function()
|
||||
cachedPreviews = {};
|
||||
for i = #doCache, 1, -1 do
|
||||
local item = doCache[i]
|
||||
if GetItemInfo(item.id) then
|
||||
cachedPreviews[item.frame] = true;
|
||||
mog.view.AddItem(item.id, item.frame);
|
||||
tremove(doCache, i)
|
||||
end
|
||||
end
|
||||
-- update the grid if using preview grid dress, and an item was cached on the active preview
|
||||
if mog.db.profile.gridDress == "preview" and cachedPreviews[mog.activePreview] then
|
||||
mog:UpdateScroll();
|
||||
end
|
||||
end)
|
||||
|
||||
local function additem(item, preview, forceSlot, subType, invType, texture)
|
||||
local slot = mog:GetSlot(invType)
|
||||
if type(forceSlot) == "string" then
|
||||
slot = forceSlot
|
||||
end
|
||||
if slot then
|
||||
if slot == "MainHandSlot" or slot == "SecondaryHandSlot" then
|
||||
if invType == "INVTYPE_2HWEAPON" then
|
||||
if IsSpellKnown(TITANS_GRIP_SPELLID) then
|
||||
-- Titan's Grip exists in the spellbook, so we can treat this weapon as one handed
|
||||
invType = "INVTYPE_WEAPON";
|
||||
end
|
||||
end
|
||||
|
||||
if invType == "INVTYPE_WEAPON" then
|
||||
-- put one handed weapons in the off hand if: main hand is occupied, off hand is free and a two handed weapon isn't equipped
|
||||
if preview.slots["MainHandSlot"].item and not preview.slots["SecondaryHandSlot"].item and not preview.data.twohand then
|
||||
slot = "SecondaryHandSlot";
|
||||
end
|
||||
end
|
||||
|
||||
if invType == "INVTYPE_2HWEAPON" or invType == "INVTYPE_RANGED" or (invType == "INVTYPE_RANGEDRIGHT" and subType ~= LBI["Wands"]) then
|
||||
-- if any two handed weapon is being equipped, first clear up both hands
|
||||
mog.view.DelItem("MainHandSlot", preview);
|
||||
mog.view.DelItem("SecondaryHandSlot", preview);
|
||||
preview.data.twohand = true;
|
||||
elseif preview.data.twohand then
|
||||
preview.data.twohand = false;
|
||||
if slot == "MainHandSlot" then
|
||||
mog.view.DelItem("SecondaryHandSlot", preview);
|
||||
elseif slot == "SecondaryHandSlot" then
|
||||
mog.view.DelItem("MainHandSlot", preview);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
preview.slots[slot].item = item;
|
||||
slotTexture(preview, slot, texture);
|
||||
if preview:IsVisible() then
|
||||
if (slot == "MainHandSlot" or slot == "SecondaryHandSlot") and preview.data.weaponEnchant then
|
||||
item = format("item:%d:%d", item, preview.data.weaponEnchant)
|
||||
end
|
||||
if invType == "INVTYPE_RANGED" then
|
||||
slot = "SecondaryHandSlot"
|
||||
end
|
||||
preview.model:TryOn(item, slot);
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local delay = CreateFrame("GameTooltip", "mogitGT", nil, "GameTooltipTemplate")
|
||||
|
||||
function mog.view.AddItem(item, preview, forceSlot)
|
||||
if not (item and preview) then return end;
|
||||
local subType,_,invType,texture = select(7,GetItemInfo(item));
|
||||
if not invType then
|
||||
delay:SetHyperlink('|Hitem:'..item..'|h')
|
||||
delay:SetScript("OnUpdate",function()
|
||||
subType,_,invType,texture = select(7,GetItemInfo(item));
|
||||
additem(item, preview, forceSlot, subType,invType,texture)
|
||||
delay:SetScript("OnUpdate",nil)
|
||||
end)
|
||||
return;
|
||||
else additem(item, preview, forceSlot, subType,invType,texture)
|
||||
end
|
||||
end
|
||||
|
||||
function mog.view.DelItem(slot,preview)
|
||||
if not (preview and slot and preview.slots[slot].item) then return end;
|
||||
local item = preview.slots[slot].item
|
||||
preview.slots[slot].item = nil;
|
||||
slotTexture(preview,slot);
|
||||
if preview:IsVisible() then
|
||||
local invType = (select(9,GetItemInfo(item)))
|
||||
if invType == "INVTYPE_RANGED" then slot = "SecondaryHandSlot" end
|
||||
--preview.model:UndressSlot(GetInventorySlotInfo(slot));
|
||||
--mog.view:Undress(preview);
|
||||
preview.model:Undress()
|
||||
for k,v in pairs(preview.slots) do
|
||||
mog.view.AddItem(v.item,preview,k);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mog:AddToPreview(item,preview)
|
||||
if not item then return end;
|
||||
preview = mog:GetPreview(preview or mog.activePreview);
|
||||
ShowUIPanel(mog.view);
|
||||
if type(item) == "number" then
|
||||
mog.view.AddItem(item,preview);
|
||||
elseif type(item) == "string" then
|
||||
mog.view.AddItem(tonumber(item:match("item:(%d+)")),preview);
|
||||
elseif type(item) == "table" then
|
||||
--mog.view:Undress(preview);
|
||||
preview.model:Undress()
|
||||
for k,v in pairs(item) do
|
||||
mog.view.AddItem(v,preview,k);
|
||||
end
|
||||
end
|
||||
|
||||
if mog.db.profile.gridDress == "preview" and mog.activePreview == preview then
|
||||
mog.scroll:update();
|
||||
end
|
||||
|
||||
return preview;
|
||||
end
|
||||
|
||||
function mog.view:Undress(preview)
|
||||
for k, v in pairs(preview.slots) do
|
||||
mog.view.DelItem(k, preview);
|
||||
end
|
||||
end
|
||||
--//
|
||||
|
||||
|
||||
--// Hooks
|
||||
if not ModifiedItemClickHandlers then
|
||||
ModifiedItemClickHandlers = {};
|
||||
|
||||
local origHandleModifiedItemClick = HandleModifiedItemClick;
|
||||
|
||||
function HandleModifiedItemClick(link)
|
||||
if not link then
|
||||
return false;
|
||||
end
|
||||
for i, v in ipairs(ModifiedItemClickHandlers) do
|
||||
if v(link) then
|
||||
return true;
|
||||
end
|
||||
end
|
||||
return origHandleModifiedItemClick(link);
|
||||
end
|
||||
end
|
||||
|
||||
-- hack to allow post hooking SetItemRef for previewing
|
||||
tinsert(ModifiedItemClickHandlers, function(link)
|
||||
local button = GetMouseButtonClicked()
|
||||
if button then
|
||||
if link and IsDressableItem(link) then
|
||||
if IsModifiedClick("DRESSUP") then
|
||||
return DressUpItemLink(link);
|
||||
elseif IsControlKeyDown() and button == "RightButton" then
|
||||
mog:AddToPreview(link);
|
||||
return true;
|
||||
end
|
||||
end
|
||||
elseif IsModifiedClick("DRESSUP") then
|
||||
-- if no mouse button was detected, this happened through a chat link
|
||||
-- if it's a dressup modified click and a dressable item, intercept the call here and let SetItemRef hook handle it
|
||||
return link and IsDressableItem(link);
|
||||
end
|
||||
local _, staticPopup = StaticPopup_Visible("MOGIT_PREVIEW_ADDITEM");
|
||||
if IsModifiedClick("CHATLINK") and staticPopup then
|
||||
staticPopup.editBox:SetText(link);
|
||||
return true
|
||||
end
|
||||
end);
|
||||
|
||||
hooksecurefunc("SetItemRef", function(link, text, button, chatFrame)
|
||||
local id = tonumber(link:match("^item:(%d+)"));
|
||||
if link:match("item:%d+") and IsModifiedClick("DRESSUP") then
|
||||
if button == "RightButton" then
|
||||
mog:AddToPreview(link);
|
||||
else
|
||||
DressUpItemLink(link);
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
local origDressUpItemLink = DressUpItemLink;
|
||||
function DressUpItemLink(link)
|
||||
if not (link and IsDressableItem(link)) then
|
||||
return false;
|
||||
end
|
||||
if mog.db.profile.dressupPreview then
|
||||
mog:AddToPreview(link);
|
||||
return true;
|
||||
end
|
||||
return origDressUpItemLink(link);
|
||||
end
|
||||
|
||||
local function hookInspectUI()
|
||||
local function onClick(self, button)
|
||||
if InspectFrame.unit and self.hasItem and IsControlKeyDown() and button == "RightButton" then
|
||||
-- GetInventoryItemID actually returns the transmogged-into item for inspect units
|
||||
mog:AddToPreview(GetInventoryItemID(InspectFrame.unit, self:GetID()));
|
||||
else
|
||||
HandleModifiedItemClick(GetInventoryItemLink(InspectFrame.unit, self:GetID()));
|
||||
end
|
||||
end
|
||||
for k, v in ipairs(mog.slots) do
|
||||
_G["Inspect"..v]:RegisterForClicks("AnyUp");
|
||||
_G["Inspect"..v]:SetScript("OnClick", onClick);
|
||||
end
|
||||
hookInspectUI = nil;
|
||||
end
|
||||
|
||||
if InspectFrame then
|
||||
hookInspectUI();
|
||||
else
|
||||
mog.view:SetScript("OnEvent",function(self,event,addon)
|
||||
if addon == "Blizzard_InspectUI" then
|
||||
hookInspectUI();
|
||||
self:UnregisterEvent(event);
|
||||
self:SetScript("OnEvent", nil);
|
||||
end
|
||||
end);
|
||||
mog.view:RegisterEvent("ADDON_LOADED");
|
||||
end
|
||||
--//
|
||||
|
||||
|
||||
--// Popups
|
||||
local function onAccept(self,preview)
|
||||
local text = self.editBox:GetText();
|
||||
text = text and text:match("(%d+).-$");
|
||||
mog:AddToPreview(tonumber(text),preview);
|
||||
end
|
||||
|
||||
StaticPopupDialogs["MOGIT_PREVIEW_ADDITEM"] = {
|
||||
text = L["Type the item ID or url in the text box below"],
|
||||
button1 = ADD,
|
||||
button2 = CANCEL,
|
||||
hasEditBox = 1,
|
||||
maxLetters = 512,
|
||||
editBoxWidth = 260,
|
||||
OnAccept = onAccept,
|
||||
EditBoxOnEnterPressed = function(self, data)
|
||||
local parent = self:GetParent();
|
||||
onAccept(parent, data);
|
||||
parent:Hide();
|
||||
end,
|
||||
EditBoxOnEscapePressed = function(self)
|
||||
self:GetParent():Hide();
|
||||
end,
|
||||
timeout = 0,
|
||||
exclusive = 1,
|
||||
whileDead = 1,
|
||||
};
|
||||
|
||||
local function onAccept(self,preview)
|
||||
local items = self.editBox:GetText();
|
||||
items = items and items:match("compare%?items=([^;#]+)");
|
||||
if items then
|
||||
local tbl = {};
|
||||
for item in items:gmatch("([^:]+)") do
|
||||
item = item:match("^(%d+)");
|
||||
table.insert(tbl,tonumber(item));
|
||||
end
|
||||
mog:AddToPreview(tbl,preview);
|
||||
end
|
||||
end
|
||||
|
||||
StaticPopupDialogs["MOGIT_PREVIEW_IMPORT"] = {
|
||||
text = L["Copy and paste a Wowhead Compare URL into the text box below to import"],
|
||||
button1 = L["Import"],
|
||||
button2 = CANCEL,
|
||||
hasEditBox = 1,
|
||||
maxLetters = 512,
|
||||
editBoxWidth = 260,
|
||||
OnShow = function(self,preview)
|
||||
local str;
|
||||
for k,v in pairs(preview.slots) do
|
||||
if v.item then
|
||||
if str then
|
||||
str = str..":"..v.item;
|
||||
else
|
||||
str = L["http://www.wowhead.com/"].."compare?items="..v.item;
|
||||
end
|
||||
end
|
||||
end
|
||||
self.editBox:SetText(str or "");
|
||||
self.editBox:HighlightText();
|
||||
end,
|
||||
OnAccept = onAccept,
|
||||
EditBoxOnEnterPressed = function(self, data)
|
||||
local parent = self:GetParent();
|
||||
onAccept(parent, data);
|
||||
parent:Hide();
|
||||
end,
|
||||
EditBoxOnEscapePressed = function(self)
|
||||
self:GetParent():Hide();
|
||||
end,
|
||||
timeout = 0,
|
||||
exclusive = 1,
|
||||
whileDead = 1,
|
||||
};
|
||||
|
||||
StaticPopupDialogs["MOGIT_PREVIEW_CLOSE"] = {
|
||||
text = L["Are you sure you want to close this set?"],
|
||||
button1 = YES,
|
||||
button2 = NO,
|
||||
OnAccept = function(self, frame)
|
||||
mog:DeletePreview(frame);
|
||||
end,
|
||||
hideOnEscape = true,
|
||||
whileDead = true,
|
||||
timeout = 0,
|
||||
}
|
||||
32
MogIt/Core/Sorting/Sorting.lua
Normal file
@@ -0,0 +1,32 @@
|
||||
local MogIt, mog = ...;
|
||||
local L = mog.L;
|
||||
|
||||
mog.sorting = {};
|
||||
|
||||
function mog:CreateSort(name, data)
|
||||
data = data or {};
|
||||
data.name = name;
|
||||
mog.sorting[name] = data;
|
||||
end
|
||||
|
||||
function mog:GetSort(name)
|
||||
return mog.sorting[name];
|
||||
end
|
||||
|
||||
function mog:GetActiveSort()
|
||||
return mog.sorting.active;
|
||||
end
|
||||
|
||||
function mog:SortList(new, update)
|
||||
if mog.active and mog.active.sorting and #mog.active.sorting > 0 then
|
||||
new = new or (mog.active.sorts[mog.sorting.active] and mog.sorting.active) or mog.active.sorting[1];
|
||||
if mog.sorting.active and (mog.sorting.active ~= new) and mog.sorting[mog.sorting.active].Unlist then
|
||||
mog.sorting[mog.sorting.active].Unlist();
|
||||
end
|
||||
mog.sorting.active = new;
|
||||
mog.sorting[new].Sort(mog.active.sorts[new]);
|
||||
if not update then
|
||||
mog.scroll:update();
|
||||
end
|
||||
end
|
||||
end
|
||||
13
MogIt/Core/Sorting/Sorting.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Ui xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.blizzard.com/wow/ui/" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
..\FrameXML\UI.xsd">
|
||||
|
||||
<Script file="Sorting.lua"/>
|
||||
|
||||
<Script file="level.lua"/>
|
||||
<Script file="itemLevel.lua"/>
|
||||
<Script file="display.lua"/>
|
||||
<Script file="id.lua"/>
|
||||
<Script file="colour.lua"/>
|
||||
|
||||
</Ui>
|
||||
63
MogIt/Core/Sorting/colour.lua
Normal file
@@ -0,0 +1,63 @@
|
||||
local MogIt,mog = ...;
|
||||
local L = mog.L;
|
||||
|
||||
local colourCache = {};
|
||||
local cR,cG,cB = 255,255,255;
|
||||
local function colourScore(id,args)
|
||||
if not colourCache[id] then
|
||||
local distance = 195075;
|
||||
local colours = args and args(id);
|
||||
if colours then
|
||||
for k,v in pairs(colours) do
|
||||
local r,g,b = v:match("^(..)(..)(..)$");
|
||||
r = tonumber(r,16);
|
||||
g = tonumber(g,16);
|
||||
b = tonumber(b,16);
|
||||
local dist = ((cR-r)^2)+((cG-g)^2)+((cB-b)^2);
|
||||
if dist < distance then
|
||||
distance = dist;
|
||||
end
|
||||
end
|
||||
end
|
||||
colourCache[id] = distance;
|
||||
end
|
||||
return colourCache[id];
|
||||
end
|
||||
|
||||
local function dropdownTier1(self)
|
||||
mog:SortList("colour");
|
||||
end
|
||||
|
||||
local function swatchFunc()
|
||||
if not ColorPickerFrame:IsShown() then
|
||||
local r,g,b = ColorPickerFrame:GetColorRGB();
|
||||
cR,cG,cB = r*255,g*255,b*255;
|
||||
mog:SortList("colour");
|
||||
end
|
||||
end
|
||||
|
||||
mog:CreateSort("colour",{
|
||||
label = L["Approximate Colour"],
|
||||
Dropdown = function(dropdown,module,tier)
|
||||
local info = UIDropDownMenu_CreateInfo();
|
||||
info.text = L["Approximate Colour"];
|
||||
info.value = "colour";
|
||||
info.func = dropdownTier1;
|
||||
info.checked = mog.sorting.active == "colour";
|
||||
info.hasColorSwatch = true;
|
||||
info.r = cR/255;
|
||||
info.g = cG/255;
|
||||
info.b = cB/255;
|
||||
info.swatchFunc = swatchFunc;
|
||||
dropdown:AddButton(info,tier);
|
||||
end,
|
||||
Sort = function(args)
|
||||
wipe(colourCache);
|
||||
table.sort(mog.list,function(a,b)
|
||||
return colourScore(a,args) < colourScore(b,args);
|
||||
end);
|
||||
end,
|
||||
Unlist = function()
|
||||
wipe(colourCache);
|
||||
end,
|
||||
});
|
||||
25
MogIt/Core/Sorting/display.lua
Normal file
@@ -0,0 +1,25 @@
|
||||
local MogIt,mog = ...;
|
||||
local L = mog.L;
|
||||
|
||||
local function dropdownTier1(self)
|
||||
mog:SortList("display");
|
||||
end
|
||||
|
||||
local function displayIDSort(a, b)
|
||||
return mog:GetData("item", a[1], "display") > mog:GetData("item", b[1], "display");
|
||||
end
|
||||
|
||||
mog:CreateSort("display",{
|
||||
label = L["Display ID"],
|
||||
Dropdown = function(dropdown,module,tier)
|
||||
local info = UIDropDownMenu_CreateInfo();
|
||||
info.text = L["Display ID"];
|
||||
info.value = "display";
|
||||
info.func = dropdownTier1;
|
||||
info.checked = mog.sorting.active == "display";
|
||||
dropdown:AddButton(info,tier);
|
||||
end,
|
||||
Sort = function(args)
|
||||
table.sort(mog.list, displayIDSort);
|
||||
end,
|
||||
});
|
||||
25
MogIt/Core/Sorting/id.lua
Normal file
@@ -0,0 +1,25 @@
|
||||
local MogIt,mog = ...;
|
||||
local L = mog.L;
|
||||
|
||||
local function dropdownTier1(self)
|
||||
mog:SortList("id");
|
||||
end
|
||||
|
||||
local function displayIDSort(a, b)
|
||||
return mog:GetData("item", a[1], "id") > mog:GetData("item", b[1], "id");
|
||||
end
|
||||
|
||||
mog:CreateSort("id",{
|
||||
label = L["Item ID"],
|
||||
Dropdown = function(dropdown,module,tier)
|
||||
local info = UIDropDownMenu_CreateInfo();
|
||||
info.text = L["Item ID"];
|
||||
info.value = "id";
|
||||
info.func = dropdownTier1;
|
||||
info.checked = mog.sorting.active == "id";
|
||||
dropdown:AddButton(info,tier);
|
||||
end,
|
||||
Sort = function(args)
|
||||
table.sort(mog.list, displayIDSort);
|
||||
end,
|
||||
});
|
||||
25
MogIt/Core/Sorting/itemLevel.lua
Normal file
@@ -0,0 +1,25 @@
|
||||
local MogIt,mog = ...;
|
||||
local L = mog.L;
|
||||
|
||||
local function dropdownTier1(self)
|
||||
mog:SortList("itemLevel");
|
||||
end
|
||||
|
||||
local function itemLevelSort(a, b)
|
||||
return mog:GetData("item", a[1], "itemLevel") > mog:GetData("item", b[1], "itemLevel");
|
||||
end
|
||||
|
||||
mog:CreateSort("itemLevel",{
|
||||
label = L["Item Level"],
|
||||
Dropdown = function(dropdown,module,tier)
|
||||
local info = UIDropDownMenu_CreateInfo();
|
||||
info.text = L["Item Level"];
|
||||
info.value = "itemLevel";
|
||||
info.func = dropdownTier1;
|
||||
info.checked = mog.sorting.active == "itemLevel";
|
||||
dropdown:AddButton(info,tier);
|
||||
end,
|
||||
Sort = function(args)
|
||||
table.sort(mog.list, itemLevelSort);
|
||||
end,
|
||||
});
|
||||
45
MogIt/Core/Sorting/level.lua
Normal file
@@ -0,0 +1,45 @@
|
||||
local MogIt, mog = ...;
|
||||
local L = mog.L;
|
||||
|
||||
local itemCache = {};
|
||||
|
||||
local function minItem(items)
|
||||
local minLevel
|
||||
for i, v in ipairs(items) do
|
||||
local reqLevel = itemCache[v] or mog:GetData("item", v, "level");
|
||||
if reqLevel then
|
||||
itemCache[v] = reqLevel;
|
||||
minLevel = min(reqLevel, minLevel or reqLevel);
|
||||
end
|
||||
end
|
||||
return minLevel or 0;
|
||||
end
|
||||
|
||||
local function dropdownTier1(self)
|
||||
mog:SortList("level");
|
||||
end
|
||||
|
||||
local function levelSort(a, b)
|
||||
local aLv, bLv = minItem(a), minItem(b);
|
||||
if aLv == bLv then
|
||||
return mog:GetData("item", a[1], "id") > mog:GetData("item", b[1], "id");
|
||||
else
|
||||
return aLv > bLv;
|
||||
end
|
||||
end
|
||||
|
||||
mog:CreateSort("level", {
|
||||
label = LEVEL,
|
||||
Dropdown = function(dropdown,module,tier)
|
||||
local info;
|
||||
info = UIDropDownMenu_CreateInfo();
|
||||
info.text = LEVEL;
|
||||
info.value = "level";
|
||||
info.func = dropdownTier1;
|
||||
info.checked = mog.sorting.active == "level";
|
||||
dropdown:AddButton(info, tier);
|
||||
end,
|
||||
Sort = function()
|
||||
table.sort(mog.list, levelSort);
|
||||
end,
|
||||
});
|
||||
564
MogIt/Core/Templates.lua
Normal file
@@ -0,0 +1,564 @@
|
||||
local MogIt, mog = ...
|
||||
local L = mog.L
|
||||
|
||||
local TEXTURE = [[Interface\RaidFrame\ReadyCheck-Ready]]
|
||||
|
||||
local function getTexture(hasItem, embedded)
|
||||
local texture = hasItem and TEXTURE or ""
|
||||
return embedded and format("|T%s:0|t ", texture) or texture
|
||||
end
|
||||
|
||||
local itemQualityColor = {
|
||||
[0] = "9d9d9d",
|
||||
[1] = "ffffff",
|
||||
[2] = "1eff00",
|
||||
[3] = "0070dd",
|
||||
[4] = "a335ee",
|
||||
[5] = "ff8000",
|
||||
[6] = "e6cc80",
|
||||
[7] = "e6cc80"
|
||||
}
|
||||
|
||||
function mog:GetItemLabel(itemID, callback, includeIcon, iconSize)
|
||||
local name,_,quality = GetItemInfo(itemID)
|
||||
local itemname = mog:GetData("item", itemID, "itemname")
|
||||
local itemquality = mog:GetData("item", itemID, "quality")
|
||||
local includeIcon = GetItemIcon(itemID)
|
||||
|
||||
-- Uncached items will revert to local database and show an asterisk next to them. Non-existent items will not show an icon.
|
||||
-- GetItemInfo requires the item to be in the cache. GetItemIcon does not.
|
||||
return (includeIcon and "|T"..GetItemIcon(itemID)..":"..(iconSize or "32") .."|t" or "")..
|
||||
(name and "|cff"..itemQualityColor[quality].." "..name .."|r" or itemname and "|cff"..itemQualityColor[itemquality].." "..itemname .."|r"..RED_FONT_COLOR_CODE.."*" )
|
||||
end
|
||||
|
||||
local function addTooltipDoubleLine(textLeft, textRight)
|
||||
GameTooltip:AddDoubleLine(textLeft, textRight, nil, nil, nil, 1, 1, 1)
|
||||
end
|
||||
|
||||
local function addItemTooltipLine(itemID)
|
||||
addTooltipDoubleLine(getTexture(mog:HasItem(itemID), true)..mog:GetItemLabel(itemID, "ModelOnEnter"), mog.GetItemSourceShort(itemID))
|
||||
end
|
||||
|
||||
function mog.GetItemSourceInfo(itemID)
|
||||
local source, info;
|
||||
local sourceType = mog:GetData("item", itemID, "source");
|
||||
local sourceID = mog:GetData("item", itemID, "sourceid");
|
||||
local sourceInfo = mog:GetData("item", itemID, "sourceinfo");
|
||||
|
||||
if sourceType == 1 and sourceID then -- Drop
|
||||
source = mog:GetData("npc", sourceID, "name");
|
||||
-- IsQuestFlaggedCompleted is a MoP API. WotLK has GetQuestsCompleted which returns all quests (option?)
|
||||
-- elseif sourceType == 3 and sourceID then -- Quest
|
||||
-- info = IsQuestFlaggedCompleted(sourceID) or false;
|
||||
-- info = false
|
||||
elseif sourceType == 5 and sourceInfo then -- Crafted
|
||||
source = L.professions[sourceInfo];
|
||||
elseif sourceType == 6 and sourceID then -- Achievement
|
||||
local _, name, _, complete = GetAchievementInfo(sourceID);
|
||||
source = name;
|
||||
info = complete;
|
||||
end
|
||||
|
||||
local zone = mog:GetData("item", itemID, "zone");
|
||||
if zone then
|
||||
--zone = GetMapNameByID(zone);
|
||||
SetMapByID(zone)
|
||||
zone = GetMapInfo()
|
||||
SetMapByID(GetCurrentMapAreaID())
|
||||
if zone then
|
||||
local diff = L.diffs[sourceInfo];
|
||||
if sourceType == 1 and diff then
|
||||
zone = format("%s (%s)", zone, diff);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return L.source[sourceType], source, zone, info;
|
||||
end
|
||||
|
||||
function mog.GetItemSourceShort(itemID)
|
||||
local sourceType, source, zone, info = mog.GetItemSourceInfo(itemID);
|
||||
if zone then
|
||||
if source then
|
||||
sourceType = source;
|
||||
end
|
||||
source = zone;
|
||||
if sourceType == L.source[3] then
|
||||
source = format("%s (%s)", source, sourceType)
|
||||
end
|
||||
end
|
||||
return source or sourceType
|
||||
end
|
||||
|
||||
-- create a new set and add the item to it
|
||||
local function previewOnClick(self, previewFrame)
|
||||
mog:AddToPreview(self.value, mog:GetPreview(previewFrame))
|
||||
CloseDropDownMenus()
|
||||
end
|
||||
|
||||
-- create a new set and add the item to it
|
||||
local function newSetOnClick(self)
|
||||
StaticPopup_Show("MOGIT_WISHLIST_CREATE_SET", nil, nil, self.value)
|
||||
CloseDropDownMenus()
|
||||
end
|
||||
|
||||
local previewItem = {
|
||||
text = L["Preview"],
|
||||
-- hasArrow = true,
|
||||
menuList = function(level)
|
||||
local info = UIDropDownMenu_CreateInfo()
|
||||
info.text = L["Active preview"]
|
||||
info.value = UIDROPDOWNMENU_MENU_VALUE
|
||||
info.func = previewOnClick
|
||||
info.disabled = not mog.activePreview
|
||||
info.notCheckable = true
|
||||
info.arg1 = mog.activePreview
|
||||
UIDropDownMenu_AddButton(info, level)
|
||||
|
||||
for i, preview in ipairs(mog.previews) do
|
||||
local info = UIDropDownMenu_CreateInfo()
|
||||
info.text = format("%s %d", L["Preview"], preview:GetID())
|
||||
info.value = UIDROPDOWNMENU_MENU_VALUE
|
||||
info.func = previewOnClick
|
||||
info.notCheckable = true
|
||||
info.arg1 = preview
|
||||
UIDropDownMenu_AddButton(info, level)
|
||||
end
|
||||
|
||||
local info = UIDropDownMenu_CreateInfo()
|
||||
info.text = L["New preview"]
|
||||
info.value = UIDROPDOWNMENU_MENU_VALUE
|
||||
info.func = previewOnClick
|
||||
info.notCheckable = true
|
||||
UIDropDownMenu_AddButton(info, level)
|
||||
end,
|
||||
}
|
||||
|
||||
local itemOptionsMenu = {
|
||||
previewItem,
|
||||
{
|
||||
text = L["Add to wishlist"],
|
||||
func = function(self)
|
||||
mog.wishlist:AddItem(self.value)
|
||||
mog:BuildList()
|
||||
CloseDropDownMenus()
|
||||
end,
|
||||
},
|
||||
{
|
||||
text = L["Add to set"],
|
||||
hasArrow = true,
|
||||
menuList = function(level)
|
||||
mog.wishlist:AddSetMenuItems(level, "addItem", UIDROPDOWNMENU_MENU_VALUE)
|
||||
|
||||
local info = UIDropDownMenu_CreateInfo()
|
||||
info.text = L["New set"]
|
||||
info.value = UIDROPDOWNMENU_MENU_VALUE
|
||||
info.func = newSetOnClick
|
||||
info.colorCode = GREEN_FONT_COLOR_CODE
|
||||
info.notCheckable = true
|
||||
UIDropDownMenu_AddButton(info, level)
|
||||
end,
|
||||
},
|
||||
{
|
||||
wishlist = true,
|
||||
text = L["Delete"],
|
||||
func = function(self, set)
|
||||
mog.wishlist:DeleteItem(self.value, set.name)
|
||||
mog:BuildList(nil, "Wishlist")
|
||||
CloseDropDownMenus()
|
||||
end,
|
||||
},
|
||||
}
|
||||
|
||||
function mog:SetPreviewMenu(isSinglePreview)
|
||||
if isSinglePreview then
|
||||
previewItem.func = previewOnClick
|
||||
previewItem.hasArrow = nil
|
||||
else
|
||||
previewItem.func = nil
|
||||
previewItem.hasArrow = true
|
||||
end
|
||||
end
|
||||
|
||||
function mog:AddItemOption(info)
|
||||
tinsert(itemOptionsMenu, info)
|
||||
end
|
||||
|
||||
local function createItemMenu(dropdown, data, func)
|
||||
local items = data.items
|
||||
-- not listing the items if it's only 1 and it's not a set
|
||||
if not items or (data.item and #items == 1) then
|
||||
return
|
||||
end
|
||||
local isArray = #items > 0
|
||||
|
||||
for i, v in ipairs(isArray and items or mog.slots) do
|
||||
v = isArray and v or items[v]
|
||||
if v then
|
||||
local info = UIDropDownMenu_CreateInfo()
|
||||
info.text = mog:GetItemLabel(v, func and "ItemMenu" or "SetMenu")
|
||||
info.value = v
|
||||
info.func = func
|
||||
info.checked = (i == data.cycle)
|
||||
info.hasArrow = true
|
||||
info.notCheckable = data.isSaved or data.name
|
||||
info.arg1 = data
|
||||
info.arg2 = i
|
||||
info.menuList = itemOptionsMenu
|
||||
dropdown:AddButton(info)
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function createMenu(self, level, menuList)
|
||||
local data = self.data
|
||||
if type(menuList) == "function" then
|
||||
menuList(level)
|
||||
else
|
||||
for i, info in ipairs(menuList) do
|
||||
if (info.wishlist == nil or info.wishlist == data.isSaved) and (not info.set or data.items) then
|
||||
info.value = UIDROPDOWNMENU_MENU_VALUE
|
||||
info.notCheckable = true
|
||||
info.arg1 = data
|
||||
self:AddButton(info, level)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local slots = {
|
||||
[1] = "MainHandSlot",
|
||||
-- [2] = "mainhand",
|
||||
-- [3] = "offhand",
|
||||
}
|
||||
|
||||
function mog.Item_FrameUpdate(self, data)
|
||||
self:ApplyDress()
|
||||
self:TryOn(("item:".. data.item.. (mog.weaponEnchant and ":"..mog.weaponEnchant or "")), slots[mog:GetData("item", data.item, "slot")])
|
||||
end
|
||||
|
||||
local sourceLabels = {
|
||||
[L.source[1]] = BOSS,
|
||||
}
|
||||
|
||||
GameTooltip:RegisterEvent("MODIFIER_STATE_CHANGED")
|
||||
GameTooltip:HookScript("OnEvent", function(self, event, key, state)
|
||||
local owner = self:GetOwner()
|
||||
if owner and self[mog] then
|
||||
owner:OnEnter()
|
||||
end
|
||||
end)
|
||||
GameTooltip:HookScript("OnTooltipCleared", function(self)
|
||||
self[mog] = nil
|
||||
end)
|
||||
|
||||
local class_HEXcolors = {
|
||||
["HUNTER"] = "ffabd473",
|
||||
["WARLOCK"] = "ff9482c9",
|
||||
["PRIEST"] = "ffffffff",
|
||||
["PALADIN"] = "fff58cba",
|
||||
["MAGE"] = "ff69ccf0",
|
||||
["ROGUE"] = "fffff569",
|
||||
["DRUID"] = "ffff7d0a",
|
||||
["SHAMAN"] = "ff0070de",
|
||||
["WARRIOR"] = "ffc79c6e",
|
||||
["DEATHKNIGHT"] = "ffc41f3b",
|
||||
}
|
||||
function mog.ShowItemTooltip(self, item, items, cycle)
|
||||
GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
|
||||
GameTooltip[mog] = true
|
||||
local l
|
||||
if IsAltKeyDown() then
|
||||
GameTooltip:SetHyperlink('|Hitem:'..item..'|h')
|
||||
l = true
|
||||
if cycle and #items > 1 then GameTooltip:AddLine(" ") GameTooltip:AddDoubleLine("", L["Item %d/%d"]:format(cycle, #items), nil, nil, nil, 1, 0, 0) end
|
||||
end
|
||||
|
||||
if not l then
|
||||
-- Reverts to local database if item isn't cached
|
||||
local itemLevel = (select(4,GetItemInfo(item))) or mog:GetData("item", item, "itemlevel")
|
||||
local itemLabel = mog:GetItemLabel(item, "ModelOnEnter")
|
||||
if cycle and #items > 1 then
|
||||
GameTooltip:AddDoubleLine(itemLabel, L["Item %d/%d"]:format(cycle, #items), nil, nil, nil, 1, 0, 0)
|
||||
else
|
||||
GameTooltip:AddLine(itemLabel)
|
||||
end
|
||||
|
||||
local bindType = mog:GetData("item", item, "bind")
|
||||
if bindType then
|
||||
addTooltipDoubleLine(L["Bind"]..":", L.bind[bindType])
|
||||
end
|
||||
-- Can't use GetItemInfo on LevelReq due to many quest items not having one
|
||||
local requiredLevel = mog:GetData("item", item, "level")
|
||||
if requiredLevel then
|
||||
addTooltipDoubleLine(LEVEL..":", requiredLevel)
|
||||
end
|
||||
addTooltipDoubleLine("Item level:", itemLevel)
|
||||
local faction = mog:GetData("item", item, "faction")
|
||||
if faction then
|
||||
addTooltipDoubleLine(FACTION..":", (faction == 1 and FACTION_ALLIANCE or FACTION_HORDE))
|
||||
end
|
||||
local class = mog:GetData("item", item, "class")
|
||||
if class and class > 0 then
|
||||
local str
|
||||
for k, v in pairs(L.classBits) do
|
||||
if bit.band(class, v) > 0 then
|
||||
local color = class_HEXcolors[k]
|
||||
local name = LOCALIZED_CLASS_NAMES_MALE[k]
|
||||
if color and name then
|
||||
if str then
|
||||
str = format("%s, |c%s%s|r", str, color, name)
|
||||
else
|
||||
str = format("|c%s%s|r", color, name)
|
||||
end
|
||||
else print("Error: MogIt\Core\Template.lua:316 ", color,name )
|
||||
end
|
||||
end
|
||||
end
|
||||
addTooltipDoubleLine(CLASS..":", str)
|
||||
end
|
||||
local slot = mog:GetData("item", item, "slot")
|
||||
if slot then
|
||||
addTooltipDoubleLine(L["Slot"]..":", L.slots[slot])
|
||||
end
|
||||
end
|
||||
GameTooltip:AddLine(" ")
|
||||
local sourceType, source, zone, info = mog.GetItemSourceInfo(item)
|
||||
if sourceType then
|
||||
addTooltipDoubleLine(L["Source"]..":", sourceType)
|
||||
if source then
|
||||
addTooltipDoubleLine((sourceLabels[sourceType] or sourceType)..":", source)
|
||||
end
|
||||
if info ~= nil then
|
||||
addTooltipDoubleLine(STATUS..":", info and COMPLETE or INCOMPLETE)
|
||||
end
|
||||
end
|
||||
if zone then
|
||||
addTooltipDoubleLine(ZONE..":", zone)
|
||||
end
|
||||
|
||||
GameTooltip:AddLine(" ")
|
||||
addTooltipDoubleLine(ID..":", item)
|
||||
|
||||
if mog:HasItem(item) then
|
||||
GameTooltip:AddLine(" ")
|
||||
GameTooltip:AddLine(L["You have this item."], 1, 1, 1)
|
||||
GameTooltip:AddTexture(TEXTURE)
|
||||
end
|
||||
|
||||
if (not mog.active or mog.active.name ~= "Wishlist") and mog.wishlist:IsItemInWishlist(item) then
|
||||
if not mog:HasItem(item) then
|
||||
GameTooltip:AddLine(" ")
|
||||
end
|
||||
GameTooltip:AddLine(L["This item is on your wishlist."], 1, 1, 1)
|
||||
GameTooltip:AddTexture("Interface\\TargetingFrame\\UI-RaidTargetingIcon_1")
|
||||
end
|
||||
|
||||
if items and #items > 1 then
|
||||
GameTooltip:AddLine(" ")
|
||||
GameTooltip:AddLine(L["Other items using this appearance:"])
|
||||
for i, v in ipairs(items) do
|
||||
if v ~= item then
|
||||
addItemTooltipLine(v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if l and AtlasLoot then
|
||||
if AtlasLoot.db.profile.SearchOn.All then
|
||||
AtlasLoot_LoadAllModules();
|
||||
else
|
||||
for k, v in pairs(AtlasLoot.db.profile.SearchOn) do
|
||||
if k ~= "All" and v == true and not IsAddOnLoaded(k) and LoadAddOn(k) and self.db.profile.LoDNotify then
|
||||
--DEFAULT_CHAT_FRAME:AddMessage(GREEN..AL["AtlasLoot"]..": "..ORANGE..k..WHITE.." "..AL["sucessfully loaded."]);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for dataID, data in pairs(AtlasLoot_Data) do
|
||||
for _, v in ipairs(data) do
|
||||
local id = v[2]
|
||||
if item == id then
|
||||
local a = AtlasLoot_TableNames[dataID] and AtlasLoot_TableNames[dataID][1] or "Argh!"
|
||||
GameTooltip:AddLine(" ");
|
||||
GameTooltip:AddDoubleLine("|cff6578ffAtlasLoot: |cffffff00"..a, dataID, nil, nil, nil, 1, 1, 1);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
GameTooltip:Show()
|
||||
end
|
||||
|
||||
local function showMenu(menu, data, isSaved)
|
||||
if menu:IsShown() and menu.data ~= data then
|
||||
HideDropDownMenu(1)
|
||||
end
|
||||
-- needs to be either true or false
|
||||
data.isSaved = isSaved ~= nil
|
||||
menu.data = data
|
||||
menu:Toggle(data.item, "cursor")
|
||||
end
|
||||
|
||||
function mog.Item_OnClick(self, btn, data, isSaved)
|
||||
local item = data.item
|
||||
if not (self and item) then return end
|
||||
|
||||
if btn == "LeftButton" then
|
||||
if (not HandleModifiedItemClick(select(2, GetItemInfo(item))) or IsAltKeyDown()) and data.items then
|
||||
data.cycle = (data.cycle % #data.items) + 1
|
||||
data.item = data.items[data.cycle]
|
||||
self:OnEnter()
|
||||
end
|
||||
elseif btn == "RightButton" then
|
||||
if IsControlKeyDown() then
|
||||
mog:AddToPreview(item)
|
||||
elseif IsShiftKeyDown() then
|
||||
mog:ShowURL(item)
|
||||
else
|
||||
showMenu(mog.Item_Menu, data, isSaved)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local function itemOnClick(self, data, index)
|
||||
data.cycle = index
|
||||
data.item = data.items[index]
|
||||
end
|
||||
|
||||
mog.Item_Menu = mog:CreateDropdown("Menu")
|
||||
mog.Item_Menu.initialize = function(self, level, menuList)
|
||||
local data = self.data
|
||||
|
||||
if not menuList then
|
||||
if not createItemMenu(self, data, itemOnClick) then
|
||||
-- this is a single item, so skip directly to the item options menu
|
||||
createMenu(self, level, itemOptionsMenu)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
createMenu(self, level, menuList)
|
||||
end
|
||||
end
|
||||
|
||||
function mog.Set_FrameUpdate(self, data)
|
||||
self:ShowIndicator("label")
|
||||
self:SetText(data.name)
|
||||
self:Undress()
|
||||
for k, v in pairs(data.items) do
|
||||
self:TryOn(v, k)
|
||||
end
|
||||
end
|
||||
|
||||
function mog.ShowSetTooltip(self, items, name)
|
||||
GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
|
||||
GameTooltip[mog] = true
|
||||
|
||||
GameTooltip:AddLine(name)
|
||||
for i, slot in ipairs(mog.slots) do
|
||||
local itemID = items[slot] or items[i]
|
||||
if itemID then
|
||||
addItemTooltipLine(itemID)
|
||||
end
|
||||
end
|
||||
GameTooltip:Show()
|
||||
end
|
||||
|
||||
function mog.Set_OnClick(self, btn, data, isSaved)
|
||||
if btn == "LeftButton" then
|
||||
if IsShiftKeyDown() then
|
||||
ChatEdit_InsertLink(mog:SetToLink(data.items))
|
||||
elseif IsControlKeyDown() then
|
||||
if mog.db.profile.dressupPreview then
|
||||
mog:AddToPreview(data.items, mog:GetPreview())
|
||||
else
|
||||
if not DressUpFrame:IsShown() or DressUpFrame.mode ~= "player" then
|
||||
DressUpFrame.mode = "player"
|
||||
-- DressUpFrame.ResetButton:Show()
|
||||
|
||||
local race, fileName = UnitRace("player")
|
||||
SetDressUpBackground(DressUpFrame, fileName)
|
||||
|
||||
ShowUIPanel(DressUpFrame)
|
||||
DressUpModel:SetUnit("player")
|
||||
end
|
||||
DressUpModel:Undress()
|
||||
for k, v in pairs(data.items) do
|
||||
DressUpItemLink(v)
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif btn == "RightButton" then
|
||||
if IsShiftKeyDown() then
|
||||
if data.set then
|
||||
mog:ShowURL(data.set, "set")
|
||||
else
|
||||
mog:ShowURL(data.items, "compare")
|
||||
end
|
||||
elseif IsControlKeyDown() then
|
||||
mog:AddToPreview(data.items, mog:GetPreview())
|
||||
else
|
||||
showMenu(mog.Set_Menu, data, isSaved)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local setMenu = {
|
||||
{
|
||||
wishlist = false,
|
||||
text = L["Add set to wishlist"],
|
||||
func = function(self, set, items)
|
||||
local create = mog.wishlist:CreateSet(set)
|
||||
if create then
|
||||
for i, itemID in pairs(items) do
|
||||
mog.wishlist:AddItem(itemID, set)
|
||||
end
|
||||
end
|
||||
end,
|
||||
},
|
||||
{
|
||||
wishlist = true,
|
||||
text = L["Rename set"],
|
||||
func = function(self, set)
|
||||
mog.wishlist:RenameSet(set)
|
||||
end,
|
||||
},
|
||||
{
|
||||
wishlist = true,
|
||||
text = L["Delete set"],
|
||||
func = function(self, set)
|
||||
mog.wishlist:DeleteSet(set)
|
||||
end,
|
||||
},
|
||||
}
|
||||
|
||||
function mog:AddSetOption(info)
|
||||
tinsert(setMenu, info)
|
||||
end
|
||||
|
||||
mog.Set_Menu = mog:CreateDropdown("Menu")
|
||||
mog.Set_Menu.initialize = function(self, level, menuList)
|
||||
local data = self.data
|
||||
|
||||
if not menuList then
|
||||
createItemMenu(self, data)
|
||||
|
||||
for i, info in ipairs(setMenu) do
|
||||
if info.wishlist == nil or info.wishlist == data.isSaved then
|
||||
info.value = data.name
|
||||
info.notCheckable = true
|
||||
info.arg1 = data.name
|
||||
info.arg2 = data.items
|
||||
self:AddButton(info, level)
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
createMenu(self, level, menuList)
|
||||
end
|
||||
end
|
||||
215
MogIt/Core/Tooltip.lua
Normal file
@@ -0,0 +1,215 @@
|
||||
local MogIt,mog = ...;
|
||||
local L = mog.L;
|
||||
|
||||
local IsDressableItem = IsDressableItem;
|
||||
local GetScreenWidth = GetScreenWidth;
|
||||
local GetScreenHeight = GetScreenHeight;
|
||||
|
||||
local class = L.classBits[select(2,UnitClass("PLAYER"))];
|
||||
|
||||
|
||||
--// Tooltip
|
||||
mog.tooltip = CreateFrame("Frame","MogItTooltip",UIParent,"TooltipBorderedFrameTemplate");
|
||||
mog.tooltip:Hide();
|
||||
mog.tooltip:SetClampedToScreen(true);
|
||||
mog.tooltip:SetFrameStrata("TOOLTIP");
|
||||
|
||||
mog.tooltip:SetScript("OnShow",function(self)
|
||||
if mog.db.profile.tooltipMouse and not InCombatLockdown() then
|
||||
SetOverrideBinding(mog.tooltip,true,"MOUSEWHEELUP","MogIt_TooltipScrollUp");
|
||||
SetOverrideBinding(mog.tooltip,true,"MOUSEWHEELDOWN","MogIt_TooltipScrollDown");
|
||||
end
|
||||
end);
|
||||
|
||||
mog.tooltip:SetScript("OnHide",function(self)
|
||||
if not InCombatLockdown() then
|
||||
ClearOverrideBindings(mog.tooltip);
|
||||
end
|
||||
end);
|
||||
|
||||
mog.tooltip:SetScript("OnEvent", function(self, event, arg1)
|
||||
if event == "PLAYER_LOGIN" then
|
||||
mog.tooltip.model:SetUnit("player");
|
||||
elseif event == "PLAYER_REGEN_DISABLED" then
|
||||
ClearOverrideBindings(mog.tooltip);
|
||||
elseif event == "PLAYER_REGEN_ENABLED" then
|
||||
if self:IsShown() and mog.db.profile.tooltipMouse then
|
||||
SetOverrideBinding(mog.tooltip,true,"MOUSEWHEELUP","MogIt_TooltipScrollUp");
|
||||
SetOverrideBinding(mog.tooltip,true,"MOUSEWHEELDOWN","MogIt_TooltipScrollDown");
|
||||
end
|
||||
end
|
||||
end);
|
||||
mog.tooltip:RegisterEvent("PLAYER_LOGIN");
|
||||
mog.tooltip:RegisterEvent("PLAYER_REGEN_DISABLED");
|
||||
mog.tooltip:RegisterEvent("PLAYER_REGEN_ENABLED");
|
||||
--//
|
||||
|
||||
|
||||
--// Model
|
||||
mog.tooltip.model = CreateFrame("DressUpModel",nil,mog.tooltip);
|
||||
mog.tooltip.model:SetPoint("TOPLEFT",mog.tooltip,"TOPLEFT",5,-5);
|
||||
mog.tooltip.model:SetPoint("BOTTOMRIGHT",mog.tooltip,"BOTTOMRIGHT",-5,5);
|
||||
mog.tooltip.model:SetScript("OnShow",function(self)
|
||||
--[[
|
||||
if mog.db.profile.tooltipCustomModel then
|
||||
self:SetCustomRace(mog.db.profile.tooltipRace, mog.db.profile.tooltipGender);
|
||||
-- hack for hidden helm and cloak showing on models
|
||||
local showingHelm, showingCloak = ShowingHelm(), ShowingCloak();
|
||||
local helm, cloak = GetInventoryItemID("player", INVSLOT_HEAD), GetInventoryItemID("player", INVSLOT_BACK);
|
||||
if not showingHelm and helm then
|
||||
self:TryOn(helm);
|
||||
self:UndressSlot(INVSLOT_HEAD);
|
||||
end
|
||||
if not showingCloak and cloak then
|
||||
self:TryOn(cloak);
|
||||
self:UndressSlot(INVSLOT_BACK);
|
||||
end
|
||||
self:RefreshCamera();
|
||||
else
|
||||
self:Dress();
|
||||
end
|
||||
--]]
|
||||
self:Dress();
|
||||
if not mog.db.profile.tooltipDress then
|
||||
self:Undress();
|
||||
end
|
||||
end);
|
||||
|
||||
|
||||
function mog.tooltip.ShowItem(self)
|
||||
local _,itemLink = self:GetItem();
|
||||
if not itemLink then
|
||||
return;
|
||||
end
|
||||
local itemID = tonumber(itemLink:match("item:(%d+)"));
|
||||
|
||||
local db = mog.db.profile
|
||||
local tooltip = mog.tooltip
|
||||
if db.tooltip and (not tooltip.mod[db.tooltipMod] or tooltip.mod[db.tooltipMod]()) then
|
||||
if not self[mog] then
|
||||
if tooltip.item ~= itemLink then
|
||||
tooltip.item = itemLink;
|
||||
local token = mog.tokens[itemID];
|
||||
if token then
|
||||
for item, classBit in pairs(token) do
|
||||
if bit.band(class, classBit) > 0 then
|
||||
itemLink = item;
|
||||
break;
|
||||
end
|
||||
end
|
||||
end
|
||||
local slot = select(9,GetItemInfo(itemLink));
|
||||
if (not db.tooltipMog ) and tooltip.slots[slot] and IsDressableItem(itemLink) then
|
||||
tooltip.model:SetFacing(tooltip.slots[slot]-(db.tooltipRotate and 0.5 or 0));
|
||||
tooltip:Show();
|
||||
tooltip.owner = self;
|
||||
--if mog.global.tooltipAnchor then
|
||||
tooltip.repos:Show();
|
||||
--else
|
||||
-- tooltip:ClearAllPoints();
|
||||
-- tooltip:SetPoint("BOTTOMRIGHT","UIParent","BOTTOMRIGHT",-CONTAINER_OFFSET_X - 13,CONTAINER_OFFSET_Y);
|
||||
--end
|
||||
tooltip.model:TryOn(itemLink);
|
||||
else
|
||||
tooltip:Hide();
|
||||
end
|
||||
end
|
||||
else
|
||||
-- tooltip:Hide();
|
||||
end
|
||||
end
|
||||
|
||||
-- add wishlist info about this item
|
||||
if not self[mog] and mog.wishlist:IsItemInWishlist(itemID) then
|
||||
self:AddLine(" ");
|
||||
self:AddLine(L["This item is on your wishlist."], 1, 1, 0);
|
||||
self:AddTexture("Interface\\TargetingFrame\\UI-RaidTargetingIcon_1");
|
||||
end
|
||||
end
|
||||
|
||||
function mog.tooltip.HideItem(self)
|
||||
mog.tooltip.check:Show();
|
||||
end
|
||||
--//
|
||||
|
||||
|
||||
--// GameTooltip
|
||||
mog.tooltip.check = CreateFrame("Frame");
|
||||
mog.tooltip.check:Hide();
|
||||
mog.tooltip.check:SetScript("OnUpdate",function(self)
|
||||
if (mog.tooltip.owner and not (mog.tooltip.owner:IsShown() and mog.tooltip.owner:GetItem())) or not mog.tooltip.owner then
|
||||
mog.tooltip:Hide();
|
||||
mog.tooltip.item = nil;
|
||||
end
|
||||
self:Hide();
|
||||
end);
|
||||
|
||||
mog.tooltip.repos = CreateFrame("Frame");
|
||||
mog.tooltip.repos:Hide();
|
||||
mog.tooltip.repos:SetScript("OnUpdate",function(self)
|
||||
local x,y = mog.tooltip.owner:GetCenter();
|
||||
if x and y then
|
||||
mog.tooltip:ClearAllPoints();
|
||||
local mogpoint,ownerpoint;
|
||||
if y/GetScreenHeight() > 0.5 then
|
||||
mogpoint = "TOP";
|
||||
ownerpoint = "BOTTOM";
|
||||
else
|
||||
mogpoint = "BOTTOM";
|
||||
ownerpoint = "TOP";
|
||||
end
|
||||
if x/GetScreenWidth() > 0.5 then
|
||||
mogpoint = mogpoint.."LEFT";
|
||||
ownerpoint = ownerpoint.."LEFT";
|
||||
else
|
||||
mogpoint = mogpoint.."RIGHT";
|
||||
ownerpoint = ownerpoint.."RIGHT";
|
||||
end
|
||||
mog.tooltip:SetPoint(mogpoint,mog.tooltip.owner,ownerpoint);
|
||||
self:Hide();
|
||||
end
|
||||
end);
|
||||
|
||||
GameTooltip:HookScript("OnTooltipSetItem",mog.tooltip.ShowItem);
|
||||
GameTooltip:HookScript("OnHide",mog.tooltip.HideItem);
|
||||
--//
|
||||
|
||||
|
||||
--// Auto-Rotate
|
||||
mog.tooltip.rotate = CreateFrame("Frame",nil,mog.tooltip);
|
||||
mog.tooltip.rotate:Hide();
|
||||
mog.tooltip.rotate:SetScript("OnUpdate",function(self,elapsed)
|
||||
mog.tooltip.model:SetFacing(mog.tooltip.model:GetFacing() + elapsed);
|
||||
end);
|
||||
--//
|
||||
|
||||
|
||||
--// Tables
|
||||
mog.tooltip.slots = {
|
||||
INVTYPE_HEAD = 0,
|
||||
INVTYPE_SHOULDER = 0,
|
||||
INVTYPE_CLOAK = 3.4,
|
||||
INVTYPE_CHEST = 0,
|
||||
INVTYPE_ROBE = 0,
|
||||
INVTYPE_WRIST = 0,
|
||||
INVTYPE_2HWEAPON = 1.6,
|
||||
INVTYPE_WEAPON = 1.6,
|
||||
INVTYPE_WEAPONMAINHAND = 1.6,
|
||||
INVTYPE_WEAPONOFFHAND = -0.7,
|
||||
INVTYPE_SHIELD = -0.7,
|
||||
INVTYPE_HOLDABLE = -0.7,
|
||||
INVTYPE_RANGED = 1.6,
|
||||
INVTYPE_RANGEDRIGHT = 1.6,
|
||||
INVTYPE_THROWN = 1.6,
|
||||
INVTYPE_HAND = 0,
|
||||
INVTYPE_WAIST = 0,
|
||||
INVTYPE_LEGS = 0,
|
||||
INVTYPE_FEET = 0,
|
||||
};
|
||||
|
||||
mog.tooltip.mod = {
|
||||
Shift = IsShiftKeyDown,
|
||||
Ctrl = IsControlKeyDown,
|
||||
Alt = IsAltKeyDown,
|
||||
};
|
||||
--//
|
||||
161
MogIt/Core/URL.lua
Normal file
@@ -0,0 +1,161 @@
|
||||
local MogIt,mog = ...;
|
||||
local L = mog.L;
|
||||
|
||||
mog.url = {};
|
||||
|
||||
function mog:AddURL(name,tbl)
|
||||
mog.url[name] = tbl;
|
||||
end
|
||||
|
||||
function mog:ShowURL(id,sub,url,force)
|
||||
if not id then return end;
|
||||
url = url or mog.db.profile.url;
|
||||
sub = sub or "item";
|
||||
if not (force or (mog.url[url] and mog.url[url][sub])) then
|
||||
url = "Wowhead";
|
||||
end
|
||||
if mog.url[url] and mog.url[url][sub] then
|
||||
local text;
|
||||
if type(mog.url[url][sub]) == "function" then
|
||||
text = mog.url[url][sub](id);
|
||||
else
|
||||
text = mog.url[url][sub]:format(id);
|
||||
end
|
||||
if text then
|
||||
StaticPopup_Show("MOGIT_URL",mog.url[url].fav and "\124T"..mog.url[url].fav..":18:18\124t " or "",url,text);
|
||||
return true;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
StaticPopupDialogs["MOGIT_URL"] = {
|
||||
preferredIndex = 3,
|
||||
text = "%s%s "..L["URL"],
|
||||
button1 = CLOSE,
|
||||
hasEditBox = 1,
|
||||
maxLetters = 512,
|
||||
hasWideEditBox = 1,
|
||||
|
||||
OnShow = function(self,url)
|
||||
self.wideEditBox:SetText(url);
|
||||
self.wideEditBox:SetFocus();
|
||||
self.wideEditBox:HighlightText();
|
||||
end,
|
||||
EditBoxOnEnterPressed = function(self)
|
||||
self:GetParent():Hide();
|
||||
end,
|
||||
EditBoxOnEscapePressed = function(self)
|
||||
self:GetParent():Hide();
|
||||
end,
|
||||
timeout = 0,
|
||||
exclusive = 1,
|
||||
whileDead = 1,
|
||||
hideOnEscape = 1
|
||||
};
|
||||
|
||||
mog:AddURL("Wowhead",{
|
||||
fav = "Interface\\AddOns\\MogIt\\Images\\fav_wh",
|
||||
item = L["http://www.wowhead.com/"].."item=%d",
|
||||
set = L["http://www.wowhead.com/"].."itemset=%d",
|
||||
npc = L["http://www.wowhead.com/"].."npc=%d",
|
||||
spell = L["http://www.wowhead.com/"].."spell=%d",
|
||||
compare = function(tbl)
|
||||
local str;
|
||||
for k,v in pairs(tbl) do
|
||||
if str then
|
||||
str = str..":"..v;
|
||||
else
|
||||
str = L["http://www.wowhead.com/"].."compare?items="..v;
|
||||
end
|
||||
end
|
||||
return str;
|
||||
end,
|
||||
});
|
||||
|
||||
mog:AddURL("WOWDB",{
|
||||
fav = "Interface\\AddOns\\MogIt\\Images\\fav_mmo",
|
||||
item = "http://www.wowdb.com/items/%d",
|
||||
set = "http://www.wowdb.com/item-sets/%d",
|
||||
npc = "http://www.wowdb.com/npcs/%d",
|
||||
spell = "http://www.wowdb.com/spells/%d",
|
||||
});
|
||||
|
||||
mog:AddURL("EVOWoW",{
|
||||
fav = "Interface\\AddOns\\MogIt\\Images\\fav_wow",
|
||||
item = "https://wotlk.evowow.com/?item=%d",
|
||||
set = "https://wotlk.evowow.com/?itemset=%d",
|
||||
npc = "http://www.wowdb.com/?npcs/%d",
|
||||
spell = "http://www.wowdb.com/?spells/%d",
|
||||
compare = function(tbl)
|
||||
local str;
|
||||
for k,v in pairs(tbl) do
|
||||
if str then
|
||||
str = str..v..";";
|
||||
else
|
||||
str = "https://wotlk.evowow.com/?compare="..v..";";
|
||||
end
|
||||
end
|
||||
return str;
|
||||
end,
|
||||
});
|
||||
|
||||
mog:AddURL("Rising-Gods",{
|
||||
fav = "Interface\\AddOns\\MogIt\\Images\\fav_wow",
|
||||
item = "https://db.rising-gods.de/?item=%d",
|
||||
set = "https://db.rising-gods.de/?item-sets/%d",
|
||||
npc = "https://db.rising-gods.de/?npcs/%d",
|
||||
spell = "https://db.rising-gods.de/?spells/%d",
|
||||
compare = function(tbl)
|
||||
local str;
|
||||
for k,v in pairs(tbl) do
|
||||
if str then
|
||||
str = str..v..";";
|
||||
else
|
||||
str = "https://db.rising-gods.de/?compare="..v..";";
|
||||
end
|
||||
end
|
||||
return str;
|
||||
end,
|
||||
});
|
||||
|
||||
mog:AddURL("WOWDB",{
|
||||
fav = "Interface\\AddOns\\MogIt\\Images\\fav_mmo",
|
||||
item = "http://www.wowdb.com/items/%d",
|
||||
set = "http://www.wowdb.com/item-sets/%d",
|
||||
npc = "http://www.wowdb.com/npcs/%d",
|
||||
spell = "http://www.wowdb.com/spells/%d",
|
||||
});
|
||||
|
||||
mog:AddURL("Wowpedia",{
|
||||
fav = "Interface\\AddOns\\MogIt\\Images\\fav_wp",
|
||||
item = "http://www.wowpedia.org/index.php?search=\"{{elinks-item|%d}}\"",
|
||||
set = "http://www.wowpedia.org/index.php?search=\"{{elinks-set|%d}}\"",
|
||||
npc = "http://www.wowpedia.org/index.php?search=\"{{elinks-NPC|%d}}\"",
|
||||
spell = "http://www.wowpedia.org/index.php?search=\"{{elinks-spell|%d}}\"",
|
||||
});
|
||||
|
||||
mog:AddURL("Buffed.de",{
|
||||
fav = "Interface\\AddOns\\MogIt\\Images\\fav_buff",
|
||||
item = "http://wowdata.buffed.de/?i=%d",
|
||||
set = "http://wowdata.buffed.de/?set=%d",
|
||||
npc = "http://wowdata.buffed.de/?n=%d",
|
||||
spell = "http://wowdata.buffed.de/?s=%d",
|
||||
compare = function(tbl)
|
||||
local str;
|
||||
for k,v in pairs(tbl) do
|
||||
if str then
|
||||
str = str..v..";";
|
||||
else
|
||||
str = "http://wowdata.buffed.de/itemcompare#"..v..";";
|
||||
end
|
||||
end
|
||||
return str;
|
||||
end,
|
||||
});
|
||||
|
||||
mog:AddURL("JudgeHype",{
|
||||
fav = "Interface\\AddOns\\MogIt\\Images\\fav_jh",
|
||||
item = "http://worldofwarcraft.judgehype.com/?page=objet&w=%d",
|
||||
npc = "http://worldofwarcraft.judgehype.com/index.php?page=pnj&w=%d",
|
||||
spell = "http://worldofwarcraft.judgehype.com/index.php?page=spell&w=%d",
|
||||
});
|
||||
BIN
MogIt/FrameGeneral/!UI-Frame.blp
Normal file
BIN
MogIt/FrameGeneral/UI-Background-Marble.blp
Normal file
BIN
MogIt/FrameGeneral/UI-Background-Rock.blp
Normal file
BIN
MogIt/FrameGeneral/UI-Frame.blp
Normal file
BIN
MogIt/FrameGeneral/_UI-Frame.blp
Normal file
BIN
MogIt/Images/MogIt.tga
Normal file
BIN
MogIt/Images/dede.tga
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
MogIt/Images/enus.tga
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
MogIt/Images/eses.tga
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
MogIt/Images/esmx.tga
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
MogIt/Images/fav_buff.tga
Normal file
BIN
MogIt/Images/fav_jh.tga
Normal file
BIN
MogIt/Images/fav_mmo.tga
Normal file
BIN
MogIt/Images/fav_tb.tga
Normal file
BIN
MogIt/Images/fav_wh.tga
Normal file
BIN
MogIt/Images/fav_wow.tga
Normal file
BIN
MogIt/Images/fav_wp.tga
Normal file
BIN
MogIt/Images/frfr.tga
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
MogIt/Images/itit.tga
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
MogIt/Images/kokr.tga
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
MogIt/Images/ptbr.tga
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
MogIt/Images/ruru.tga
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
MogIt/Images/zhcn.tga
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
MogIt/Images/zhtw.tga
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
57
MogIt/Libs/AceConfig-3.0/AceConfig-3.0.lua
Normal file
@@ -0,0 +1,57 @@
|
||||
--- AceConfig-3.0 wrapper library.
|
||||
-- Provides an API to register an options table with the config registry,
|
||||
-- as well as associate it with a slash command.
|
||||
-- @class file
|
||||
-- @name AceConfig-3.0
|
||||
-- @release $Id: AceConfig-3.0.lua 969 2010-10-07 02:11:48Z shefki $
|
||||
|
||||
--[[
|
||||
AceConfig-3.0
|
||||
|
||||
Very light wrapper library that combines all the AceConfig subcomponents into one more easily used whole.
|
||||
|
||||
]]
|
||||
|
||||
local MAJOR, MINOR = "AceConfig-3.0", 2
|
||||
local AceConfig = LibStub:NewLibrary(MAJOR, MINOR)
|
||||
|
||||
if not AceConfig then return end
|
||||
|
||||
local cfgreg = LibStub("AceConfigRegistry-3.0")
|
||||
local cfgcmd = LibStub("AceConfigCmd-3.0")
|
||||
--TODO: local cfgdlg = LibStub("AceConfigDialog-3.0", true)
|
||||
--TODO: local cfgdrp = LibStub("AceConfigDropdown-3.0", true)
|
||||
|
||||
-- Lua APIs
|
||||
local pcall, error, type, pairs = pcall, error, type, pairs
|
||||
|
||||
-- -------------------------------------------------------------------
|
||||
-- :RegisterOptionsTable(appName, options, slashcmd, persist)
|
||||
--
|
||||
-- - appName - (string) application name
|
||||
-- - options - table or function ref, see AceConfigRegistry
|
||||
-- - slashcmd - slash command (string) or table with commands, or nil to NOT create a slash command
|
||||
|
||||
--- Register a option table with the AceConfig registry.
|
||||
-- You can supply a slash command (or a table of slash commands) to register with AceConfigCmd directly.
|
||||
-- @paramsig appName, options [, slashcmd]
|
||||
-- @param appName The application name for the config table.
|
||||
-- @param options The option table (or a function to generate one on demand). http://www.wowace.com/addons/ace3/pages/ace-config-3-0-options-tables/
|
||||
-- @param slashcmd A slash command to register for the option table, or a table of slash commands.
|
||||
-- @usage
|
||||
-- local AceConfig = LibStub("AceConfig-3.0")
|
||||
-- AceConfig:RegisterOptionsTable("MyAddon", myOptions, {"/myslash", "/my"})
|
||||
function AceConfig:RegisterOptionsTable(appName, options, slashcmd)
|
||||
local ok,msg = pcall(cfgreg.RegisterOptionsTable, self, appName, options)
|
||||
if not ok then error(msg, 2) end
|
||||
|
||||
if slashcmd then
|
||||
if type(slashcmd) == "table" then
|
||||
for _,cmd in pairs(slashcmd) do
|
||||
cfgcmd:CreateChatCommand(cmd, appName)
|
||||
end
|
||||
else
|
||||
cfgcmd:CreateChatCommand(slashcmd, appName)
|
||||
end
|
||||
end
|
||||
end
|
||||
8
MogIt/Libs/AceConfig-3.0/AceConfig-3.0.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
..\FrameXML\UI.xsd">
|
||||
<Include file="AceConfigRegistry-3.0\AceConfigRegistry-3.0.xml"/>
|
||||
<Include file="AceConfigCmd-3.0\AceConfigCmd-3.0.xml"/>
|
||||
<Include file="AceConfigDialog-3.0\AceConfigDialog-3.0.xml"/>
|
||||
<!--<Include file="AceConfigDropdown-3.0\AceConfigDropdown-3.0.xml"/>-->
|
||||
<Script file="AceConfig-3.0.lua"/>
|
||||
</Ui>
|
||||
787
MogIt/Libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.lua
Normal file
@@ -0,0 +1,787 @@
|
||||
--- AceConfigCmd-3.0 handles access to an options table through the "command line" interface via the ChatFrames.
|
||||
-- @class file
|
||||
-- @name AceConfigCmd-3.0
|
||||
-- @release $Id: AceConfigCmd-3.0.lua 904 2009-12-13 11:56:37Z nevcairiel $
|
||||
|
||||
--[[
|
||||
AceConfigCmd-3.0
|
||||
|
||||
Handles commandline optionstable access
|
||||
|
||||
REQUIRES: AceConsole-3.0 for command registration (loaded on demand)
|
||||
|
||||
]]
|
||||
|
||||
-- TODO: plugin args
|
||||
|
||||
|
||||
local MAJOR, MINOR = "AceConfigCmd-3.0", 12
|
||||
local AceConfigCmd = LibStub:NewLibrary(MAJOR, MINOR)
|
||||
|
||||
if not AceConfigCmd then return end
|
||||
|
||||
AceConfigCmd.commands = AceConfigCmd.commands or {}
|
||||
local commands = AceConfigCmd.commands
|
||||
|
||||
local cfgreg = LibStub("AceConfigRegistry-3.0")
|
||||
local AceConsole -- LoD
|
||||
local AceConsoleName = "AceConsole-3.0"
|
||||
|
||||
-- Lua APIs
|
||||
local strsub, strsplit, strlower, strmatch, strtrim = string.sub, string.split, string.lower, string.match, string.trim
|
||||
local format, tonumber, tostring = string.format, tonumber, tostring
|
||||
local tsort, tinsert = table.sort, table.insert
|
||||
local select, pairs, next, type = select, pairs, next, type
|
||||
local error, assert = error, assert
|
||||
|
||||
-- WoW APIs
|
||||
local _G = _G
|
||||
|
||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||
-- List them here for Mikk's FindGlobals script
|
||||
-- GLOBALS: LibStub, SELECTED_CHAT_FRAME, DEFAULT_CHAT_FRAME
|
||||
|
||||
|
||||
local L = setmetatable({}, { -- TODO: replace with proper locale
|
||||
__index = function(self,k) return k end
|
||||
})
|
||||
|
||||
|
||||
|
||||
local function print(msg)
|
||||
(SELECTED_CHAT_FRAME or DEFAULT_CHAT_FRAME):AddMessage(msg)
|
||||
end
|
||||
|
||||
-- constants used by getparam() calls below
|
||||
|
||||
local handlertypes = {["table"]=true}
|
||||
local handlermsg = "expected a table"
|
||||
|
||||
local functypes = {["function"]=true, ["string"]=true}
|
||||
local funcmsg = "expected function or member name"
|
||||
|
||||
|
||||
-- pickfirstset() - picks the first non-nil value and returns it
|
||||
|
||||
local function pickfirstset(...)
|
||||
for i=1,select("#",...) do
|
||||
if select(i,...)~=nil then
|
||||
return select(i,...)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- err() - produce real error() regarding malformed options tables etc
|
||||
|
||||
local function err(info,inputpos,msg )
|
||||
local cmdstr=" "..strsub(info.input, 1, inputpos-1)
|
||||
error(MAJOR..": /" ..info[0] ..cmdstr ..": "..(msg or "malformed options table"), 2)
|
||||
end
|
||||
|
||||
|
||||
-- usererr() - produce chatframe message regarding bad slash syntax etc
|
||||
|
||||
local function usererr(info,inputpos,msg )
|
||||
local cmdstr=strsub(info.input, 1, inputpos-1);
|
||||
print("/" ..info[0] .. " "..cmdstr ..": "..(msg or "malformed options table"))
|
||||
end
|
||||
|
||||
|
||||
-- callmethod() - call a given named method (e.g. "get", "set") with given arguments
|
||||
|
||||
local function callmethod(info, inputpos, tab, methodtype, ...)
|
||||
local method = info[methodtype]
|
||||
if not method then
|
||||
err(info, inputpos, "'"..methodtype.."': not set")
|
||||
end
|
||||
|
||||
info.arg = tab.arg
|
||||
info.option = tab
|
||||
info.type = tab.type
|
||||
|
||||
if type(method)=="function" then
|
||||
return method(info, ...)
|
||||
elseif type(method)=="string" then
|
||||
if type(info.handler[method])~="function" then
|
||||
err(info, inputpos, "'"..methodtype.."': '"..method.."' is not a member function of "..tostring(info.handler))
|
||||
end
|
||||
return info.handler[method](info.handler, info, ...)
|
||||
else
|
||||
assert(false) -- type should have already been checked on read
|
||||
end
|
||||
end
|
||||
|
||||
-- callfunction() - call a given named function (e.g. "name", "desc") with given arguments
|
||||
|
||||
local function callfunction(info, tab, methodtype, ...)
|
||||
local method = tab[methodtype]
|
||||
|
||||
info.arg = tab.arg
|
||||
info.option = tab
|
||||
info.type = tab.type
|
||||
|
||||
if type(method)=="function" then
|
||||
return method(info, ...)
|
||||
else
|
||||
assert(false) -- type should have already been checked on read
|
||||
end
|
||||
end
|
||||
|
||||
-- do_final() - do the final step (set/execute) along with validation and confirmation
|
||||
|
||||
local function do_final(info, inputpos, tab, methodtype, ...)
|
||||
if info.validate then
|
||||
local res = callmethod(info,inputpos,tab,"validate",...)
|
||||
if type(res)=="string" then
|
||||
usererr(info, inputpos, "'"..strsub(info.input, inputpos).."' - "..res)
|
||||
return
|
||||
end
|
||||
end
|
||||
-- console ignores .confirm
|
||||
|
||||
callmethod(info,inputpos,tab,methodtype, ...)
|
||||
end
|
||||
|
||||
|
||||
-- getparam() - used by handle() to retreive and store "handler", "get", "set", etc
|
||||
|
||||
local function getparam(info, inputpos, tab, depth, paramname, types, errormsg)
|
||||
local old,oldat = info[paramname], info[paramname.."_at"]
|
||||
local val=tab[paramname]
|
||||
if val~=nil then
|
||||
if val==false then
|
||||
val=nil
|
||||
elseif not types[type(val)] then
|
||||
err(info, inputpos, "'" .. paramname.. "' - "..errormsg)
|
||||
end
|
||||
info[paramname] = val
|
||||
info[paramname.."_at"] = depth
|
||||
end
|
||||
return old,oldat
|
||||
end
|
||||
|
||||
|
||||
-- iterateargs(tab) - custom iterator that iterates both t.args and t.plugins.*
|
||||
local dummytable={}
|
||||
|
||||
local function iterateargs(tab)
|
||||
if not tab.plugins then
|
||||
return pairs(tab.args)
|
||||
end
|
||||
|
||||
local argtabkey,argtab=next(tab.plugins)
|
||||
local v
|
||||
|
||||
return function(_, k)
|
||||
while argtab do
|
||||
k,v = next(argtab, k)
|
||||
if k then return k,v end
|
||||
if argtab==tab.args then
|
||||
argtab=nil
|
||||
else
|
||||
argtabkey,argtab = next(tab.plugins, argtabkey)
|
||||
if not argtabkey then
|
||||
argtab=tab.args
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function checkhidden(info, inputpos, tab)
|
||||
if tab.cmdHidden~=nil then
|
||||
return tab.cmdHidden
|
||||
end
|
||||
local hidden = tab.hidden
|
||||
if type(hidden) == "function" or type(hidden) == "string" then
|
||||
info.hidden = hidden
|
||||
hidden = callmethod(info, inputpos, tab, 'hidden')
|
||||
info.hidden = nil
|
||||
end
|
||||
return hidden
|
||||
end
|
||||
|
||||
local function showhelp(info, inputpos, tab, depth, noHead)
|
||||
if not noHead then
|
||||
print("|cff33ff99"..info.appName.."|r: Arguments to |cffffff78/"..info[0].."|r "..strsub(info.input,1,inputpos-1)..":")
|
||||
end
|
||||
|
||||
local sortTbl = {} -- [1..n]=name
|
||||
local refTbl = {} -- [name]=tableref
|
||||
|
||||
for k,v in iterateargs(tab) do
|
||||
if not refTbl[k] then -- a plugin overriding something in .args
|
||||
tinsert(sortTbl, k)
|
||||
refTbl[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
tsort(sortTbl, function(one, two)
|
||||
local o1 = refTbl[one].order or 100
|
||||
local o2 = refTbl[two].order or 100
|
||||
if type(o1) == "function" or type(o1) == "string" then
|
||||
info.order = o1
|
||||
info[#info+1] = one
|
||||
o1 = callmethod(info, inputpos, refTbl[one], "order")
|
||||
info[#info] = nil
|
||||
info.order = nil
|
||||
end
|
||||
if type(o2) == "function" or type(o1) == "string" then
|
||||
info.order = o2
|
||||
info[#info+1] = two
|
||||
o2 = callmethod(info, inputpos, refTbl[two], "order")
|
||||
info[#info] = nil
|
||||
info.order = nil
|
||||
end
|
||||
if o1<0 and o2<0 then return o1<o2 end
|
||||
if o2<0 then return true end
|
||||
if o1<0 then return false end
|
||||
if o1==o2 then return tostring(one)<tostring(two) end -- compare names
|
||||
return o1<o2
|
||||
end)
|
||||
|
||||
for i = 1, #sortTbl do
|
||||
local k = sortTbl[i]
|
||||
local v = refTbl[k]
|
||||
if not checkhidden(info, inputpos, v) then
|
||||
if v.type ~= "description" and v.type ~= "header" then
|
||||
-- recursively show all inline groups
|
||||
local name, desc = v.name, v.desc
|
||||
if type(name) == "function" then
|
||||
name = callfunction(info, v, 'name')
|
||||
end
|
||||
if type(desc) == "function" then
|
||||
desc = callfunction(info, v, 'desc')
|
||||
end
|
||||
if v.type == "group" and pickfirstset(v.cmdInline, v.inline, false) then
|
||||
print(" "..(desc or name)..":")
|
||||
local oldhandler,oldhandler_at = getparam(info, inputpos, v, depth, "handler", handlertypes, handlermsg)
|
||||
showhelp(info, inputpos, v, depth, true)
|
||||
info.handler,info.handler_at = oldhandler,oldhandler_at
|
||||
else
|
||||
local key = k:gsub(" ", "_")
|
||||
print(" |cffffff78"..key.."|r - "..(desc or name or ""))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function keybindingValidateFunc(text)
|
||||
if text == nil or text == "NONE" then
|
||||
return nil
|
||||
end
|
||||
text = text:upper()
|
||||
local shift, ctrl, alt
|
||||
local modifier
|
||||
while true do
|
||||
if text == "-" then
|
||||
break
|
||||
end
|
||||
modifier, text = strsplit('-', text, 2)
|
||||
if text then
|
||||
if modifier ~= "SHIFT" and modifier ~= "CTRL" and modifier ~= "ALT" then
|
||||
return false
|
||||
end
|
||||
if modifier == "SHIFT" then
|
||||
if shift then
|
||||
return false
|
||||
end
|
||||
shift = true
|
||||
end
|
||||
if modifier == "CTRL" then
|
||||
if ctrl then
|
||||
return false
|
||||
end
|
||||
ctrl = true
|
||||
end
|
||||
if modifier == "ALT" then
|
||||
if alt then
|
||||
return false
|
||||
end
|
||||
alt = true
|
||||
end
|
||||
else
|
||||
text = modifier
|
||||
break
|
||||
end
|
||||
end
|
||||
if text == "" then
|
||||
return false
|
||||
end
|
||||
if not text:find("^F%d+$") and text ~= "CAPSLOCK" and text:len() ~= 1 and (text:byte() < 128 or text:len() > 4) and not _G["KEY_" .. text] then
|
||||
return false
|
||||
end
|
||||
local s = text
|
||||
if shift then
|
||||
s = "SHIFT-" .. s
|
||||
end
|
||||
if ctrl then
|
||||
s = "CTRL-" .. s
|
||||
end
|
||||
if alt then
|
||||
s = "ALT-" .. s
|
||||
end
|
||||
return s
|
||||
end
|
||||
|
||||
-- handle() - selfrecursing function that processes input->optiontable
|
||||
-- - depth - starts at 0
|
||||
-- - retfalse - return false rather than produce error if a match is not found (used by inlined groups)
|
||||
|
||||
local function handle(info, inputpos, tab, depth, retfalse)
|
||||
|
||||
if not(type(tab)=="table" and type(tab.type)=="string") then err(info,inputpos) end
|
||||
|
||||
-------------------------------------------------------------------
|
||||
-- Grab hold of handler,set,get,func,etc if set (and remember old ones)
|
||||
-- Note that we do NOT validate if method names are correct at this stage,
|
||||
-- the handler may change before they're actually used!
|
||||
|
||||
local oldhandler,oldhandler_at = getparam(info,inputpos,tab,depth,"handler",handlertypes,handlermsg)
|
||||
local oldset,oldset_at = getparam(info,inputpos,tab,depth,"set",functypes,funcmsg)
|
||||
local oldget,oldget_at = getparam(info,inputpos,tab,depth,"get",functypes,funcmsg)
|
||||
local oldfunc,oldfunc_at = getparam(info,inputpos,tab,depth,"func",functypes,funcmsg)
|
||||
local oldvalidate,oldvalidate_at = getparam(info,inputpos,tab,depth,"validate",functypes,funcmsg)
|
||||
--local oldconfirm,oldconfirm_at = getparam(info,inputpos,tab,depth,"confirm",functypes,funcmsg)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
-- Act according to .type of this table
|
||||
|
||||
if tab.type=="group" then
|
||||
------------ group --------------------------------------------
|
||||
|
||||
if type(tab.args)~="table" then err(info, inputpos) end
|
||||
if tab.plugins and type(tab.plugins)~="table" then err(info,inputpos) end
|
||||
|
||||
-- grab next arg from input
|
||||
local _,nextpos,arg = (info.input):find(" *([^ ]+) *", inputpos)
|
||||
if not arg then
|
||||
showhelp(info, inputpos, tab, depth)
|
||||
return
|
||||
end
|
||||
nextpos=nextpos+1
|
||||
|
||||
-- loop .args and try to find a key with a matching name
|
||||
for k,v in iterateargs(tab) do
|
||||
if not(type(k)=="string" and type(v)=="table" and type(v.type)=="string") then err(info,inputpos, "options table child '"..tostring(k).."' is malformed") end
|
||||
|
||||
-- is this child an inline group? if so, traverse into it
|
||||
if v.type=="group" and pickfirstset(v.cmdInline, v.inline, false) then
|
||||
info[depth+1] = k
|
||||
if handle(info, inputpos, v, depth+1, true)==false then
|
||||
info[depth+1] = nil
|
||||
-- wasn't found in there, but that's ok, we just keep looking down here
|
||||
else
|
||||
return -- done, name was found in inline group
|
||||
end
|
||||
-- matching name and not a inline group
|
||||
elseif strlower(arg)==strlower(k:gsub(" ", "_")) then
|
||||
info[depth+1] = k
|
||||
return handle(info,nextpos,v,depth+1)
|
||||
end
|
||||
end
|
||||
|
||||
-- no match
|
||||
if retfalse then
|
||||
-- restore old infotable members and return false to indicate failure
|
||||
info.handler,info.handler_at = oldhandler,oldhandler_at
|
||||
info.set,info.set_at = oldset,oldset_at
|
||||
info.get,info.get_at = oldget,oldget_at
|
||||
info.func,info.func_at = oldfunc,oldfunc_at
|
||||
info.validate,info.validate_at = oldvalidate,oldvalidate_at
|
||||
--info.confirm,info.confirm_at = oldconfirm,oldconfirm_at
|
||||
return false
|
||||
end
|
||||
|
||||
-- couldn't find the command, display error
|
||||
usererr(info, inputpos, "'"..arg.."' - " .. L["unknown argument"])
|
||||
return
|
||||
end
|
||||
|
||||
local str = strsub(info.input,inputpos);
|
||||
|
||||
if tab.type=="execute" then
|
||||
------------ execute --------------------------------------------
|
||||
do_final(info, inputpos, tab, "func")
|
||||
|
||||
|
||||
|
||||
elseif tab.type=="input" then
|
||||
------------ input --------------------------------------------
|
||||
|
||||
local res = true
|
||||
if tab.pattern then
|
||||
if not(type(tab.pattern)=="string") then err(info, inputpos, "'pattern' - expected a string") end
|
||||
if not strmatch(str, tab.pattern) then
|
||||
usererr(info, inputpos, "'"..str.."' - " .. L["invalid input"])
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
do_final(info, inputpos, tab, "set", str)
|
||||
|
||||
|
||||
|
||||
elseif tab.type=="toggle" then
|
||||
------------ toggle --------------------------------------------
|
||||
local b
|
||||
local str = strtrim(strlower(str))
|
||||
if str=="" then
|
||||
b = callmethod(info, inputpos, tab, "get")
|
||||
|
||||
if tab.tristate then
|
||||
--cycle in true, nil, false order
|
||||
if b then
|
||||
b = nil
|
||||
elseif b == nil then
|
||||
b = false
|
||||
else
|
||||
b = true
|
||||
end
|
||||
else
|
||||
b = not b
|
||||
end
|
||||
|
||||
elseif str==L["on"] then
|
||||
b = true
|
||||
elseif str==L["off"] then
|
||||
b = false
|
||||
elseif tab.tristate and str==L["default"] then
|
||||
b = nil
|
||||
else
|
||||
if tab.tristate then
|
||||
usererr(info, inputpos, format(L["'%s' - expected 'on', 'off' or 'default', or no argument to toggle."], str))
|
||||
else
|
||||
usererr(info, inputpos, format(L["'%s' - expected 'on' or 'off', or no argument to toggle."], str))
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
do_final(info, inputpos, tab, "set", b)
|
||||
|
||||
|
||||
elseif tab.type=="range" then
|
||||
------------ range --------------------------------------------
|
||||
local val = tonumber(str)
|
||||
if not val then
|
||||
usererr(info, inputpos, "'"..str.."' - "..L["expected number"])
|
||||
return
|
||||
end
|
||||
if type(info.step)=="number" then
|
||||
val = val- (val % info.step)
|
||||
end
|
||||
if type(info.min)=="number" and val<info.min then
|
||||
usererr(info, inputpos, val.." - "..format(L["must be equal to or higher than %s"], tostring(info.min)) )
|
||||
return
|
||||
end
|
||||
if type(info.max)=="number" and val>info.max then
|
||||
usererr(info, inputpos, val.." - "..format(L["must be equal to or lower than %s"], tostring(info.max)) )
|
||||
return
|
||||
end
|
||||
|
||||
do_final(info, inputpos, tab, "set", val)
|
||||
|
||||
|
||||
elseif tab.type=="select" then
|
||||
------------ select ------------------------------------
|
||||
local str = strtrim(strlower(str))
|
||||
|
||||
local values = tab.values
|
||||
if type(values) == "function" or type(values) == "string" then
|
||||
info.values = values
|
||||
values = callmethod(info, inputpos, tab, "values")
|
||||
info.values = nil
|
||||
end
|
||||
|
||||
if str == "" then
|
||||
local b = callmethod(info, inputpos, tab, "get")
|
||||
local fmt = "|cffffff78- [%s]|r %s"
|
||||
local fmt_sel = "|cffffff78- [%s]|r %s |cffff0000*|r"
|
||||
print(L["Options for |cffffff78"..info[#info].."|r:"])
|
||||
for k, v in pairs(values) do
|
||||
if b == k then
|
||||
print(fmt_sel:format(k, v))
|
||||
else
|
||||
print(fmt:format(k, v))
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local ok
|
||||
for k,v in pairs(values) do
|
||||
if strlower(k)==str then
|
||||
str = k -- overwrite with key (in case of case mismatches)
|
||||
ok = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not ok then
|
||||
usererr(info, inputpos, "'"..str.."' - "..L["unknown selection"])
|
||||
return
|
||||
end
|
||||
|
||||
do_final(info, inputpos, tab, "set", str)
|
||||
|
||||
elseif tab.type=="multiselect" then
|
||||
------------ multiselect -------------------------------------------
|
||||
local str = strtrim(strlower(str))
|
||||
|
||||
local values = tab.values
|
||||
if type(values) == "function" or type(values) == "string" then
|
||||
info.values = values
|
||||
values = callmethod(info, inputpos, tab, "values")
|
||||
info.values = nil
|
||||
end
|
||||
|
||||
if str == "" then
|
||||
local fmt = "|cffffff78- [%s]|r %s"
|
||||
local fmt_sel = "|cffffff78- [%s]|r %s |cffff0000*|r"
|
||||
print(L["Options for |cffffff78"..info[#info].."|r (multiple possible):"])
|
||||
for k, v in pairs(values) do
|
||||
if callmethod(info, inputpos, tab, "get", k) then
|
||||
print(fmt_sel:format(k, v))
|
||||
else
|
||||
print(fmt:format(k, v))
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
--build a table of the selections, checking that they exist
|
||||
--parse for =on =off =default in the process
|
||||
--table will be key = true for options that should toggle, key = [on|off|default] for options to be set
|
||||
local sels = {}
|
||||
for v in str:gmatch("[^ ]+") do
|
||||
--parse option=on etc
|
||||
local opt, val = v:match('(.+)=(.+)')
|
||||
--get option if toggling
|
||||
if not opt then
|
||||
opt = v
|
||||
end
|
||||
|
||||
--check that the opt is valid
|
||||
local ok
|
||||
for k,v in pairs(values) do
|
||||
if strlower(k)==opt then
|
||||
opt = k -- overwrite with key (in case of case mismatches)
|
||||
ok = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not ok then
|
||||
usererr(info, inputpos, "'"..opt.."' - "..L["unknown selection"])
|
||||
return
|
||||
end
|
||||
|
||||
--check that if val was supplied it is valid
|
||||
if val then
|
||||
if val == L["on"] or val == L["off"] or (tab.tristate and val == L["default"]) then
|
||||
--val is valid insert it
|
||||
sels[opt] = val
|
||||
else
|
||||
if tab.tristate then
|
||||
usererr(info, inputpos, format(L["'%s' '%s' - expected 'on', 'off' or 'default', or no argument to toggle."], v, val))
|
||||
else
|
||||
usererr(info, inputpos, format(L["'%s' '%s' - expected 'on' or 'off', or no argument to toggle."], v, val))
|
||||
end
|
||||
return
|
||||
end
|
||||
else
|
||||
-- no val supplied, toggle
|
||||
sels[opt] = true
|
||||
end
|
||||
end
|
||||
|
||||
for opt, val in pairs(sels) do
|
||||
local newval
|
||||
|
||||
if (val == true) then
|
||||
--toggle the option
|
||||
local b = callmethod(info, inputpos, tab, "get", opt)
|
||||
|
||||
if tab.tristate then
|
||||
--cycle in true, nil, false order
|
||||
if b then
|
||||
b = nil
|
||||
elseif b == nil then
|
||||
b = false
|
||||
else
|
||||
b = true
|
||||
end
|
||||
else
|
||||
b = not b
|
||||
end
|
||||
newval = b
|
||||
else
|
||||
--set the option as specified
|
||||
if val==L["on"] then
|
||||
newval = true
|
||||
elseif val==L["off"] then
|
||||
newval = false
|
||||
elseif val==L["default"] then
|
||||
newval = nil
|
||||
end
|
||||
end
|
||||
|
||||
do_final(info, inputpos, tab, "set", opt, newval)
|
||||
end
|
||||
|
||||
|
||||
elseif tab.type=="color" then
|
||||
------------ color --------------------------------------------
|
||||
local str = strtrim(strlower(str))
|
||||
if str == "" then
|
||||
--TODO: Show current value
|
||||
return
|
||||
end
|
||||
|
||||
local r, g, b, a
|
||||
|
||||
if tab.hasAlpha then
|
||||
if str:len() == 8 and str:find("^%x*$") then
|
||||
--parse a hex string
|
||||
r,g,b,a = tonumber(str:sub(1, 2), 16) / 255, tonumber(str:sub(3, 4), 16) / 255, tonumber(str:sub(5, 6), 16) / 255, tonumber(str:sub(7, 8), 16) / 255
|
||||
else
|
||||
--parse seperate values
|
||||
r,g,b,a = str:match("^([%d%.]+) ([%d%.]+) ([%d%.]+) ([%d%.]+)$")
|
||||
r,g,b,a = tonumber(r), tonumber(g), tonumber(b), tonumber(a)
|
||||
end
|
||||
if not (r and g and b and a) then
|
||||
usererr(info, inputpos, format(L["'%s' - expected 'RRGGBBAA' or 'r g b a'."], str))
|
||||
return
|
||||
end
|
||||
|
||||
if r >= 0.0 and r <= 1.0 and g >= 0.0 and g <= 1.0 and b >= 0.0 and b <= 1.0 and a >= 0.0 and a <= 1.0 then
|
||||
--values are valid
|
||||
elseif r >= 0 and r <= 255 and g >= 0 and g <= 255 and b >= 0 and b <= 255 and a >= 0 and a <= 255 then
|
||||
--values are valid 0..255, convert to 0..1
|
||||
r = r / 255
|
||||
g = g / 255
|
||||
b = b / 255
|
||||
a = a / 255
|
||||
else
|
||||
--values are invalid
|
||||
usererr(info, inputpos, format(L["'%s' - values must all be either in the range 0..1 or 0..255."], str))
|
||||
end
|
||||
else
|
||||
a = 1.0
|
||||
if str:len() == 6 and str:find("^%x*$") then
|
||||
--parse a hex string
|
||||
r,g,b = tonumber(str:sub(1, 2), 16) / 255, tonumber(str:sub(3, 4), 16) / 255, tonumber(str:sub(5, 6), 16) / 255
|
||||
else
|
||||
--parse seperate values
|
||||
r,g,b = str:match("^([%d%.]+) ([%d%.]+) ([%d%.]+)$")
|
||||
r,g,b = tonumber(r), tonumber(g), tonumber(b)
|
||||
end
|
||||
if not (r and g and b) then
|
||||
usererr(info, inputpos, format(L["'%s' - expected 'RRGGBB' or 'r g b'."], str))
|
||||
return
|
||||
end
|
||||
if r >= 0.0 and r <= 1.0 and g >= 0.0 and g <= 1.0 and b >= 0.0 and b <= 1.0 then
|
||||
--values are valid
|
||||
elseif r >= 0 and r <= 255 and g >= 0 and g <= 255 and b >= 0 and b <= 255 then
|
||||
--values are valid 0..255, convert to 0..1
|
||||
r = r / 255
|
||||
g = g / 255
|
||||
b = b / 255
|
||||
else
|
||||
--values are invalid
|
||||
usererr(info, inputpos, format(L["'%s' - values must all be either in the range 0-1 or 0-255."], str))
|
||||
end
|
||||
end
|
||||
|
||||
do_final(info, inputpos, tab, "set", r,g,b,a)
|
||||
|
||||
elseif tab.type=="keybinding" then
|
||||
------------ keybinding --------------------------------------------
|
||||
local str = strtrim(strlower(str))
|
||||
if str == "" then
|
||||
--TODO: Show current value
|
||||
return
|
||||
end
|
||||
local value = keybindingValidateFunc(str:upper())
|
||||
if value == false then
|
||||
usererr(info, inputpos, format(L["'%s' - Invalid Keybinding."], str))
|
||||
return
|
||||
end
|
||||
|
||||
do_final(info, inputpos, tab, "set", value)
|
||||
|
||||
elseif tab.type=="description" then
|
||||
------------ description --------------------
|
||||
-- ignore description, GUI config only
|
||||
else
|
||||
err(info, inputpos, "unknown options table item type '"..tostring(tab.type).."'")
|
||||
end
|
||||
end
|
||||
|
||||
--- Handle the chat command.
|
||||
-- This is usually called from a chat command handler to parse the command input as operations on an aceoptions table.\\
|
||||
-- AceConfigCmd uses this function internally when a slash command is registered with `:CreateChatCommand`
|
||||
-- @param slashcmd The slash command WITHOUT leading slash (only used for error output)
|
||||
-- @param appName The application name as given to `:RegisterOptionsTable()`
|
||||
-- @param input The commandline input (as given by the WoW handler, i.e. without the command itself)
|
||||
-- @usage
|
||||
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon", "AceConsole-3.0")
|
||||
-- -- Use AceConsole-3.0 to register a Chat Command
|
||||
-- MyAddon:RegisterChatCommand("mychat", "ChatCommand")
|
||||
--
|
||||
-- -- Show the GUI if no input is supplied, otherwise handle the chat input.
|
||||
-- function MyAddon:ChatCommand(input)
|
||||
-- -- Assuming "MyOptions" is the appName of a valid options table
|
||||
-- if not input or input:trim() == "" then
|
||||
-- LibStub("AceConfigDialog-3.0"):Open("MyOptions")
|
||||
-- else
|
||||
-- LibStub("AceConfigCmd-3.0").HandleCommand(MyAddon, "mychat", "MyOptions", input)
|
||||
-- end
|
||||
-- end
|
||||
function AceConfigCmd:HandleCommand(slashcmd, appName, input)
|
||||
|
||||
local optgetter = cfgreg:GetOptionsTable(appName)
|
||||
if not optgetter then
|
||||
error([[Usage: HandleCommand("slashcmd", "appName", "input"): 'appName' - no options table "]]..tostring(appName)..[[" has been registered]], 2)
|
||||
end
|
||||
local options = assert( optgetter("cmd", MAJOR) )
|
||||
|
||||
local info = { -- Don't try to recycle this, it gets handed off to callbacks and whatnot
|
||||
[0] = slashcmd,
|
||||
appName = appName,
|
||||
options = options,
|
||||
input = input,
|
||||
self = self,
|
||||
handler = self,
|
||||
uiType = "cmd",
|
||||
uiName = MAJOR,
|
||||
}
|
||||
|
||||
handle(info, 1, options, 0) -- (info, inputpos, table, depth)
|
||||
end
|
||||
|
||||
--- Utility function to create a slash command handler.
|
||||
-- Also registers tab completion with AceTab
|
||||
-- @param slashcmd The slash command WITHOUT leading slash (only used for error output)
|
||||
-- @param appName The application name as given to `:RegisterOptionsTable()`
|
||||
function AceConfigCmd:CreateChatCommand(slashcmd, appName)
|
||||
if not AceConsole then
|
||||
AceConsole = LibStub(AceConsoleName)
|
||||
end
|
||||
if AceConsole.RegisterChatCommand(self, slashcmd, function(input)
|
||||
AceConfigCmd.HandleCommand(self, slashcmd, appName, input) -- upgradable
|
||||
end,
|
||||
true) then -- succesfully registered so lets get the command -> app table in
|
||||
commands[slashcmd] = appName
|
||||
end
|
||||
end
|
||||
|
||||
--- Utility function that returns the options table that belongs to a slashcommand.
|
||||
-- Designed to be used for the AceTab interface.
|
||||
-- @param slashcmd The slash command WITHOUT leading slash (only used for error output)
|
||||
-- @return The options table associated with the slash command (or nil if the slash command was not registered)
|
||||
function AceConfigCmd:GetChatCommandOptions(slashcmd)
|
||||
return commands[slashcmd]
|
||||
end
|
||||
@@ -0,0 +1,4 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
..\FrameXML\UI.xsd">
|
||||
<Script file="AceConfigCmd-3.0.lua"/>
|
||||
</Ui>
|
||||
1901
MogIt/Libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua
Normal file
@@ -0,0 +1,4 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
..\FrameXML\UI.xsd">
|
||||
<Script file="AceConfigDialog-3.0.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,346 @@
|
||||
--- AceConfigRegistry-3.0 handles central registration of options tables in use by addons and modules.\\
|
||||
-- Options tables can be registered as raw tables, OR as function refs that return a table.\\
|
||||
-- Such functions receive three arguments: "uiType", "uiName", "appName". \\
|
||||
-- * Valid **uiTypes**: "cmd", "dropdown", "dialog". This is verified by the library at call time. \\
|
||||
-- * The **uiName** field is expected to contain the full name of the calling addon, including version, e.g. "FooBar-1.0". This is verified by the library at call time.\\
|
||||
-- * The **appName** field is the options table name as given at registration time \\
|
||||
--
|
||||
-- :IterateOptionsTables() (and :GetOptionsTable() if only given one argument) return a function reference that the requesting config handling addon must call with valid "uiType", "uiName".
|
||||
-- @class file
|
||||
-- @name AceConfigRegistry-3.0
|
||||
-- @release $Id: AceConfigRegistry-3.0.lua 921 2010-05-09 15:49:14Z nevcairiel $
|
||||
local MAJOR, MINOR = "AceConfigRegistry-3.0", 12
|
||||
local AceConfigRegistry = LibStub:NewLibrary(MAJOR, MINOR)
|
||||
|
||||
if not AceConfigRegistry then return end
|
||||
|
||||
AceConfigRegistry.tables = AceConfigRegistry.tables or {}
|
||||
|
||||
local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0")
|
||||
|
||||
if not AceConfigRegistry.callbacks then
|
||||
AceConfigRegistry.callbacks = CallbackHandler:New(AceConfigRegistry)
|
||||
end
|
||||
|
||||
-- Lua APIs
|
||||
local tinsert, tconcat = table.insert, table.concat
|
||||
local strfind, strmatch = string.find, string.match
|
||||
local type, tostring, select, pairs = type, tostring, select, pairs
|
||||
local error, assert = error, assert
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
-- Validating options table consistency:
|
||||
|
||||
|
||||
AceConfigRegistry.validated = {
|
||||
-- list of options table names ran through :ValidateOptionsTable automatically.
|
||||
-- CLEARED ON PURPOSE, since newer versions may have newer validators
|
||||
cmd = {},
|
||||
dropdown = {},
|
||||
dialog = {},
|
||||
}
|
||||
|
||||
|
||||
|
||||
local function err(msg, errlvl, ...)
|
||||
local t = {}
|
||||
for i=select("#",...),1,-1 do
|
||||
tinsert(t, (select(i, ...)))
|
||||
end
|
||||
error(MAJOR..":ValidateOptionsTable(): "..tconcat(t,".")..msg, errlvl+2)
|
||||
end
|
||||
|
||||
|
||||
local isstring={["string"]=true, _="string"}
|
||||
local isstringfunc={["string"]=true,["function"]=true, _="string or funcref"}
|
||||
local istable={["table"]=true, _="table"}
|
||||
local ismethodtable={["table"]=true,["string"]=true,["function"]=true, _="methodname, funcref or table"}
|
||||
local optstring={["nil"]=true,["string"]=true, _="string"}
|
||||
local optstringfunc={["nil"]=true,["string"]=true,["function"]=true, _="string or funcref"}
|
||||
local optnumber={["nil"]=true,["number"]=true, _="number"}
|
||||
local optmethod={["nil"]=true,["string"]=true,["function"]=true, _="methodname or funcref"}
|
||||
local optmethodfalse={["nil"]=true,["string"]=true,["function"]=true,["boolean"]={[false]=true}, _="methodname, funcref or false"}
|
||||
local optmethodnumber={["nil"]=true,["string"]=true,["function"]=true,["number"]=true, _="methodname, funcref or number"}
|
||||
local optmethodtable={["nil"]=true,["string"]=true,["function"]=true,["table"]=true, _="methodname, funcref or table"}
|
||||
local optmethodbool={["nil"]=true,["string"]=true,["function"]=true,["boolean"]=true, _="methodname, funcref or boolean"}
|
||||
local opttable={["nil"]=true,["table"]=true, _="table"}
|
||||
local optbool={["nil"]=true,["boolean"]=true, _="boolean"}
|
||||
local optboolnumber={["nil"]=true,["boolean"]=true,["number"]=true, _="boolean or number"}
|
||||
|
||||
local basekeys={
|
||||
type=isstring,
|
||||
name=isstringfunc,
|
||||
desc=optstringfunc,
|
||||
descStyle=optstring,
|
||||
order=optmethodnumber,
|
||||
validate=optmethodfalse,
|
||||
confirm=optmethodbool,
|
||||
confirmText=optstring,
|
||||
disabled=optmethodbool,
|
||||
hidden=optmethodbool,
|
||||
guiHidden=optmethodbool,
|
||||
dialogHidden=optmethodbool,
|
||||
dropdownHidden=optmethodbool,
|
||||
cmdHidden=optmethodbool,
|
||||
icon=optstringfunc,
|
||||
iconCoords=optmethodtable,
|
||||
handler=opttable,
|
||||
get=optmethodfalse,
|
||||
set=optmethodfalse,
|
||||
func=optmethodfalse,
|
||||
arg={["*"]=true},
|
||||
width=optstring,
|
||||
}
|
||||
|
||||
local typedkeys={
|
||||
header={},
|
||||
description={
|
||||
image=optstringfunc,
|
||||
imageCoords=optmethodtable,
|
||||
imageHeight=optnumber,
|
||||
imageWidth=optnumber,
|
||||
fontSize=optstringfunc,
|
||||
},
|
||||
group={
|
||||
args=istable,
|
||||
plugins=opttable,
|
||||
inline=optbool,
|
||||
cmdInline=optbool,
|
||||
guiInline=optbool,
|
||||
dropdownInline=optbool,
|
||||
dialogInline=optbool,
|
||||
childGroups=optstring,
|
||||
},
|
||||
execute={
|
||||
image=optstringfunc,
|
||||
imageCoords=optmethodtable,
|
||||
imageHeight=optnumber,
|
||||
imageWidth=optnumber,
|
||||
},
|
||||
input={
|
||||
pattern=optstring,
|
||||
usage=optstring,
|
||||
control=optstring,
|
||||
dialogControl=optstring,
|
||||
dropdownControl=optstring,
|
||||
multiline=optboolnumber,
|
||||
},
|
||||
toggle={
|
||||
tristate=optbool,
|
||||
image=optstringfunc,
|
||||
imageCoords=optmethodtable,
|
||||
},
|
||||
tristate={
|
||||
},
|
||||
range={
|
||||
min=optnumber,
|
||||
softMin=optnumber,
|
||||
max=optnumber,
|
||||
softMax=optnumber,
|
||||
step=optnumber,
|
||||
bigStep=optnumber,
|
||||
isPercent=optbool,
|
||||
},
|
||||
select={
|
||||
values=ismethodtable,
|
||||
style={
|
||||
["nil"]=true,
|
||||
["string"]={dropdown=true,radio=true},
|
||||
_="string: 'dropdown' or 'radio'"
|
||||
},
|
||||
control=optstring,
|
||||
dialogControl=optstring,
|
||||
dropdownControl=optstring,
|
||||
},
|
||||
multiselect={
|
||||
values=ismethodtable,
|
||||
style=optstring,
|
||||
tristate=optbool,
|
||||
control=optstring,
|
||||
dialogControl=optstring,
|
||||
dropdownControl=optstring,
|
||||
},
|
||||
color={
|
||||
hasAlpha=optbool,
|
||||
},
|
||||
keybinding={
|
||||
-- TODO
|
||||
},
|
||||
}
|
||||
|
||||
local function validateKey(k,errlvl,...)
|
||||
errlvl=(errlvl or 0)+1
|
||||
if type(k)~="string" then
|
||||
err("["..tostring(k).."] - key is not a string", errlvl,...)
|
||||
end
|
||||
if strfind(k, "[%c\127]") then
|
||||
err("["..tostring(k).."] - key name contained control characters", errlvl,...)
|
||||
end
|
||||
end
|
||||
|
||||
local function validateVal(v, oktypes, errlvl,...)
|
||||
errlvl=(errlvl or 0)+1
|
||||
local isok=oktypes[type(v)] or oktypes["*"]
|
||||
|
||||
if not isok then
|
||||
err(": expected a "..oktypes._..", got '"..tostring(v).."'", errlvl,...)
|
||||
end
|
||||
if type(isok)=="table" then -- isok was a table containing specific values to be tested for!
|
||||
if not isok[v] then
|
||||
err(": did not expect "..type(v).." value '"..tostring(v).."'", errlvl,...)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function validate(options,errlvl,...)
|
||||
errlvl=(errlvl or 0)+1
|
||||
-- basic consistency
|
||||
if type(options)~="table" then
|
||||
err(": expected a table, got a "..type(options), errlvl,...)
|
||||
end
|
||||
if type(options.type)~="string" then
|
||||
err(".type: expected a string, got a "..type(options.type), errlvl,...)
|
||||
end
|
||||
|
||||
-- get type and 'typedkeys' member
|
||||
local tk = typedkeys[options.type]
|
||||
if not tk then
|
||||
err(".type: unknown type '"..options.type.."'", errlvl,...)
|
||||
end
|
||||
|
||||
-- make sure that all options[] are known parameters
|
||||
for k,v in pairs(options) do
|
||||
if not (tk[k] or basekeys[k]) then
|
||||
err(": unknown parameter", errlvl,tostring(k),...)
|
||||
end
|
||||
end
|
||||
|
||||
-- verify that required params are there, and that everything is the right type
|
||||
for k,oktypes in pairs(basekeys) do
|
||||
validateVal(options[k], oktypes, errlvl,k,...)
|
||||
end
|
||||
for k,oktypes in pairs(tk) do
|
||||
validateVal(options[k], oktypes, errlvl,k,...)
|
||||
end
|
||||
|
||||
-- extra logic for groups
|
||||
if options.type=="group" then
|
||||
for k,v in pairs(options.args) do
|
||||
validateKey(k,errlvl,"args",...)
|
||||
validate(v, errlvl,k,"args",...)
|
||||
end
|
||||
if options.plugins then
|
||||
for plugname,plugin in pairs(options.plugins) do
|
||||
if type(plugin)~="table" then
|
||||
err(": expected a table, got '"..tostring(plugin).."'", errlvl,tostring(plugname),"plugins",...)
|
||||
end
|
||||
for k,v in pairs(plugin) do
|
||||
validateKey(k,errlvl,tostring(plugname),"plugins",...)
|
||||
validate(v, errlvl,k,tostring(plugname),"plugins",...)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Validates basic structure and integrity of an options table \\
|
||||
-- Does NOT verify that get/set etc actually exist, since they can be defined at any depth
|
||||
-- @param options The table to be validated
|
||||
-- @param name The name of the table to be validated (shown in any error message)
|
||||
-- @param errlvl (optional number) error level offset, default 0 (=errors point to the function calling :ValidateOptionsTable)
|
||||
function AceConfigRegistry:ValidateOptionsTable(options,name,errlvl)
|
||||
errlvl=(errlvl or 0)+1
|
||||
name = name or "Optionstable"
|
||||
if not options.name then
|
||||
options.name=name -- bit of a hack, the root level doesn't really need a .name :-/
|
||||
end
|
||||
validate(options,errlvl,name)
|
||||
end
|
||||
|
||||
--- Fires a "ConfigTableChange" callback for those listening in on it, allowing config GUIs to refresh.
|
||||
-- You should call this function if your options table changed from any outside event, like a game event
|
||||
-- or a timer.
|
||||
-- @param appName The application name as given to `:RegisterOptionsTable()`
|
||||
function AceConfigRegistry:NotifyChange(appName)
|
||||
if not AceConfigRegistry.tables[appName] then return end
|
||||
AceConfigRegistry.callbacks:Fire("ConfigTableChange", appName)
|
||||
end
|
||||
|
||||
-- -------------------------------------------------------------------
|
||||
-- Registering and retreiving options tables:
|
||||
|
||||
|
||||
-- validateGetterArgs: helper function for :GetOptionsTable (or, rather, the getter functions returned by it)
|
||||
|
||||
local function validateGetterArgs(uiType, uiName, errlvl)
|
||||
errlvl=(errlvl or 0)+2
|
||||
if uiType~="cmd" and uiType~="dropdown" and uiType~="dialog" then
|
||||
error(MAJOR..": Requesting options table: 'uiType' - invalid configuration UI type, expected 'cmd', 'dropdown' or 'dialog'", errlvl)
|
||||
end
|
||||
if not strmatch(uiName, "[A-Za-z]%-[0-9]") then -- Expecting e.g. "MyLib-1.2"
|
||||
error(MAJOR..": Requesting options table: 'uiName' - badly formatted or missing version number. Expected e.g. 'MyLib-1.2'", errlvl)
|
||||
end
|
||||
end
|
||||
|
||||
--- Register an options table with the config registry.
|
||||
-- @param appName The application name as given to `:RegisterOptionsTable()`
|
||||
-- @param options The options table, OR a function reference that generates it on demand. \\
|
||||
-- See the top of the page for info on arguments passed to such functions.
|
||||
function AceConfigRegistry:RegisterOptionsTable(appName, options)
|
||||
if type(options)=="table" then
|
||||
if options.type~="group" then -- quick sanity checker
|
||||
error(MAJOR..": RegisterOptionsTable(appName, options): 'options' - missing type='group' member in root group", 2)
|
||||
end
|
||||
AceConfigRegistry.tables[appName] = function(uiType, uiName, errlvl)
|
||||
errlvl=(errlvl or 0)+1
|
||||
validateGetterArgs(uiType, uiName, errlvl)
|
||||
if not AceConfigRegistry.validated[uiType][appName] then
|
||||
AceConfigRegistry:ValidateOptionsTable(options, appName, errlvl) -- upgradable
|
||||
AceConfigRegistry.validated[uiType][appName] = true
|
||||
end
|
||||
return options
|
||||
end
|
||||
elseif type(options)=="function" then
|
||||
AceConfigRegistry.tables[appName] = function(uiType, uiName, errlvl)
|
||||
errlvl=(errlvl or 0)+1
|
||||
validateGetterArgs(uiType, uiName, errlvl)
|
||||
local tab = assert(options(uiType, uiName, appName))
|
||||
if not AceConfigRegistry.validated[uiType][appName] then
|
||||
AceConfigRegistry:ValidateOptionsTable(tab, appName, errlvl) -- upgradable
|
||||
AceConfigRegistry.validated[uiType][appName] = true
|
||||
end
|
||||
return tab
|
||||
end
|
||||
else
|
||||
error(MAJOR..": RegisterOptionsTable(appName, options): 'options' - expected table or function reference", 2)
|
||||
end
|
||||
end
|
||||
|
||||
--- Returns an iterator of ["appName"]=funcref pairs
|
||||
function AceConfigRegistry:IterateOptionsTables()
|
||||
return pairs(AceConfigRegistry.tables)
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
--- Query the registry for a specific options table.
|
||||
-- If only appName is given, a function is returned which you
|
||||
-- can call with (uiType,uiName) to get the table.\\
|
||||
-- If uiType&uiName are given, the table is returned.
|
||||
-- @param appName The application name as given to `:RegisterOptionsTable()`
|
||||
-- @param uiType The type of UI to get the table for, one of "cmd", "dropdown", "dialog"
|
||||
-- @param uiName The name of the library/addon querying for the table, e.g. "MyLib-1.0"
|
||||
function AceConfigRegistry:GetOptionsTable(appName, uiType, uiName)
|
||||
local f = AceConfigRegistry.tables[appName]
|
||||
if not f then
|
||||
return nil
|
||||
end
|
||||
|
||||
if uiType then
|
||||
return f(uiType,uiName,1) -- get the table for us
|
||||
else
|
||||
return f -- return the function
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,4 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
..\FrameXML\UI.xsd">
|
||||
<Script file="AceConfigRegistry-3.0.lua"/>
|
||||
</Ui>
|
||||
728
MogIt/Libs/AceDB-3.0/AceDB-3.0.lua
Normal file
@@ -0,0 +1,728 @@
|
||||
--- **AceDB-3.0** manages the SavedVariables of your addon.
|
||||
-- It offers profile management, smart defaults and namespaces for modules.\\
|
||||
-- Data can be saved in different data-types, depending on its intended usage.
|
||||
-- The most common data-type is the `profile` type, which allows the user to choose
|
||||
-- the active profile, and manage the profiles of all of his characters.\\
|
||||
-- The following data types are available:
|
||||
-- * **char** Character-specific data. Every character has its own database.
|
||||
-- * **realm** Realm-specific data. All of the players characters on the same realm share this database.
|
||||
-- * **class** Class-specific data. All of the players characters of the same class share this database.
|
||||
-- * **race** Race-specific data. All of the players characters of the same race share this database.
|
||||
-- * **faction** Faction-specific data. All of the players characters of the same faction share this database.
|
||||
-- * **factionrealm** Faction and realm specific data. All of the players characters on the same realm and of the same faction share this database.
|
||||
-- * **global** Global Data. All characters on the same account share this database.
|
||||
-- * **profile** Profile-specific data. All characters using the same profile share this database. The user can control which profile should be used.
|
||||
--
|
||||
-- Creating a new Database using the `:New` function will return a new DBObject. A database will inherit all functions
|
||||
-- of the DBObjectLib listed here. \\
|
||||
-- If you create a new namespaced child-database (`:RegisterNamespace`), you'll get a DBObject as well, but note
|
||||
-- that the child-databases cannot individually change their profile, and are linked to their parents profile - and because of that,
|
||||
-- the profile related APIs are not available. Only `:RegisterDefaults` and `:ResetProfile` are available on child-databases.
|
||||
--
|
||||
-- For more details on how to use AceDB-3.0, see the [[AceDB-3.0 Tutorial]].
|
||||
--
|
||||
-- You may also be interested in [[libdualspec-1-0|LibDualSpec-1.0]] to do profile switching automatically when switching specs.
|
||||
--
|
||||
-- @usage
|
||||
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("DBExample")
|
||||
--
|
||||
-- -- declare defaults to be used in the DB
|
||||
-- local defaults = {
|
||||
-- profile = {
|
||||
-- setting = true,
|
||||
-- }
|
||||
-- }
|
||||
--
|
||||
-- function MyAddon:OnInitialize()
|
||||
-- -- Assuming the .toc says ## SavedVariables: MyAddonDB
|
||||
-- self.db = LibStub("AceDB-3.0"):New("MyAddonDB", defaults, true)
|
||||
-- end
|
||||
-- @class file
|
||||
-- @name AceDB-3.0.lua
|
||||
-- @release $Id: AceDB-3.0.lua 940 2010-06-19 08:01:47Z nevcairiel $
|
||||
local ACEDB_MAJOR, ACEDB_MINOR = "AceDB-3.0", 21
|
||||
local AceDB, oldminor = LibStub:NewLibrary(ACEDB_MAJOR, ACEDB_MINOR)
|
||||
|
||||
if not AceDB then return end -- No upgrade needed
|
||||
|
||||
-- Lua APIs
|
||||
local type, pairs, next, error = type, pairs, next, error
|
||||
local setmetatable, getmetatable, rawset, rawget = setmetatable, getmetatable, rawset, rawget
|
||||
|
||||
-- WoW APIs
|
||||
local _G = _G
|
||||
|
||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||
-- List them here for Mikk's FindGlobals script
|
||||
-- GLOBALS: LibStub
|
||||
|
||||
AceDB.db_registry = AceDB.db_registry or {}
|
||||
AceDB.frame = AceDB.frame or CreateFrame("Frame")
|
||||
|
||||
local CallbackHandler
|
||||
local CallbackDummy = { Fire = function() end }
|
||||
|
||||
local DBObjectLib = {}
|
||||
|
||||
--[[-------------------------------------------------------------------------
|
||||
AceDB Utility Functions
|
||||
---------------------------------------------------------------------------]]
|
||||
|
||||
-- Simple shallow copy for copying defaults
|
||||
local function copyTable(src, dest)
|
||||
if type(dest) ~= "table" then dest = {} end
|
||||
if type(src) == "table" then
|
||||
for k,v in pairs(src) do
|
||||
if type(v) == "table" then
|
||||
-- try to index the key first so that the metatable creates the defaults, if set, and use that table
|
||||
v = copyTable(v, dest[k])
|
||||
end
|
||||
dest[k] = v
|
||||
end
|
||||
end
|
||||
return dest
|
||||
end
|
||||
|
||||
-- Called to add defaults to a section of the database
|
||||
--
|
||||
-- When a ["*"] default section is indexed with a new key, a table is returned
|
||||
-- and set in the host table. These tables must be cleaned up by removeDefaults
|
||||
-- in order to ensure we don't write empty default tables.
|
||||
local function copyDefaults(dest, src)
|
||||
-- this happens if some value in the SV overwrites our default value with a non-table
|
||||
--if type(dest) ~= "table" then return end
|
||||
for k, v in pairs(src) do
|
||||
if k == "*" or k == "**" then
|
||||
if type(v) == "table" then
|
||||
-- This is a metatable used for table defaults
|
||||
local mt = {
|
||||
-- This handles the lookup and creation of new subtables
|
||||
__index = function(t,k)
|
||||
if k == nil then return nil end
|
||||
local tbl = {}
|
||||
copyDefaults(tbl, v)
|
||||
rawset(t, k, tbl)
|
||||
return tbl
|
||||
end,
|
||||
}
|
||||
setmetatable(dest, mt)
|
||||
-- handle already existing tables in the SV
|
||||
for dk, dv in pairs(dest) do
|
||||
if not rawget(src, dk) and type(dv) == "table" then
|
||||
copyDefaults(dv, v)
|
||||
end
|
||||
end
|
||||
else
|
||||
-- Values are not tables, so this is just a simple return
|
||||
local mt = {__index = function(t,k) return k~=nil and v or nil end}
|
||||
setmetatable(dest, mt)
|
||||
end
|
||||
elseif type(v) == "table" then
|
||||
if not rawget(dest, k) then rawset(dest, k, {}) end
|
||||
if type(dest[k]) == "table" then
|
||||
copyDefaults(dest[k], v)
|
||||
if src['**'] then
|
||||
copyDefaults(dest[k], src['**'])
|
||||
end
|
||||
end
|
||||
else
|
||||
if rawget(dest, k) == nil then
|
||||
rawset(dest, k, v)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Called to remove all defaults in the default table from the database
|
||||
local function removeDefaults(db, defaults, blocker)
|
||||
-- remove all metatables from the db, so we don't accidentally create new sub-tables through them
|
||||
setmetatable(db, nil)
|
||||
-- loop through the defaults and remove their content
|
||||
for k,v in pairs(defaults) do
|
||||
if k == "*" or k == "**" then
|
||||
if type(v) == "table" then
|
||||
-- Loop through all the actual k,v pairs and remove
|
||||
for key, value in pairs(db) do
|
||||
if type(value) == "table" then
|
||||
-- if the key was not explicitly specified in the defaults table, just strip everything from * and ** tables
|
||||
if defaults[key] == nil and (not blocker or blocker[key] == nil) then
|
||||
removeDefaults(value, v)
|
||||
-- if the table is empty afterwards, remove it
|
||||
if next(value) == nil then
|
||||
db[key] = nil
|
||||
end
|
||||
-- if it was specified, only strip ** content, but block values which were set in the key table
|
||||
elseif k == "**" then
|
||||
removeDefaults(value, v, defaults[key])
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif k == "*" then
|
||||
-- check for non-table default
|
||||
for key, value in pairs(db) do
|
||||
if defaults[key] == nil and v == value then
|
||||
db[key] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif type(v) == "table" and type(db[k]) == "table" then
|
||||
-- if a blocker was set, dive into it, to allow multi-level defaults
|
||||
removeDefaults(db[k], v, blocker and blocker[k])
|
||||
if next(db[k]) == nil then
|
||||
db[k] = nil
|
||||
end
|
||||
else
|
||||
-- check if the current value matches the default, and that its not blocked by another defaults table
|
||||
if db[k] == defaults[k] and (not blocker or blocker[k] == nil) then
|
||||
db[k] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- This is called when a table section is first accessed, to set up the defaults
|
||||
local function initSection(db, section, svstore, key, defaults)
|
||||
local sv = rawget(db, "sv")
|
||||
|
||||
local tableCreated
|
||||
if not sv[svstore] then sv[svstore] = {} end
|
||||
if not sv[svstore][key] then
|
||||
sv[svstore][key] = {}
|
||||
tableCreated = true
|
||||
end
|
||||
|
||||
local tbl = sv[svstore][key]
|
||||
|
||||
if defaults then
|
||||
copyDefaults(tbl, defaults)
|
||||
end
|
||||
rawset(db, section, tbl)
|
||||
|
||||
return tableCreated, tbl
|
||||
end
|
||||
|
||||
-- Metatable to handle the dynamic creation of sections and copying of sections.
|
||||
local dbmt = {
|
||||
__index = function(t, section)
|
||||
local keys = rawget(t, "keys")
|
||||
local key = keys[section]
|
||||
if key then
|
||||
local defaultTbl = rawget(t, "defaults")
|
||||
local defaults = defaultTbl and defaultTbl[section]
|
||||
|
||||
if section == "profile" then
|
||||
local new = initSection(t, section, "profiles", key, defaults)
|
||||
if new then
|
||||
-- Callback: OnNewProfile, database, newProfileKey
|
||||
t.callbacks:Fire("OnNewProfile", t, key)
|
||||
end
|
||||
elseif section == "profiles" then
|
||||
local sv = rawget(t, "sv")
|
||||
if not sv.profiles then sv.profiles = {} end
|
||||
rawset(t, "profiles", sv.profiles)
|
||||
elseif section == "global" then
|
||||
local sv = rawget(t, "sv")
|
||||
if not sv.global then sv.global = {} end
|
||||
if defaults then
|
||||
copyDefaults(sv.global, defaults)
|
||||
end
|
||||
rawset(t, section, sv.global)
|
||||
else
|
||||
initSection(t, section, section, key, defaults)
|
||||
end
|
||||
end
|
||||
|
||||
return rawget(t, section)
|
||||
end
|
||||
}
|
||||
|
||||
local function validateDefaults(defaults, keyTbl, offset)
|
||||
if not defaults then return end
|
||||
offset = offset or 0
|
||||
for k in pairs(defaults) do
|
||||
if not keyTbl[k] or k == "profiles" then
|
||||
error(("Usage: AceDBObject:RegisterDefaults(defaults): '%s' is not a valid datatype."):format(k), 3 + offset)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local preserve_keys = {
|
||||
["callbacks"] = true,
|
||||
["RegisterCallback"] = true,
|
||||
["UnregisterCallback"] = true,
|
||||
["UnregisterAllCallbacks"] = true,
|
||||
["children"] = true,
|
||||
}
|
||||
|
||||
local realmKey = GetRealmName()
|
||||
local charKey = UnitName("player") .. " - " .. realmKey
|
||||
local _, classKey = UnitClass("player")
|
||||
local _, raceKey = UnitRace("player")
|
||||
local factionKey = UnitFactionGroup("player")
|
||||
local factionrealmKey = factionKey .. " - " .. realmKey
|
||||
-- Actual database initialization function
|
||||
local function initdb(sv, defaults, defaultProfile, olddb, parent)
|
||||
-- Generate the database keys for each section
|
||||
|
||||
-- map "true" to our "Default" profile
|
||||
if defaultProfile == true then defaultProfile = "Default" end
|
||||
|
||||
local profileKey
|
||||
if not parent then
|
||||
-- Make a container for profile keys
|
||||
if not sv.profileKeys then sv.profileKeys = {} end
|
||||
|
||||
-- Try to get the profile selected from the char db
|
||||
profileKey = sv.profileKeys[charKey] or defaultProfile or charKey
|
||||
|
||||
-- save the selected profile for later
|
||||
sv.profileKeys[charKey] = profileKey
|
||||
else
|
||||
-- Use the profile of the parents DB
|
||||
profileKey = parent.keys.profile or defaultProfile or charKey
|
||||
|
||||
-- clear the profileKeys in the DB, namespaces don't need to store them
|
||||
sv.profileKeys = nil
|
||||
end
|
||||
|
||||
-- This table contains keys that enable the dynamic creation
|
||||
-- of each section of the table. The 'global' and 'profiles'
|
||||
-- have a key of true, since they are handled in a special case
|
||||
local keyTbl= {
|
||||
["char"] = charKey,
|
||||
["realm"] = realmKey,
|
||||
["class"] = classKey,
|
||||
["race"] = raceKey,
|
||||
["faction"] = factionKey,
|
||||
["factionrealm"] = factionrealmKey,
|
||||
["profile"] = profileKey,
|
||||
["global"] = true,
|
||||
["profiles"] = true,
|
||||
}
|
||||
|
||||
validateDefaults(defaults, keyTbl, 1)
|
||||
|
||||
-- This allows us to use this function to reset an entire database
|
||||
-- Clear out the old database
|
||||
if olddb then
|
||||
for k,v in pairs(olddb) do if not preserve_keys[k] then olddb[k] = nil end end
|
||||
end
|
||||
|
||||
-- Give this database the metatable so it initializes dynamically
|
||||
local db = setmetatable(olddb or {}, dbmt)
|
||||
|
||||
if not rawget(db, "callbacks") then
|
||||
-- try to load CallbackHandler-1.0 if it loaded after our library
|
||||
if not CallbackHandler then CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0", true) end
|
||||
db.callbacks = CallbackHandler and CallbackHandler:New(db) or CallbackDummy
|
||||
end
|
||||
|
||||
-- Copy methods locally into the database object, to avoid hitting
|
||||
-- the metatable when calling methods
|
||||
|
||||
if not parent then
|
||||
for name, func in pairs(DBObjectLib) do
|
||||
db[name] = func
|
||||
end
|
||||
else
|
||||
-- hack this one in
|
||||
db.RegisterDefaults = DBObjectLib.RegisterDefaults
|
||||
db.ResetProfile = DBObjectLib.ResetProfile
|
||||
end
|
||||
|
||||
-- Set some properties in the database object
|
||||
db.profiles = sv.profiles
|
||||
db.keys = keyTbl
|
||||
db.sv = sv
|
||||
--db.sv_name = name
|
||||
db.defaults = defaults
|
||||
db.parent = parent
|
||||
|
||||
-- store the DB in the registry
|
||||
AceDB.db_registry[db] = true
|
||||
|
||||
return db
|
||||
end
|
||||
|
||||
-- handle PLAYER_LOGOUT
|
||||
-- strip all defaults from all databases
|
||||
-- and cleans up empty sections
|
||||
local function logoutHandler(frame, event)
|
||||
if event == "PLAYER_LOGOUT" then
|
||||
for db in pairs(AceDB.db_registry) do
|
||||
db.callbacks:Fire("OnDatabaseShutdown", db)
|
||||
db:RegisterDefaults(nil)
|
||||
|
||||
-- cleanup sections that are empty without defaults
|
||||
local sv = rawget(db, "sv")
|
||||
for section in pairs(db.keys) do
|
||||
if rawget(sv, section) then
|
||||
-- global is special, all other sections have sub-entrys
|
||||
-- also don't delete empty profiles on main dbs, only on namespaces
|
||||
if section ~= "global" and (section ~= "profiles" or rawget(db, "parent")) then
|
||||
for key in pairs(sv[section]) do
|
||||
if not next(sv[section][key]) then
|
||||
sv[section][key] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
if not next(sv[section]) then
|
||||
sv[section] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
AceDB.frame:RegisterEvent("PLAYER_LOGOUT")
|
||||
AceDB.frame:SetScript("OnEvent", logoutHandler)
|
||||
|
||||
|
||||
--[[-------------------------------------------------------------------------
|
||||
AceDB Object Method Definitions
|
||||
---------------------------------------------------------------------------]]
|
||||
|
||||
--- Sets the defaults table for the given database object by clearing any
|
||||
-- that are currently set, and then setting the new defaults.
|
||||
-- @param defaults A table of defaults for this database
|
||||
function DBObjectLib:RegisterDefaults(defaults)
|
||||
if defaults and type(defaults) ~= "table" then
|
||||
error("Usage: AceDBObject:RegisterDefaults(defaults): 'defaults' - table or nil expected.", 2)
|
||||
end
|
||||
|
||||
validateDefaults(defaults, self.keys)
|
||||
|
||||
-- Remove any currently set defaults
|
||||
if self.defaults then
|
||||
for section,key in pairs(self.keys) do
|
||||
if self.defaults[section] and rawget(self, section) then
|
||||
removeDefaults(self[section], self.defaults[section])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Set the DBObject.defaults table
|
||||
self.defaults = defaults
|
||||
|
||||
-- Copy in any defaults, only touching those sections already created
|
||||
if defaults then
|
||||
for section,key in pairs(self.keys) do
|
||||
if defaults[section] and rawget(self, section) then
|
||||
copyDefaults(self[section], defaults[section])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Changes the profile of the database and all of it's namespaces to the
|
||||
-- supplied named profile
|
||||
-- @param name The name of the profile to set as the current profile
|
||||
function DBObjectLib:SetProfile(name)
|
||||
if type(name) ~= "string" then
|
||||
error("Usage: AceDBObject:SetProfile(name): 'name' - string expected.", 2)
|
||||
end
|
||||
|
||||
-- changing to the same profile, dont do anything
|
||||
if name == self.keys.profile then return end
|
||||
|
||||
local oldProfile = self.profile
|
||||
local defaults = self.defaults and self.defaults.profile
|
||||
|
||||
-- Callback: OnProfileShutdown, database
|
||||
self.callbacks:Fire("OnProfileShutdown", self)
|
||||
|
||||
if oldProfile and defaults then
|
||||
-- Remove the defaults from the old profile
|
||||
removeDefaults(oldProfile, defaults)
|
||||
end
|
||||
|
||||
self.profile = nil
|
||||
self.keys["profile"] = name
|
||||
|
||||
-- if the storage exists, save the new profile
|
||||
-- this won't exist on namespaces.
|
||||
if self.sv.profileKeys then
|
||||
self.sv.profileKeys[charKey] = name
|
||||
end
|
||||
|
||||
-- populate to child namespaces
|
||||
if self.children then
|
||||
for _, db in pairs(self.children) do
|
||||
DBObjectLib.SetProfile(db, name)
|
||||
end
|
||||
end
|
||||
|
||||
-- Callback: OnProfileChanged, database, newProfileKey
|
||||
self.callbacks:Fire("OnProfileChanged", self, name)
|
||||
end
|
||||
|
||||
--- Returns a table with the names of the existing profiles in the database.
|
||||
-- You can optionally supply a table to re-use for this purpose.
|
||||
-- @param tbl A table to store the profile names in (optional)
|
||||
function DBObjectLib:GetProfiles(tbl)
|
||||
if tbl and type(tbl) ~= "table" then
|
||||
error("Usage: AceDBObject:GetProfiles(tbl): 'tbl' - table or nil expected.", 2)
|
||||
end
|
||||
|
||||
-- Clear the container table
|
||||
if tbl then
|
||||
for k,v in pairs(tbl) do tbl[k] = nil end
|
||||
else
|
||||
tbl = {}
|
||||
end
|
||||
|
||||
local curProfile = self.keys.profile
|
||||
|
||||
local i = 0
|
||||
for profileKey in pairs(self.profiles) do
|
||||
i = i + 1
|
||||
tbl[i] = profileKey
|
||||
if curProfile and profileKey == curProfile then curProfile = nil end
|
||||
end
|
||||
|
||||
-- Add the current profile, if it hasn't been created yet
|
||||
if curProfile then
|
||||
i = i + 1
|
||||
tbl[i] = curProfile
|
||||
end
|
||||
|
||||
return tbl, i
|
||||
end
|
||||
|
||||
--- Returns the current profile name used by the database
|
||||
function DBObjectLib:GetCurrentProfile()
|
||||
return self.keys.profile
|
||||
end
|
||||
|
||||
--- Deletes a named profile. This profile must not be the active profile.
|
||||
-- @param name The name of the profile to be deleted
|
||||
-- @param silent If true, do not raise an error when the profile does not exist
|
||||
function DBObjectLib:DeleteProfile(name, silent)
|
||||
if type(name) ~= "string" then
|
||||
error("Usage: AceDBObject:DeleteProfile(name): 'name' - string expected.", 2)
|
||||
end
|
||||
|
||||
if self.keys.profile == name then
|
||||
error("Cannot delete the active profile in an AceDBObject.", 2)
|
||||
end
|
||||
|
||||
if not rawget(self.profiles, name) and not silent then
|
||||
error("Cannot delete profile '" .. name .. "'. It does not exist.", 2)
|
||||
end
|
||||
|
||||
self.profiles[name] = nil
|
||||
|
||||
-- populate to child namespaces
|
||||
if self.children then
|
||||
for _, db in pairs(self.children) do
|
||||
DBObjectLib.DeleteProfile(db, name, true)
|
||||
end
|
||||
end
|
||||
|
||||
-- Callback: OnProfileDeleted, database, profileKey
|
||||
self.callbacks:Fire("OnProfileDeleted", self, name)
|
||||
end
|
||||
|
||||
--- Copies a named profile into the current profile, overwriting any conflicting
|
||||
-- settings.
|
||||
-- @param name The name of the profile to be copied into the current profile
|
||||
-- @param silent If true, do not raise an error when the profile does not exist
|
||||
function DBObjectLib:CopyProfile(name, silent)
|
||||
if type(name) ~= "string" then
|
||||
error("Usage: AceDBObject:CopyProfile(name): 'name' - string expected.", 2)
|
||||
end
|
||||
|
||||
if name == self.keys.profile then
|
||||
error("Cannot have the same source and destination profiles.", 2)
|
||||
end
|
||||
|
||||
if not rawget(self.profiles, name) and not silent then
|
||||
error("Cannot copy profile '" .. name .. "'. It does not exist.", 2)
|
||||
end
|
||||
|
||||
-- Reset the profile before copying
|
||||
DBObjectLib.ResetProfile(self, nil, true)
|
||||
|
||||
local profile = self.profile
|
||||
local source = self.profiles[name]
|
||||
|
||||
copyTable(source, profile)
|
||||
|
||||
-- populate to child namespaces
|
||||
if self.children then
|
||||
for _, db in pairs(self.children) do
|
||||
DBObjectLib.CopyProfile(db, name, true)
|
||||
end
|
||||
end
|
||||
|
||||
-- Callback: OnProfileCopied, database, sourceProfileKey
|
||||
self.callbacks:Fire("OnProfileCopied", self, name)
|
||||
end
|
||||
|
||||
--- Resets the current profile to the default values (if specified).
|
||||
-- @param noChildren if set to true, the reset will not be populated to the child namespaces of this DB object
|
||||
-- @param noCallbacks if set to true, won't fire the OnProfileReset callback
|
||||
function DBObjectLib:ResetProfile(noChildren, noCallbacks)
|
||||
local profile = self.profile
|
||||
|
||||
for k,v in pairs(profile) do
|
||||
profile[k] = nil
|
||||
end
|
||||
|
||||
local defaults = self.defaults and self.defaults.profile
|
||||
if defaults then
|
||||
copyDefaults(profile, defaults)
|
||||
end
|
||||
|
||||
-- populate to child namespaces
|
||||
if self.children and not noChildren then
|
||||
for _, db in pairs(self.children) do
|
||||
DBObjectLib.ResetProfile(db, nil, noCallbacks)
|
||||
end
|
||||
end
|
||||
|
||||
-- Callback: OnProfileReset, database
|
||||
if not noCallbacks then
|
||||
self.callbacks:Fire("OnProfileReset", self)
|
||||
end
|
||||
end
|
||||
|
||||
--- Resets the entire database, using the string defaultProfile as the new default
|
||||
-- profile.
|
||||
-- @param defaultProfile The profile name to use as the default
|
||||
function DBObjectLib:ResetDB(defaultProfile)
|
||||
if defaultProfile and type(defaultProfile) ~= "string" then
|
||||
error("Usage: AceDBObject:ResetDB(defaultProfile): 'defaultProfile' - string or nil expected.", 2)
|
||||
end
|
||||
|
||||
local sv = self.sv
|
||||
for k,v in pairs(sv) do
|
||||
sv[k] = nil
|
||||
end
|
||||
|
||||
local parent = self.parent
|
||||
|
||||
initdb(sv, self.defaults, defaultProfile, self)
|
||||
|
||||
-- fix the child namespaces
|
||||
if self.children then
|
||||
if not sv.namespaces then sv.namespaces = {} end
|
||||
for name, db in pairs(self.children) do
|
||||
if not sv.namespaces[name] then sv.namespaces[name] = {} end
|
||||
initdb(sv.namespaces[name], db.defaults, self.keys.profile, db, self)
|
||||
end
|
||||
end
|
||||
|
||||
-- Callback: OnDatabaseReset, database
|
||||
self.callbacks:Fire("OnDatabaseReset", self)
|
||||
-- Callback: OnProfileChanged, database, profileKey
|
||||
self.callbacks:Fire("OnProfileChanged", self, self.keys["profile"])
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Creates a new database namespace, directly tied to the database. This
|
||||
-- is a full scale database in it's own rights other than the fact that
|
||||
-- it cannot control its profile individually
|
||||
-- @param name The name of the new namespace
|
||||
-- @param defaults A table of values to use as defaults
|
||||
function DBObjectLib:RegisterNamespace(name, defaults)
|
||||
if type(name) ~= "string" then
|
||||
error("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - string expected.", 2)
|
||||
end
|
||||
if defaults and type(defaults) ~= "table" then
|
||||
error("Usage: AceDBObject:RegisterNamespace(name, defaults): 'defaults' - table or nil expected.", 2)
|
||||
end
|
||||
if self.children and self.children[name] then
|
||||
error ("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - a namespace with that name already exists.", 2)
|
||||
end
|
||||
|
||||
local sv = self.sv
|
||||
if not sv.namespaces then sv.namespaces = {} end
|
||||
if not sv.namespaces[name] then
|
||||
sv.namespaces[name] = {}
|
||||
end
|
||||
|
||||
local newDB = initdb(sv.namespaces[name], defaults, self.keys.profile, nil, self)
|
||||
|
||||
if not self.children then self.children = {} end
|
||||
self.children[name] = newDB
|
||||
return newDB
|
||||
end
|
||||
|
||||
--- Returns an already existing namespace from the database object.
|
||||
-- @param name The name of the new namespace
|
||||
-- @param silent if true, the addon is optional, silently return nil if its not found
|
||||
-- @usage
|
||||
-- local namespace = self.db:GetNamespace('namespace')
|
||||
-- @return the namespace object if found
|
||||
function DBObjectLib:GetNamespace(name, silent)
|
||||
if type(name) ~= "string" then
|
||||
error("Usage: AceDBObject:GetNamespace(name): 'name' - string expected.", 2)
|
||||
end
|
||||
if not silent and not (self.children and self.children[name]) then
|
||||
error ("Usage: AceDBObject:GetNamespace(name): 'name' - namespace does not exist.", 2)
|
||||
end
|
||||
if not self.children then self.children = {} end
|
||||
return self.children[name]
|
||||
end
|
||||
|
||||
--[[-------------------------------------------------------------------------
|
||||
AceDB Exposed Methods
|
||||
---------------------------------------------------------------------------]]
|
||||
|
||||
--- Creates a new database object that can be used to handle database settings and profiles.
|
||||
-- By default, an empty DB is created, using a character specific profile.
|
||||
--
|
||||
-- You can override the default profile used by passing any profile name as the third argument,
|
||||
-- or by passing //true// as the third argument to use a globally shared profile called "Default".
|
||||
--
|
||||
-- Note that there is no token replacement in the default profile name, passing a defaultProfile as "char"
|
||||
-- will use a profile named "char", and not a character-specific profile.
|
||||
-- @param tbl The name of variable, or table to use for the database
|
||||
-- @param defaults A table of database defaults
|
||||
-- @param defaultProfile The name of the default profile. If not set, a character specific profile will be used as the default.
|
||||
-- You can also pass //true// to use a shared global profile called "Default".
|
||||
-- @usage
|
||||
-- -- Create an empty DB using a character-specific default profile.
|
||||
-- self.db = LibStub("AceDB-3.0"):New("MyAddonDB")
|
||||
-- @usage
|
||||
-- -- Create a DB using defaults and using a shared default profile
|
||||
-- self.db = LibStub("AceDB-3.0"):New("MyAddonDB", defaults, true)
|
||||
function AceDB:New(tbl, defaults, defaultProfile)
|
||||
if type(tbl) == "string" then
|
||||
local name = tbl
|
||||
tbl = _G[name]
|
||||
if not tbl then
|
||||
tbl = {}
|
||||
_G[name] = tbl
|
||||
end
|
||||
end
|
||||
|
||||
if type(tbl) ~= "table" then
|
||||
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'tbl' - table expected.", 2)
|
||||
end
|
||||
|
||||
if defaults and type(defaults) ~= "table" then
|
||||
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaults' - table expected.", 2)
|
||||
end
|
||||
|
||||
if defaultProfile and type(defaultProfile) ~= "string" and defaultProfile ~= true then
|
||||
error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaultProfile' - string or true expected.", 2)
|
||||
end
|
||||
|
||||
return initdb(tbl, defaults, defaultProfile)
|
||||
end
|
||||
|
||||
-- upgrade existing databases
|
||||
for db in pairs(AceDB.db_registry) do
|
||||
if not db.parent then
|
||||
for name,func in pairs(DBObjectLib) do
|
||||
db[name] = func
|
||||
end
|
||||
else
|
||||
db.RegisterDefaults = DBObjectLib.RegisterDefaults
|
||||
db.ResetProfile = DBObjectLib.ResetProfile
|
||||
end
|
||||
end
|
||||
4
MogIt/Libs/AceDB-3.0/AceDB-3.0.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
..\FrameXML\UI.xsd">
|
||||
<Script file="AceDB-3.0.lua"/>
|
||||
</Ui>
|
||||
420
MogIt/Libs/AceDBOptions-3.0/AceDBOptions-3.0.lua
Normal file
@@ -0,0 +1,420 @@
|
||||
--- AceDBOptions-3.0 provides a universal AceConfig options screen for managing AceDB-3.0 profiles.
|
||||
-- @class file
|
||||
-- @name AceDBOptions-3.0
|
||||
-- @release $Id: AceDBOptions-3.0.lua 938 2010-06-13 07:21:38Z nevcairiel $
|
||||
local ACEDBO_MAJOR, ACEDBO_MINOR = "AceDBOptions-3.0", 12
|
||||
local AceDBOptions, oldminor = LibStub:NewLibrary(ACEDBO_MAJOR, ACEDBO_MINOR)
|
||||
|
||||
if not AceDBOptions then return end -- No upgrade needed
|
||||
|
||||
-- Lua APIs
|
||||
local pairs, next = pairs, next
|
||||
|
||||
-- WoW APIs
|
||||
local UnitClass = UnitClass
|
||||
|
||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||
-- List them here for Mikk's FindGlobals script
|
||||
-- GLOBALS: NORMAL_FONT_COLOR_CODE, FONT_COLOR_CODE_CLOSE
|
||||
|
||||
AceDBOptions.optionTables = AceDBOptions.optionTables or {}
|
||||
AceDBOptions.handlers = AceDBOptions.handlers or {}
|
||||
|
||||
--[[
|
||||
Localization of AceDBOptions-3.0
|
||||
]]
|
||||
|
||||
local L = {
|
||||
default = "Default",
|
||||
intro = "You can change the active database profile, so you can have different settings for every character.",
|
||||
reset_desc = "Reset the current profile back to its default values, in case your configuration is broken, or you simply want to start over.",
|
||||
reset = "Reset Profile",
|
||||
reset_sub = "Reset the current profile to the default",
|
||||
choose_desc = "You can either create a new profile by entering a name in the editbox, or choose one of the already existing profiles.",
|
||||
new = "New",
|
||||
new_sub = "Create a new empty profile.",
|
||||
choose = "Existing Profiles",
|
||||
choose_sub = "Select one of your currently available profiles.",
|
||||
copy_desc = "Copy the settings from one existing profile into the currently active profile.",
|
||||
copy = "Copy From",
|
||||
delete_desc = "Delete existing and unused profiles from the database to save space, and cleanup the SavedVariables file.",
|
||||
delete = "Delete a Profile",
|
||||
delete_sub = "Deletes a profile from the database.",
|
||||
delete_confirm = "Are you sure you want to delete the selected profile?",
|
||||
profiles = "Profiles",
|
||||
profiles_sub = "Manage Profiles",
|
||||
current = "Current Profile:",
|
||||
}
|
||||
|
||||
local LOCALE = GetLocale()
|
||||
if LOCALE == "deDE" then
|
||||
L["default"] = "Standard"
|
||||
L["intro"] = "Hier kannst du das aktive Datenbankprofile \195\164ndern, damit du verschiedene Einstellungen f\195\188r jeden Charakter erstellen kannst, wodurch eine sehr flexible Konfiguration m\195\182glich wird."
|
||||
L["reset_desc"] = "Setzt das momentane Profil auf Standardwerte zur\195\188ck, f\195\188r den Fall das mit der Konfiguration etwas schief lief oder weil du einfach neu starten willst."
|
||||
L["reset"] = "Profil zur\195\188cksetzen"
|
||||
L["reset_sub"] = "Das aktuelle Profil auf Standard zur\195\188cksetzen."
|
||||
L["choose_desc"] = "Du kannst ein neues Profil erstellen, indem du einen neuen Namen in der Eingabebox 'Neu' eingibst, oder w\195\164hle eines der vorhandenen Profile aus."
|
||||
L["new"] = "Neu"
|
||||
L["new_sub"] = "Ein neues Profil erstellen."
|
||||
L["choose"] = "Vorhandene Profile"
|
||||
L["choose_sub"] = "W\195\164hlt ein bereits vorhandenes Profil aus."
|
||||
L["copy_desc"] = "Kopiere die Einstellungen von einem vorhandenen Profil in das aktive Profil."
|
||||
L["copy"] = "Kopieren von..."
|
||||
L["delete_desc"] = "L\195\182sche vorhandene oder unbenutzte Profile aus der Datenbank um Platz zu sparen und um die SavedVariables Datei 'sauber' zu halten."
|
||||
L["delete"] = "Profil l\195\182schen"
|
||||
L["delete_sub"] = "L\195\182scht ein Profil aus der Datenbank."
|
||||
L["delete_confirm"] = "Willst du das ausgew\195\164hlte Profil wirklich l\195\182schen?"
|
||||
L["profiles"] = "Profile"
|
||||
L["profiles_sub"] = "Profile verwalten"
|
||||
--L["current"] = "Current Profile:"
|
||||
elseif LOCALE == "frFR" then
|
||||
L["default"] = "D\195\169faut"
|
||||
L["intro"] = "Vous pouvez changer le profil actuel afin d'avoir des param\195\168tres diff\195\169rents pour chaque personnage, permettant ainsi d'avoir une configuration tr\195\168s flexible."
|
||||
L["reset_desc"] = "R\195\169initialise le profil actuel au cas o\195\185 votre configuration est corrompue ou si vous voulez tout simplement faire table rase."
|
||||
L["reset"] = "R\195\169initialiser le profil"
|
||||
L["reset_sub"] = "R\195\169initialise le profil actuel avec les param\195\168tres par d\195\169faut."
|
||||
L["choose_desc"] = "Vous pouvez cr\195\169er un nouveau profil en entrant un nouveau nom dans la bo\195\174te de saisie, ou en choississant un des profils d\195\169j\195\160 existants."
|
||||
L["new"] = "Nouveau"
|
||||
L["new_sub"] = "Cr\195\169\195\169e un nouveau profil vierge."
|
||||
L["choose"] = "Profils existants"
|
||||
L["choose_sub"] = "Permet de choisir un des profils d\195\169j\195\160 disponibles."
|
||||
L["copy_desc"] = "Copie les param\195\168tres d'un profil d\195\169j\195\160 existant dans le profil actuellement actif."
|
||||
L["copy"] = "Copier \195\160 partir de"
|
||||
L["delete_desc"] = "Supprime les profils existants inutilis\195\169s de la base de donn\195\169es afin de gagner de la place et de nettoyer le fichier SavedVariables."
|
||||
L["delete"] = "Supprimer un profil"
|
||||
L["delete_sub"] = "Supprime un profil de la base de donn\195\169es."
|
||||
L["delete_confirm"] = "Etes-vous s\195\187r de vouloir supprimer le profil s\195\169lectionn\195\169 ?"
|
||||
L["profiles"] = "Profils"
|
||||
L["profiles_sub"] = "Gestion des profils"
|
||||
--L["current"] = "Current Profile:"
|
||||
elseif LOCALE == "koKR" then
|
||||
L["default"] = "기본값"
|
||||
L["intro"] = "모든 캐릭터의 다양한 설정과 사용중인 데이터베이스 프로필, 어느것이던지 매우 다루기 쉽게 바꿀수 있습니다."
|
||||
L["reset_desc"] = "단순히 다시 새롭게 구성을 원하는 경우, 현재 프로필을 기본값으로 초기화 합니다."
|
||||
L["reset"] = "프로필 초기화"
|
||||
L["reset_sub"] = "현재의 프로필을 기본값으로 초기화 합니다"
|
||||
L["choose_desc"] = "새로운 이름을 입력하거나, 이미 있는 프로필중 하나를 선택하여 새로운 프로필을 만들 수 있습니다."
|
||||
L["new"] = "새로운 프로필"
|
||||
L["new_sub"] = "새로운 프로필을 만듭니다."
|
||||
L["choose"] = "프로필 선택"
|
||||
L["choose_sub"] = "당신이 현재 이용할수 있는 프로필을 선택합니다."
|
||||
L["copy_desc"] = "현재 사용중인 프로필에, 선택한 프로필의 설정을 복사합니다."
|
||||
L["copy"] = "복사"
|
||||
L["delete_desc"] = "데이터베이스에 사용중이거나 저장된 프로파일 삭제로 SavedVariables 파일의 정리와 공간 절약이 됩니다."
|
||||
L["delete"] = "프로필 삭제"
|
||||
L["delete_sub"] = "데이터베이스의 프로필을 삭제합니다."
|
||||
L["delete_confirm"] = "정말로 선택한 프로필의 삭제를 원하십니까?"
|
||||
L["profiles"] = "프로필"
|
||||
L["profiles_sub"] = "프로필 설정"
|
||||
--L["current"] = "Current Profile:"
|
||||
elseif LOCALE == "esES" or LOCALE == "esMX" then
|
||||
L["default"] = "Por defecto"
|
||||
L["intro"] = "Puedes cambiar el perfil activo de tal manera que cada personaje tenga diferentes configuraciones."
|
||||
L["reset_desc"] = "Reinicia el perfil actual a los valores por defectos, en caso de que se haya estropeado la configuración o quieras volver a empezar de nuevo."
|
||||
L["reset"] = "Reiniciar Perfil"
|
||||
L["reset_sub"] = "Reinicar el perfil actual al de por defecto"
|
||||
L["choose_desc"] = "Puedes crear un nuevo perfil introduciendo un nombre en el recuadro o puedes seleccionar un perfil de los ya existentes."
|
||||
L["new"] = "Nuevo"
|
||||
L["new_sub"] = "Crear un nuevo perfil vacio."
|
||||
L["choose"] = "Perfiles existentes"
|
||||
L["choose_sub"] = "Selecciona uno de los perfiles disponibles."
|
||||
L["copy_desc"] = "Copia los ajustes de un perfil existente al perfil actual."
|
||||
L["copy"] = "Copiar de"
|
||||
L["delete_desc"] = "Borra los perfiles existentes y sin uso de la base de datos para ganar espacio y limpiar el archivo SavedVariables."
|
||||
L["delete"] = "Borrar un Perfil"
|
||||
L["delete_sub"] = "Borra un perfil de la base de datos."
|
||||
L["delete_confirm"] = "¿Estas seguro que quieres borrar el perfil seleccionado?"
|
||||
L["profiles"] = "Perfiles"
|
||||
L["profiles_sub"] = "Manejar Perfiles"
|
||||
--L["current"] = "Current Profile:"
|
||||
elseif LOCALE == "zhTW" then
|
||||
L["default"] = "預設"
|
||||
L["intro"] = "你可以選擇一個活動的資料設定檔,這樣你的每個角色就可以擁有不同的設定值,可以給你的插件設定帶來極大的靈活性。"
|
||||
L["reset_desc"] = "將當前的設定檔恢復到它的預設值,用於你的設定檔損壞,或者你只是想重來的情況。"
|
||||
L["reset"] = "重置設定檔"
|
||||
L["reset_sub"] = "將當前的設定檔恢復為預設值"
|
||||
L["choose_desc"] = "你可以通過在文本框內輸入一個名字創立一個新的設定檔,也可以選擇一個已經存在的設定檔。"
|
||||
L["new"] = "新建"
|
||||
L["new_sub"] = "新建一個空的設定檔。"
|
||||
L["choose"] = "現有的設定檔"
|
||||
L["choose_sub"] = "從當前可用的設定檔裏面選擇一個。"
|
||||
L["copy_desc"] = "從當前某個已保存的設定檔複製到當前正使用的設定檔。"
|
||||
L["copy"] = "複製自"
|
||||
L["delete_desc"] = "從資料庫裏刪除不再使用的設定檔,以節省空間,並且清理SavedVariables檔。"
|
||||
L["delete"] = "刪除一個設定檔"
|
||||
L["delete_sub"] = "從資料庫裏刪除一個設定檔。"
|
||||
L["delete_confirm"] = "你確定要刪除所選擇的設定檔嗎?"
|
||||
L["profiles"] = "設定檔"
|
||||
L["profiles_sub"] = "管理設定檔"
|
||||
--L["current"] = "Current Profile:"
|
||||
elseif LOCALE == "zhCN" then
|
||||
L["default"] = "默认"
|
||||
L["intro"] = "你可以选择一个活动的数据配置文件,这样你的每个角色就可以拥有不同的设置值,可以给你的插件配置带来极大的灵活性。"
|
||||
L["reset_desc"] = "将当前的配置文件恢复到它的默认值,用于你的配置文件损坏,或者你只是想重来的情况。"
|
||||
L["reset"] = "重置配置文件"
|
||||
L["reset_sub"] = "将当前的配置文件恢复为默认值"
|
||||
L["choose_desc"] = "你可以通过在文本框内输入一个名字创立一个新的配置文件,也可以选择一个已经存在的配置文件。"
|
||||
L["new"] = "新建"
|
||||
L["new_sub"] = "新建一个空的配置文件。"
|
||||
L["choose"] = "现有的配置文件"
|
||||
L["choose_sub"] = "从当前可用的配置文件里面选择一个。"
|
||||
L["copy_desc"] = "从当前某个已保存的配置文件复制到当前正使用的配置文件。"
|
||||
L["copy"] = "复制自"
|
||||
L["delete_desc"] = "从数据库里删除不再使用的配置文件,以节省空间,并且清理SavedVariables文件。"
|
||||
L["delete"] = "删除一个配置文件"
|
||||
L["delete_sub"] = "从数据库里删除一个配置文件。"
|
||||
L["delete_confirm"] = "你确定要删除所选择的配置文件么?"
|
||||
L["profiles"] = "配置文件"
|
||||
L["profiles_sub"] = "管理配置文件"
|
||||
--L["current"] = "Current Profile:"
|
||||
elseif LOCALE == "ruRU" then
|
||||
L["default"] = "По умолчанию"
|
||||
L["intro"] = "Изменяя активный профиль, вы можете задать различные настройки модификаций для каждого персонажа."
|
||||
L["reset_desc"] = "Если ваша конфигурации испорчена или если вы хотите настроить всё заново - сбросьте текущий профиль на стандартные значения."
|
||||
L["reset"] = "Сброс профиля"
|
||||
L["reset_sub"] = "Сброс текущего профиля на стандартный"
|
||||
L["choose_desc"] = "Вы можете создать новый профиль, введя название в поле ввода, или выбрать один из уже существующих профилей."
|
||||
L["new"] = "Новый"
|
||||
L["new_sub"] = "Создать новый чистый профиль"
|
||||
L["choose"] = "Существующие профили"
|
||||
L["choose_sub"] = "Выбор одиного из уже доступных профилей"
|
||||
L["copy_desc"] = "Скопировать настройки из выбранного профиля в активный."
|
||||
L["copy"] = "Скопировать из"
|
||||
L["delete_desc"] = "Удалить существующий и неиспользуемый профиль из БД для сохранения места, и очистить SavedVariables файл."
|
||||
L["delete"] = "Удалить профиль"
|
||||
L["delete_sub"] = "Удаление профиля из БД"
|
||||
L["delete_confirm"] = "Вы уверены, что вы хотите удалить выбранный профиль?"
|
||||
L["profiles"] = "Профили"
|
||||
L["profiles_sub"] = "Управление профилями"
|
||||
--L["current"] = "Current Profile:"
|
||||
end
|
||||
|
||||
local defaultProfiles
|
||||
local tmpprofiles = {}
|
||||
|
||||
-- Get a list of available profiles for the specified database.
|
||||
-- You can specify which profiles to include/exclude in the list using the two boolean parameters listed below.
|
||||
-- @param db The db object to retrieve the profiles from
|
||||
-- @param common If true, getProfileList will add the default profiles to the return list, even if they have not been created yet
|
||||
-- @param nocurrent If true, then getProfileList will not display the current profile in the list
|
||||
-- @return Hashtable of all profiles with the internal name as keys and the display name as value.
|
||||
local function getProfileList(db, common, nocurrent)
|
||||
local profiles = {}
|
||||
|
||||
-- copy existing profiles into the table
|
||||
local currentProfile = db:GetCurrentProfile()
|
||||
for i,v in pairs(db:GetProfiles(tmpprofiles)) do
|
||||
if not (nocurrent and v == currentProfile) then
|
||||
profiles[v] = v
|
||||
end
|
||||
end
|
||||
|
||||
-- add our default profiles to choose from ( or rename existing profiles)
|
||||
for k,v in pairs(defaultProfiles) do
|
||||
if (common or profiles[k]) and not (nocurrent and k == currentProfile) then
|
||||
profiles[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
return profiles
|
||||
end
|
||||
|
||||
--[[
|
||||
OptionsHandlerPrototype
|
||||
prototype class for handling the options in a sane way
|
||||
]]
|
||||
local OptionsHandlerPrototype = {}
|
||||
|
||||
--[[ Reset the profile ]]
|
||||
function OptionsHandlerPrototype:Reset()
|
||||
self.db:ResetProfile()
|
||||
end
|
||||
|
||||
--[[ Set the profile to value ]]
|
||||
function OptionsHandlerPrototype:SetProfile(info, value)
|
||||
self.db:SetProfile(value)
|
||||
end
|
||||
|
||||
--[[ returns the currently active profile ]]
|
||||
function OptionsHandlerPrototype:GetCurrentProfile()
|
||||
return self.db:GetCurrentProfile()
|
||||
end
|
||||
|
||||
--[[
|
||||
List all active profiles
|
||||
you can control the output with the .arg variable
|
||||
currently four modes are supported
|
||||
|
||||
(empty) - return all available profiles
|
||||
"nocurrent" - returns all available profiles except the currently active profile
|
||||
"common" - returns all avaialble profiles + some commonly used profiles ("char - realm", "realm", "class", "Default")
|
||||
"both" - common except the active profile
|
||||
]]
|
||||
function OptionsHandlerPrototype:ListProfiles(info)
|
||||
local arg = info.arg
|
||||
local profiles
|
||||
if arg == "common" and not self.noDefaultProfiles then
|
||||
profiles = getProfileList(self.db, true, nil)
|
||||
elseif arg == "nocurrent" then
|
||||
profiles = getProfileList(self.db, nil, true)
|
||||
elseif arg == "both" then -- currently not used
|
||||
profiles = getProfileList(self.db, (not self.noDefaultProfiles) and true, true)
|
||||
else
|
||||
profiles = getProfileList(self.db)
|
||||
end
|
||||
|
||||
return profiles
|
||||
end
|
||||
|
||||
function OptionsHandlerPrototype:HasNoProfiles(info)
|
||||
local profiles = self:ListProfiles(info)
|
||||
return ((not next(profiles)) and true or false)
|
||||
end
|
||||
|
||||
--[[ Copy a profile ]]
|
||||
function OptionsHandlerPrototype:CopyProfile(info, value)
|
||||
self.db:CopyProfile(value)
|
||||
end
|
||||
|
||||
--[[ Delete a profile from the db ]]
|
||||
function OptionsHandlerPrototype:DeleteProfile(info, value)
|
||||
self.db:DeleteProfile(value)
|
||||
end
|
||||
|
||||
--[[ fill defaultProfiles with some generic values ]]
|
||||
local function generateDefaultProfiles(db)
|
||||
defaultProfiles = {
|
||||
["Default"] = L["default"],
|
||||
[db.keys.char] = db.keys.char,
|
||||
[db.keys.realm] = db.keys.realm,
|
||||
[db.keys.class] = UnitClass("player")
|
||||
}
|
||||
end
|
||||
|
||||
--[[ create and return a handler object for the db, or upgrade it if it already existed ]]
|
||||
local function getOptionsHandler(db, noDefaultProfiles)
|
||||
if not defaultProfiles then
|
||||
generateDefaultProfiles(db)
|
||||
end
|
||||
|
||||
local handler = AceDBOptions.handlers[db] or { db = db, noDefaultProfiles = noDefaultProfiles }
|
||||
|
||||
for k,v in pairs(OptionsHandlerPrototype) do
|
||||
handler[k] = v
|
||||
end
|
||||
|
||||
AceDBOptions.handlers[db] = handler
|
||||
return handler
|
||||
end
|
||||
|
||||
--[[
|
||||
the real options table
|
||||
]]
|
||||
local optionsTable = {
|
||||
desc = {
|
||||
order = 1,
|
||||
type = "description",
|
||||
name = L["intro"] .. "\n",
|
||||
},
|
||||
descreset = {
|
||||
order = 9,
|
||||
type = "description",
|
||||
name = L["reset_desc"],
|
||||
},
|
||||
reset = {
|
||||
order = 10,
|
||||
type = "execute",
|
||||
name = L["reset"],
|
||||
desc = L["reset_sub"],
|
||||
func = "Reset",
|
||||
},
|
||||
current = {
|
||||
order = 11,
|
||||
type = "description",
|
||||
name = function(info) return L["current"] .. " " .. NORMAL_FONT_COLOR_CODE .. info.handler:GetCurrentProfile() .. FONT_COLOR_CODE_CLOSE end,
|
||||
width = "default",
|
||||
},
|
||||
choosedesc = {
|
||||
order = 20,
|
||||
type = "description",
|
||||
name = "\n" .. L["choose_desc"],
|
||||
},
|
||||
new = {
|
||||
name = L["new"],
|
||||
desc = L["new_sub"],
|
||||
type = "input",
|
||||
order = 30,
|
||||
get = false,
|
||||
set = "SetProfile",
|
||||
},
|
||||
choose = {
|
||||
name = L["choose"],
|
||||
desc = L["choose_sub"],
|
||||
type = "select",
|
||||
order = 40,
|
||||
get = "GetCurrentProfile",
|
||||
set = "SetProfile",
|
||||
values = "ListProfiles",
|
||||
arg = "common",
|
||||
},
|
||||
copydesc = {
|
||||
order = 50,
|
||||
type = "description",
|
||||
name = "\n" .. L["copy_desc"],
|
||||
},
|
||||
copyfrom = {
|
||||
order = 60,
|
||||
type = "select",
|
||||
name = L["copy"],
|
||||
desc = L["copy_desc"],
|
||||
get = false,
|
||||
set = "CopyProfile",
|
||||
values = "ListProfiles",
|
||||
disabled = "HasNoProfiles",
|
||||
arg = "nocurrent",
|
||||
},
|
||||
deldesc = {
|
||||
order = 70,
|
||||
type = "description",
|
||||
name = "\n" .. L["delete_desc"],
|
||||
},
|
||||
delete = {
|
||||
order = 80,
|
||||
type = "select",
|
||||
name = L["delete"],
|
||||
desc = L["delete_sub"],
|
||||
get = false,
|
||||
set = "DeleteProfile",
|
||||
values = "ListProfiles",
|
||||
disabled = "HasNoProfiles",
|
||||
arg = "nocurrent",
|
||||
confirm = true,
|
||||
confirmText = L["delete_confirm"],
|
||||
},
|
||||
}
|
||||
|
||||
--- Get/Create a option table that you can use in your addon to control the profiles of AceDB-3.0.
|
||||
-- @param db The database object to create the options table for.
|
||||
-- @return The options table to be used in AceConfig-3.0
|
||||
-- @usage
|
||||
-- -- Assuming `options` is your top-level options table and `self.db` is your database:
|
||||
-- options.args.profiles = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db)
|
||||
function AceDBOptions:GetOptionsTable(db, noDefaultProfiles)
|
||||
local tbl = AceDBOptions.optionTables[db] or {
|
||||
type = "group",
|
||||
name = L["profiles"],
|
||||
desc = L["profiles_sub"],
|
||||
}
|
||||
|
||||
tbl.handler = getOptionsHandler(db, noDefaultProfiles)
|
||||
tbl.args = optionsTable
|
||||
|
||||
AceDBOptions.optionTables[db] = tbl
|
||||
return tbl
|
||||
end
|
||||
|
||||
-- upgrade existing tables
|
||||
for db,tbl in pairs(AceDBOptions.optionTables) do
|
||||
tbl.handler = getOptionsHandler(db)
|
||||
tbl.args = optionsTable
|
||||
end
|
||||
4
MogIt/Libs/AceDBOptions-3.0/AceDBOptions-3.0.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
..\FrameXML\UI.xsd">
|
||||
<Script file="AceDBOptions-3.0.lua"/>
|
||||
</Ui>
|
||||
805
MogIt/Libs/AceGUI-3.0/AceGUI-3.0.lua
Normal file
@@ -0,0 +1,805 @@
|
||||
--- **AceGUI-3.0** provides access to numerous widgets which can be used to create GUIs.
|
||||
-- AceGUI is used by AceConfigDialog to create the option GUIs, but you can use it by itself
|
||||
-- to create any custom GUI. There are more extensive examples in the test suite in the Ace3
|
||||
-- stand-alone distribution.
|
||||
--
|
||||
-- **Note**: When using AceGUI-3.0 directly, please do not modify the frames of the widgets directly,
|
||||
-- as any "unknown" change to the widgets will cause addons that get your widget out of the widget pool
|
||||
-- to misbehave. If you think some part of a widget should be modifiable, please open a ticket, and we"ll
|
||||
-- implement a proper API to modify it.
|
||||
-- @usage
|
||||
-- local AceGUI = LibStub("AceGUI-3.0")
|
||||
-- -- Create a container frame
|
||||
-- local f = AceGUI:Create("Frame")
|
||||
-- f:SetCallback("OnClose",function(widget) AceGUI:Release(widget) end)
|
||||
-- f:SetTitle("AceGUI-3.0 Example")
|
||||
-- f:SetStatusText("Status Bar")
|
||||
-- f:SetLayout("Flow")
|
||||
-- -- Create a button
|
||||
-- local btn = AceGUI:Create("Button")
|
||||
-- btn:SetWidth(170)
|
||||
-- btn:SetText("Button !")
|
||||
-- btn:SetCallback("OnClick", function() print("Click!") end)
|
||||
-- -- Add the button to the container
|
||||
-- f:AddChild(btn)
|
||||
-- @class file
|
||||
-- @name AceGUI-3.0
|
||||
-- @release $Id: AceGUI-3.0.lua 924 2010-05-13 15:12:20Z nevcairiel $
|
||||
local ACEGUI_MAJOR, ACEGUI_MINOR = "AceGUI-3.0", 33
|
||||
local AceGUI, oldminor = LibStub:NewLibrary(ACEGUI_MAJOR, ACEGUI_MINOR)
|
||||
|
||||
if not AceGUI then return end -- No upgrade needed
|
||||
|
||||
-- Lua APIs
|
||||
local tconcat, tremove, tinsert = table.concat, table.remove, table.insert
|
||||
local select, pairs, next, type = select, pairs, next, type
|
||||
local error, assert, loadstring = error, assert, loadstring
|
||||
local setmetatable, rawget, rawset = setmetatable, rawget, rawset
|
||||
local math_max = math.max
|
||||
|
||||
-- WoW APIs
|
||||
local UIParent = UIParent
|
||||
|
||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||
-- List them here for Mikk's FindGlobals script
|
||||
-- GLOBALS: geterrorhandler, LibStub
|
||||
|
||||
--local con = LibStub("AceConsole-3.0",true)
|
||||
|
||||
AceGUI.WidgetRegistry = AceGUI.WidgetRegistry or {}
|
||||
AceGUI.LayoutRegistry = AceGUI.LayoutRegistry or {}
|
||||
AceGUI.WidgetBase = AceGUI.WidgetBase or {}
|
||||
AceGUI.WidgetContainerBase = AceGUI.WidgetContainerBase or {}
|
||||
AceGUI.WidgetVersions = AceGUI.WidgetVersions or {}
|
||||
|
||||
-- local upvalues
|
||||
local WidgetRegistry = AceGUI.WidgetRegistry
|
||||
local LayoutRegistry = AceGUI.LayoutRegistry
|
||||
local WidgetVersions = AceGUI.WidgetVersions
|
||||
|
||||
--[[
|
||||
xpcall safecall implementation
|
||||
]]
|
||||
local xpcall = xpcall
|
||||
|
||||
local function errorhandler(err)
|
||||
return geterrorhandler()(err)
|
||||
end
|
||||
|
||||
local function CreateDispatcher(argCount)
|
||||
local code = [[
|
||||
local xpcall, eh = ...
|
||||
local method, ARGS
|
||||
local function call() return method(ARGS) end
|
||||
|
||||
local function dispatch(func, ...)
|
||||
method = func
|
||||
if not method then return end
|
||||
ARGS = ...
|
||||
return xpcall(call, eh)
|
||||
end
|
||||
|
||||
return dispatch
|
||||
]]
|
||||
|
||||
local ARGS = {}
|
||||
for i = 1, argCount do ARGS[i] = "arg"..i end
|
||||
code = code:gsub("ARGS", tconcat(ARGS, ", "))
|
||||
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
|
||||
end
|
||||
|
||||
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
|
||||
local dispatcher = CreateDispatcher(argCount)
|
||||
rawset(self, argCount, dispatcher)
|
||||
return dispatcher
|
||||
end})
|
||||
Dispatchers[0] = function(func)
|
||||
return xpcall(func, errorhandler)
|
||||
end
|
||||
|
||||
local function safecall(func, ...)
|
||||
return Dispatchers[select("#", ...)](func, ...)
|
||||
end
|
||||
|
||||
-- Recycling functions
|
||||
local newWidget, delWidget
|
||||
do
|
||||
-- Version Upgrade in Minor 29
|
||||
-- Internal Storage of the objects changed, from an array table
|
||||
-- to a hash table, and additionally we introduced versioning on
|
||||
-- the widgets which would discard all widgets from a pre-29 version
|
||||
-- anyway, so we just clear the storage now, and don't try to
|
||||
-- convert the storage tables to the new format.
|
||||
-- This should generally not cause *many* widgets to end up in trash,
|
||||
-- since once dialogs are opened, all addons should be loaded already
|
||||
-- and AceGUI should be on the latest version available on the users
|
||||
-- setup.
|
||||
-- -- nevcairiel - Nov 2nd, 2009
|
||||
if oldminor and oldminor < 29 and AceGUI.objPools then
|
||||
AceGUI.objPools = nil
|
||||
end
|
||||
|
||||
AceGUI.objPools = AceGUI.objPools or {}
|
||||
local objPools = AceGUI.objPools
|
||||
--Returns a new instance, if none are available either returns a new table or calls the given contructor
|
||||
function newWidget(type)
|
||||
if not WidgetRegistry[type] then
|
||||
error("Attempt to instantiate unknown widget type", 2)
|
||||
end
|
||||
|
||||
if not objPools[type] then
|
||||
objPools[type] = {}
|
||||
end
|
||||
|
||||
local newObj = next(objPools[type])
|
||||
if not newObj then
|
||||
newObj = WidgetRegistry[type]()
|
||||
newObj.AceGUIWidgetVersion = WidgetVersions[type]
|
||||
else
|
||||
objPools[type][newObj] = nil
|
||||
-- if the widget is older then the latest, don't even try to reuse it
|
||||
-- just forget about it, and grab a new one.
|
||||
if not newObj.AceGUIWidgetVersion or newObj.AceGUIWidgetVersion < WidgetVersions[type] then
|
||||
return newWidget(type)
|
||||
end
|
||||
end
|
||||
return newObj
|
||||
end
|
||||
-- Releases an instance to the Pool
|
||||
function delWidget(obj,type)
|
||||
if not objPools[type] then
|
||||
objPools[type] = {}
|
||||
end
|
||||
if objPools[type][obj] then
|
||||
error("Attempt to Release Widget that is already released", 2)
|
||||
end
|
||||
objPools[type][obj] = true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-------------------
|
||||
-- API Functions --
|
||||
-------------------
|
||||
|
||||
-- Gets a widget Object
|
||||
|
||||
--- Create a new Widget of the given type.
|
||||
-- This function will instantiate a new widget (or use one from the widget pool), and call the
|
||||
-- OnAcquire function on it, before returning.
|
||||
-- @param type The type of the widget.
|
||||
-- @return The newly created widget.
|
||||
function AceGUI:Create(type)
|
||||
if WidgetRegistry[type] then
|
||||
local widget = newWidget(type)
|
||||
|
||||
if rawget(widget, "Acquire") then
|
||||
widget.OnAcquire = widget.Acquire
|
||||
widget.Acquire = nil
|
||||
elseif rawget(widget, "Aquire") then
|
||||
widget.OnAcquire = widget.Aquire
|
||||
widget.Aquire = nil
|
||||
end
|
||||
|
||||
if rawget(widget, "Release") then
|
||||
widget.OnRelease = rawget(widget, "Release")
|
||||
widget.Release = nil
|
||||
end
|
||||
|
||||
if widget.OnAcquire then
|
||||
widget:OnAcquire()
|
||||
else
|
||||
error(("Widget type %s doesn't supply an OnAcquire Function"):format(type))
|
||||
end
|
||||
-- Set the default Layout ("List")
|
||||
safecall(widget.SetLayout, widget, "List")
|
||||
safecall(widget.ResumeLayout, widget)
|
||||
return widget
|
||||
end
|
||||
end
|
||||
|
||||
--- Releases a widget Object.
|
||||
-- This function calls OnRelease on the widget and places it back in the widget pool.
|
||||
-- Any data on the widget is being erased, and the widget will be hidden.\\
|
||||
-- If this widget is a Container-Widget, all of its Child-Widgets will be releases as well.
|
||||
-- @param widget The widget to release
|
||||
function AceGUI:Release(widget)
|
||||
safecall(widget.PauseLayout, widget)
|
||||
widget:Fire("OnRelease")
|
||||
safecall(widget.ReleaseChildren, widget)
|
||||
|
||||
if widget.OnRelease then
|
||||
widget:OnRelease()
|
||||
-- else
|
||||
-- error(("Widget type %s doesn't supply an OnRelease Function"):format(widget.type))
|
||||
end
|
||||
for k in pairs(widget.userdata) do
|
||||
widget.userdata[k] = nil
|
||||
end
|
||||
for k in pairs(widget.events) do
|
||||
widget.events[k] = nil
|
||||
end
|
||||
widget.width = nil
|
||||
widget.relWidth = nil
|
||||
widget.height = nil
|
||||
widget.relHeight = nil
|
||||
widget.noAutoHeight = nil
|
||||
widget.frame:ClearAllPoints()
|
||||
widget.frame:Hide()
|
||||
widget.frame:SetParent(UIParent)
|
||||
widget.frame.width = nil
|
||||
widget.frame.height = nil
|
||||
if widget.content then
|
||||
widget.content.width = nil
|
||||
widget.content.height = nil
|
||||
end
|
||||
delWidget(widget, widget.type)
|
||||
end
|
||||
|
||||
-----------
|
||||
-- Focus --
|
||||
-----------
|
||||
|
||||
|
||||
--- Called when a widget has taken focus.
|
||||
-- e.g. Dropdowns opening, Editboxes gaining kb focus
|
||||
-- @param widget The widget that should be focused
|
||||
function AceGUI:SetFocus(widget)
|
||||
if self.FocusedWidget and self.FocusedWidget ~= widget then
|
||||
safecall(self.FocusedWidget.ClearFocus, self.FocusedWidget)
|
||||
end
|
||||
self.FocusedWidget = widget
|
||||
end
|
||||
|
||||
|
||||
--- Called when something has happened that could cause widgets with focus to drop it
|
||||
-- e.g. titlebar of a frame being clicked
|
||||
function AceGUI:ClearFocus()
|
||||
if self.FocusedWidget then
|
||||
safecall(self.FocusedWidget.ClearFocus, self.FocusedWidget)
|
||||
self.FocusedWidget = nil
|
||||
end
|
||||
end
|
||||
|
||||
-------------
|
||||
-- Widgets --
|
||||
-------------
|
||||
--[[
|
||||
Widgets must provide the following functions
|
||||
OnAcquire() - Called when the object is acquired, should set everything to a default hidden state
|
||||
|
||||
And the following members
|
||||
frame - the frame or derivitive object that will be treated as the widget for size and anchoring purposes
|
||||
type - the type of the object, same as the name given to :RegisterWidget()
|
||||
|
||||
Widgets contain a table called userdata, this is a safe place to store data associated with the wigdet
|
||||
It will be cleared automatically when a widget is released
|
||||
Placing values directly into a widget object should be avoided
|
||||
|
||||
If the Widget can act as a container for other Widgets the following
|
||||
content - frame or derivitive that children will be anchored to
|
||||
|
||||
The Widget can supply the following Optional Members
|
||||
:OnRelease() - Called when the object is Released, should remove any additional anchors and clear any data
|
||||
:OnWidthSet(width) - Called when the width of the widget is changed
|
||||
:OnHeightSet(height) - Called when the height of the widget is changed
|
||||
Widgets should not use the OnSizeChanged events of thier frame or content members, use these methods instead
|
||||
AceGUI already sets a handler to the event
|
||||
:LayoutFinished(width, height) - called after a layout has finished, the width and height will be the width and height of the
|
||||
area used for controls. These can be nil if the layout used the existing size to layout the controls.
|
||||
|
||||
]]
|
||||
|
||||
--------------------------
|
||||
-- Widget Base Template --
|
||||
--------------------------
|
||||
do
|
||||
local WidgetBase = AceGUI.WidgetBase
|
||||
|
||||
WidgetBase.SetParent = function(self, parent)
|
||||
local frame = self.frame
|
||||
frame:SetParent(nil)
|
||||
frame:SetParent(parent.content)
|
||||
self.parent = parent
|
||||
end
|
||||
|
||||
WidgetBase.SetCallback = function(self, name, func)
|
||||
if type(func) == "function" then
|
||||
self.events[name] = func
|
||||
end
|
||||
end
|
||||
|
||||
WidgetBase.Fire = function(self, name, ...)
|
||||
if self.events[name] then
|
||||
local success, ret = safecall(self.events[name], self, name, ...)
|
||||
if success then
|
||||
return ret
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
WidgetBase.SetWidth = function(self, width)
|
||||
self.frame:SetWidth(width)
|
||||
self.frame.width = width
|
||||
if self.OnWidthSet then
|
||||
self:OnWidthSet(width)
|
||||
end
|
||||
end
|
||||
|
||||
WidgetBase.SetRelativeWidth = function(self, width)
|
||||
if width <= 0 or width > 1 then
|
||||
error(":SetRelativeWidth(width): Invalid relative width.", 2)
|
||||
end
|
||||
self.relWidth = width
|
||||
self.width = "relative"
|
||||
end
|
||||
|
||||
WidgetBase.SetHeight = function(self, height)
|
||||
self.frame:SetHeight(height)
|
||||
self.frame.height = height
|
||||
if self.OnHeightSet then
|
||||
self:OnHeightSet(height)
|
||||
end
|
||||
end
|
||||
|
||||
--[[ WidgetBase.SetRelativeHeight = function(self, height)
|
||||
if height <= 0 or height > 1 then
|
||||
error(":SetRelativeHeight(height): Invalid relative height.", 2)
|
||||
end
|
||||
self.relHeight = height
|
||||
self.height = "relative"
|
||||
end ]]
|
||||
|
||||
WidgetBase.IsVisible = function(self)
|
||||
return self.frame:IsVisible()
|
||||
end
|
||||
|
||||
WidgetBase.IsShown= function(self)
|
||||
return self.frame:IsShown()
|
||||
end
|
||||
|
||||
WidgetBase.Release = function(self)
|
||||
AceGUI:Release(self)
|
||||
end
|
||||
|
||||
WidgetBase.SetPoint = function(self, ...)
|
||||
return self.frame:SetPoint(...)
|
||||
end
|
||||
|
||||
WidgetBase.ClearAllPoints = function(self)
|
||||
return self.frame:ClearAllPoints()
|
||||
end
|
||||
|
||||
WidgetBase.GetNumPoints = function(self)
|
||||
return self.frame:GetNumPoints()
|
||||
end
|
||||
|
||||
WidgetBase.GetPoint = function(self, ...)
|
||||
return self.frame:GetPoint(...)
|
||||
end
|
||||
|
||||
WidgetBase.GetUserDataTable = function(self)
|
||||
return self.userdata
|
||||
end
|
||||
|
||||
WidgetBase.SetUserData = function(self, key, value)
|
||||
self.userdata[key] = value
|
||||
end
|
||||
|
||||
WidgetBase.GetUserData = function(self, key)
|
||||
return self.userdata[key]
|
||||
end
|
||||
|
||||
WidgetBase.IsFullHeight = function(self)
|
||||
return self.height == "fill"
|
||||
end
|
||||
|
||||
WidgetBase.SetFullHeight = function(self, isFull)
|
||||
if isFull then
|
||||
self.height = "fill"
|
||||
else
|
||||
self.height = nil
|
||||
end
|
||||
end
|
||||
|
||||
WidgetBase.IsFullWidth = function(self)
|
||||
return self.width == "fill"
|
||||
end
|
||||
|
||||
WidgetBase.SetFullWidth = function(self, isFull)
|
||||
if isFull then
|
||||
self.width = "fill"
|
||||
else
|
||||
self.width = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- local function LayoutOnUpdate(this)
|
||||
-- this:SetScript("OnUpdate",nil)
|
||||
-- this.obj:PerformLayout()
|
||||
-- end
|
||||
|
||||
local WidgetContainerBase = AceGUI.WidgetContainerBase
|
||||
|
||||
WidgetContainerBase.PauseLayout = function(self)
|
||||
self.LayoutPaused = true
|
||||
end
|
||||
|
||||
WidgetContainerBase.ResumeLayout = function(self)
|
||||
self.LayoutPaused = nil
|
||||
end
|
||||
|
||||
WidgetContainerBase.PerformLayout = function(self)
|
||||
if self.LayoutPaused then
|
||||
return
|
||||
end
|
||||
safecall(self.LayoutFunc, self.content, self.children)
|
||||
end
|
||||
|
||||
--call this function to layout, makes sure layed out objects get a frame to get sizes etc
|
||||
WidgetContainerBase.DoLayout = function(self)
|
||||
self:PerformLayout()
|
||||
-- if not self.parent then
|
||||
-- self.frame:SetScript("OnUpdate", LayoutOnUpdate)
|
||||
-- end
|
||||
end
|
||||
|
||||
WidgetContainerBase.AddChild = function(self, child, beforeWidget)
|
||||
if beforeWidget then
|
||||
local siblingIndex = 1
|
||||
for _, widget in pairs(self.children) do
|
||||
if widget == beforeWidget then
|
||||
break
|
||||
end
|
||||
siblingIndex = siblingIndex + 1
|
||||
end
|
||||
tinsert(self.children, siblingIndex, child)
|
||||
else
|
||||
tinsert(self.children, child)
|
||||
end
|
||||
child:SetParent(self)
|
||||
child.frame:Show()
|
||||
self:DoLayout()
|
||||
end
|
||||
|
||||
WidgetContainerBase.AddChildren = function(self, ...)
|
||||
for i = 1, select("#", ...) do
|
||||
local child = select(i, ...)
|
||||
tinsert(self.children, child)
|
||||
child:SetParent(self)
|
||||
child.frame:Show()
|
||||
end
|
||||
self:DoLayout()
|
||||
end
|
||||
|
||||
WidgetContainerBase.ReleaseChildren = function(self)
|
||||
local children = self.children
|
||||
for i = 1,#children do
|
||||
AceGUI:Release(children[i])
|
||||
children[i] = nil
|
||||
end
|
||||
end
|
||||
|
||||
WidgetContainerBase.SetLayout = function(self, Layout)
|
||||
self.LayoutFunc = AceGUI:GetLayout(Layout)
|
||||
end
|
||||
|
||||
WidgetContainerBase.SetAutoAdjustHeight = function(self, adjust)
|
||||
if adjust then
|
||||
self.noAutoHeight = nil
|
||||
else
|
||||
self.noAutoHeight = true
|
||||
end
|
||||
end
|
||||
|
||||
local function FrameResize(this)
|
||||
local self = this.obj
|
||||
if this:GetWidth() and this:GetHeight() then
|
||||
if self.OnWidthSet then
|
||||
self:OnWidthSet(this:GetWidth())
|
||||
end
|
||||
if self.OnHeightSet then
|
||||
self:OnHeightSet(this:GetHeight())
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function ContentResize(this)
|
||||
if this:GetWidth() and this:GetHeight() then
|
||||
this.width = this:GetWidth()
|
||||
this.height = this:GetHeight()
|
||||
this.obj:DoLayout()
|
||||
end
|
||||
end
|
||||
|
||||
setmetatable(WidgetContainerBase, {__index=WidgetBase})
|
||||
|
||||
--One of these function should be called on each Widget Instance as part of its creation process
|
||||
|
||||
--- Register a widget-class as a container for newly created widgets.
|
||||
-- @param widget The widget class
|
||||
function AceGUI:RegisterAsContainer(widget)
|
||||
widget.children = {}
|
||||
widget.userdata = {}
|
||||
widget.events = {}
|
||||
widget.base = WidgetContainerBase
|
||||
widget.content.obj = widget
|
||||
widget.frame.obj = widget
|
||||
widget.content:SetScript("OnSizeChanged", ContentResize)
|
||||
widget.frame:SetScript("OnSizeChanged", FrameResize)
|
||||
setmetatable(widget, {__index = WidgetContainerBase})
|
||||
widget:SetLayout("List")
|
||||
return widget
|
||||
end
|
||||
|
||||
--- Register a widget-class as a widget.
|
||||
-- @param widget The widget class
|
||||
function AceGUI:RegisterAsWidget(widget)
|
||||
widget.userdata = {}
|
||||
widget.events = {}
|
||||
widget.base = WidgetBase
|
||||
widget.frame.obj = widget
|
||||
widget.frame:SetScript("OnSizeChanged", FrameResize)
|
||||
setmetatable(widget, {__index = WidgetBase})
|
||||
return widget
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
------------------
|
||||
-- Widget API --
|
||||
------------------
|
||||
|
||||
--- Registers a widget Constructor, this function returns a new instance of the Widget
|
||||
-- @param Name The name of the widget
|
||||
-- @param Constructor The widget constructor function
|
||||
-- @param Version The version of the widget
|
||||
function AceGUI:RegisterWidgetType(Name, Constructor, Version)
|
||||
assert(type(Constructor) == "function")
|
||||
assert(type(Version) == "number")
|
||||
|
||||
local oldVersion = WidgetVersions[Name]
|
||||
if oldVersion and oldVersion >= Version then return end
|
||||
|
||||
WidgetVersions[Name] = Version
|
||||
WidgetRegistry[Name] = Constructor
|
||||
end
|
||||
|
||||
--- Registers a Layout Function
|
||||
-- @param Name The name of the layout
|
||||
-- @param LayoutFunc Reference to the layout function
|
||||
function AceGUI:RegisterLayout(Name, LayoutFunc)
|
||||
assert(type(LayoutFunc) == "function")
|
||||
if type(Name) == "string" then
|
||||
Name = Name:upper()
|
||||
end
|
||||
LayoutRegistry[Name] = LayoutFunc
|
||||
end
|
||||
|
||||
--- Get a Layout Function from the registry
|
||||
-- @param Name The name of the layout
|
||||
function AceGUI:GetLayout(Name)
|
||||
if type(Name) == "string" then
|
||||
Name = Name:upper()
|
||||
end
|
||||
return LayoutRegistry[Name]
|
||||
end
|
||||
|
||||
AceGUI.counts = AceGUI.counts or {}
|
||||
|
||||
--- A type-based counter to count the number of widgets created.
|
||||
-- This is used by widgets that require a named frame, e.g. when a Blizzard
|
||||
-- Template requires it.
|
||||
-- @param type The widget type
|
||||
function AceGUI:GetNextWidgetNum(type)
|
||||
if not self.counts[type] then
|
||||
self.counts[type] = 0
|
||||
end
|
||||
self.counts[type] = self.counts[type] + 1
|
||||
return self.counts[type]
|
||||
end
|
||||
|
||||
--- Return the number of created widgets for this type.
|
||||
-- In contrast to GetNextWidgetNum, the number is not incremented.
|
||||
-- @param type The widget type
|
||||
function AceGUI:GetWidgetCount(type)
|
||||
return self.counts[type] or 0
|
||||
end
|
||||
|
||||
--- Return the version of the currently registered widget type.
|
||||
-- @param type The widget type
|
||||
function AceGUI:GetWidgetVersion(type)
|
||||
return WidgetVersions[type]
|
||||
end
|
||||
|
||||
-------------
|
||||
-- Layouts --
|
||||
-------------
|
||||
|
||||
--[[
|
||||
A Layout is a func that takes 2 parameters
|
||||
content - the frame that widgets will be placed inside
|
||||
children - a table containing the widgets to layout
|
||||
]]
|
||||
|
||||
-- Very simple Layout, Children are stacked on top of each other down the left side
|
||||
AceGUI:RegisterLayout("List",
|
||||
function(content, children)
|
||||
local height = 0
|
||||
local width = content.width or content:GetWidth() or 0
|
||||
for i = 1, #children do
|
||||
local child = children[i]
|
||||
|
||||
local frame = child.frame
|
||||
frame:ClearAllPoints()
|
||||
frame:Show()
|
||||
if i == 1 then
|
||||
frame:SetPoint("TOPLEFT", content)
|
||||
else
|
||||
frame:SetPoint("TOPLEFT", children[i-1].frame, "BOTTOMLEFT")
|
||||
end
|
||||
|
||||
if child.width == "fill" then
|
||||
child:SetWidth(width)
|
||||
frame:SetPoint("RIGHT", content)
|
||||
|
||||
if child.DoLayout then
|
||||
child:DoLayout()
|
||||
end
|
||||
elseif child.width == "relative" then
|
||||
child:SetWidth(width * child.relWidth)
|
||||
|
||||
if child.DoLayout then
|
||||
child:DoLayout()
|
||||
end
|
||||
end
|
||||
|
||||
height = height + (frame.height or frame:GetHeight() or 0)
|
||||
end
|
||||
safecall(content.obj.LayoutFinished, content.obj, nil, height)
|
||||
end)
|
||||
|
||||
-- A single control fills the whole content area
|
||||
AceGUI:RegisterLayout("Fill",
|
||||
function(content, children)
|
||||
if children[1] then
|
||||
children[1]:SetWidth(content:GetWidth() or 0)
|
||||
children[1]:SetHeight(content:GetHeight() or 0)
|
||||
children[1].frame:SetAllPoints(content)
|
||||
children[1].frame:Show()
|
||||
safecall(content.obj.LayoutFinished, content.obj, nil, children[1].frame:GetHeight())
|
||||
end
|
||||
end)
|
||||
|
||||
AceGUI:RegisterLayout("Flow",
|
||||
function(content, children)
|
||||
--used height so far
|
||||
local height = 0
|
||||
--width used in the current row
|
||||
local usedwidth = 0
|
||||
--height of the current row
|
||||
local rowheight = 0
|
||||
local rowoffset = 0
|
||||
local lastrowoffset
|
||||
|
||||
local width = content.width or content:GetWidth() or 0
|
||||
|
||||
--control at the start of the row
|
||||
local rowstart
|
||||
local rowstartoffset
|
||||
local lastrowstart
|
||||
local isfullheight
|
||||
|
||||
local frameoffset
|
||||
local lastframeoffset
|
||||
local oversize
|
||||
for i = 1, #children do
|
||||
local child = children[i]
|
||||
oversize = nil
|
||||
local frame = child.frame
|
||||
local frameheight = frame.height or frame:GetHeight() or 0
|
||||
local framewidth = frame.width or frame:GetWidth() or 0
|
||||
lastframeoffset = frameoffset
|
||||
-- HACK: Why did we set a frameoffset of (frameheight / 2) ?
|
||||
-- That was moving all widgets half the widgets size down, is that intended?
|
||||
-- Actually, it seems to be neccessary for many cases, we'll leave it in for now.
|
||||
-- If widgets seem to anchor weirdly with this, provide a valid alignoffset for them.
|
||||
-- TODO: Investigate moar!
|
||||
frameoffset = child.alignoffset or (frameheight / 2)
|
||||
|
||||
if child.width == "relative" then
|
||||
framewidth = width * child.relWidth
|
||||
end
|
||||
|
||||
frame:Show()
|
||||
frame:ClearAllPoints()
|
||||
if i == 1 then
|
||||
-- anchor the first control to the top left
|
||||
frame:SetPoint("TOPLEFT", content)
|
||||
rowheight = frameheight
|
||||
rowoffset = frameoffset
|
||||
rowstart = frame
|
||||
rowstartoffset = frameoffset
|
||||
usedwidth = framewidth
|
||||
if usedwidth > width then
|
||||
oversize = true
|
||||
end
|
||||
else
|
||||
-- if there isn't available width for the control start a new row
|
||||
-- if a control is "fill" it will be on a row of its own full width
|
||||
if usedwidth == 0 or ((framewidth) + usedwidth > width) or child.width == "fill" then
|
||||
if isfullheight then
|
||||
-- a previous row has already filled the entire height, there's nothing we can usefully do anymore
|
||||
-- (maybe error/warn about this?)
|
||||
break
|
||||
end
|
||||
--anchor the previous row, we will now know its height and offset
|
||||
rowstart:SetPoint("TOPLEFT", content, "TOPLEFT", 0, -(height + (rowoffset - rowstartoffset) + 3))
|
||||
height = height + rowheight + 3
|
||||
--save this as the rowstart so we can anchor it after the row is complete and we have the max height and offset of controls in it
|
||||
rowstart = frame
|
||||
rowstartoffset = frameoffset
|
||||
rowheight = frameheight
|
||||
rowoffset = frameoffset
|
||||
usedwidth = framewidth
|
||||
if usedwidth > width then
|
||||
oversize = true
|
||||
end
|
||||
-- put the control on the current row, adding it to the width and checking if the height needs to be increased
|
||||
else
|
||||
--handles cases where the new height is higher than either control because of the offsets
|
||||
--math.max(rowheight-rowoffset+frameoffset, frameheight-frameoffset+rowoffset)
|
||||
|
||||
--offset is always the larger of the two offsets
|
||||
rowoffset = math_max(rowoffset, frameoffset)
|
||||
rowheight = math_max(rowheight, rowoffset + (frameheight / 2))
|
||||
|
||||
frame:SetPoint("TOPLEFT", children[i-1].frame, "TOPRIGHT", 0, frameoffset - lastframeoffset)
|
||||
usedwidth = framewidth + usedwidth
|
||||
end
|
||||
end
|
||||
|
||||
if child.width == "fill" then
|
||||
child:SetWidth(width)
|
||||
frame:SetPoint("RIGHT", content)
|
||||
|
||||
usedwidth = 0
|
||||
rowstart = frame
|
||||
rowstartoffset = frameoffset
|
||||
|
||||
if child.DoLayout then
|
||||
child:DoLayout()
|
||||
end
|
||||
rowheight = frame.height or frame:GetHeight() or 0
|
||||
rowoffset = child.alignoffset or (rowheight / 2)
|
||||
rowstartoffset = rowoffset
|
||||
elseif child.width == "relative" then
|
||||
child:SetWidth(width * child.relWidth)
|
||||
|
||||
if child.DoLayout then
|
||||
child:DoLayout()
|
||||
end
|
||||
elseif oversize then
|
||||
if width > 1 then
|
||||
frame:SetPoint("RIGHT", content)
|
||||
end
|
||||
end
|
||||
|
||||
if child.height == "fill" then
|
||||
frame:SetPoint("BOTTOM", content)
|
||||
isfullheight = true
|
||||
end
|
||||
end
|
||||
|
||||
--anchor the last row, if its full height needs a special case since its height has just been changed by the anchor
|
||||
if isfullheight then
|
||||
rowstart:SetPoint("TOPLEFT", content, "TOPLEFT", 0, -height)
|
||||
elseif rowstart then
|
||||
rowstart:SetPoint("TOPLEFT", content, "TOPLEFT", 0, -(height + (rowoffset - rowstartoffset) + 3))
|
||||
end
|
||||
|
||||
height = height + rowheight + 3
|
||||
safecall(content.obj.LayoutFinished, content.obj, nil, height)
|
||||
end)
|
||||
28
MogIt/Libs/AceGUI-3.0/AceGUI-3.0.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
..\FrameXML\UI.xsd">
|
||||
<Script file="AceGUI-3.0.lua"/>
|
||||
<!-- Container -->
|
||||
<Script file="widgets\AceGUIContainer-BlizOptionsGroup.lua"/>
|
||||
<Script file="widgets\AceGUIContainer-DropDownGroup.lua"/>
|
||||
<Script file="widgets\AceGUIContainer-Frame.lua"/>
|
||||
<Script file="widgets\AceGUIContainer-InlineGroup.lua"/>
|
||||
<Script file="widgets\AceGUIContainer-ScrollFrame.lua"/>
|
||||
<Script file="widgets\AceGUIContainer-SimpleGroup.lua"/>
|
||||
<Script file="widgets\AceGUIContainer-TabGroup.lua"/>
|
||||
<Script file="widgets\AceGUIContainer-TreeGroup.lua"/>
|
||||
<Script file="widgets\AceGUIContainer-Window.lua"/>
|
||||
<!-- Widgets -->
|
||||
<Script file="widgets\AceGUIWidget-Button.lua"/>
|
||||
<Script file="widgets\AceGUIWidget-CheckBox.lua"/>
|
||||
<Script file="widgets\AceGUIWidget-ColorPicker.lua"/>
|
||||
<Script file="widgets\AceGUIWidget-DropDown.lua"/>
|
||||
<Script file="widgets\AceGUIWidget-DropDown-Items.lua"/>
|
||||
<Script file="widgets\AceGUIWidget-EditBox.lua"/>
|
||||
<Script file="widgets\AceGUIWidget-Heading.lua"/>
|
||||
<Script file="widgets\AceGUIWidget-Icon.lua"/>
|
||||
<Script file="widgets\AceGUIWidget-InteractiveLabel.lua"/>
|
||||
<Script file="widgets\AceGUIWidget-Keybinding.lua"/>
|
||||
<Script file="widgets\AceGUIWidget-Label.lua"/>
|
||||
<Script file="widgets\AceGUIWidget-MultiLineEditBox.lua"/>
|
||||
<Script file="widgets\AceGUIWidget-Slider.lua"/>
|
||||
</Ui>
|
||||
@@ -0,0 +1,133 @@
|
||||
--[[-----------------------------------------------------------------------------
|
||||
BlizOptionsGroup Container
|
||||
Simple container widget for the integration of AceGUI into the Blizzard Interface Options
|
||||
-------------------------------------------------------------------------------]]
|
||||
local Type, Version = "BlizOptionsGroup", 20
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local pairs = pairs
|
||||
|
||||
-- WoW APIs
|
||||
local CreateFrame = CreateFrame
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function OnShow(frame)
|
||||
frame.obj:Fire("OnShow")
|
||||
end
|
||||
|
||||
local function OnHide(frame)
|
||||
frame.obj:Fire("OnHide")
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Support functions
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function okay(frame)
|
||||
frame.obj:Fire("okay")
|
||||
end
|
||||
|
||||
local function cancel(frame)
|
||||
frame.obj:Fire("cancel")
|
||||
end
|
||||
|
||||
local function defaults(frame)
|
||||
frame.obj:Fire("defaults")
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self:SetName()
|
||||
self:SetTitle()
|
||||
end,
|
||||
|
||||
-- ["OnRelease"] = nil,
|
||||
|
||||
["OnWidthSet"] = function(self, width)
|
||||
local content = self.content
|
||||
local contentwidth = width - 63
|
||||
if contentwidth < 0 then
|
||||
contentwidth = 0
|
||||
end
|
||||
content:SetWidth(contentwidth)
|
||||
content.width = contentwidth
|
||||
end,
|
||||
|
||||
["OnHeightSet"] = function(self, height)
|
||||
local content = self.content
|
||||
local contentheight = height - 26
|
||||
if contentheight < 0 then
|
||||
contentheight = 0
|
||||
end
|
||||
content:SetHeight(contentheight)
|
||||
content.height = contentheight
|
||||
end,
|
||||
|
||||
["SetName"] = function(self, name, parent)
|
||||
self.frame.name = name
|
||||
self.frame.parent = parent
|
||||
end,
|
||||
|
||||
["SetTitle"] = function(self, title)
|
||||
local content = self.content
|
||||
content:ClearAllPoints()
|
||||
if not title or title == "" then
|
||||
content:SetPoint("TOPLEFT", 10, -10)
|
||||
self.label:SetText("")
|
||||
else
|
||||
content:SetPoint("TOPLEFT", 10, -40)
|
||||
self.label:SetText(title)
|
||||
end
|
||||
content:SetPoint("BOTTOMRIGHT", -10, 10)
|
||||
end
|
||||
}
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Constructor()
|
||||
local frame = CreateFrame("Frame")
|
||||
frame:Hide()
|
||||
|
||||
-- support functions for the Blizzard Interface Options
|
||||
frame.okay = okay
|
||||
frame.cancel = cancel
|
||||
frame.defaults = defaults
|
||||
|
||||
frame:SetScript("OnHide", OnHide)
|
||||
frame:SetScript("OnShow", OnShow)
|
||||
|
||||
local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
|
||||
label:SetPoint("TOPLEFT", 10, -15)
|
||||
label:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT", 10, -45)
|
||||
label:SetJustifyH("LEFT")
|
||||
label:SetJustifyV("TOP")
|
||||
|
||||
--Container Support
|
||||
local content = CreateFrame("Frame", nil, frame)
|
||||
content:SetPoint("TOPLEFT", 10, -10)
|
||||
content:SetPoint("BOTTOMRIGHT", -10, 10)
|
||||
|
||||
local widget = {
|
||||
label = label,
|
||||
frame = frame,
|
||||
content = content,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
|
||||
return AceGUI:RegisterAsContainer(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
157
MogIt/Libs/AceGUI-3.0/widgets/AceGUIContainer-DropDownGroup.lua
Normal file
@@ -0,0 +1,157 @@
|
||||
--[[-----------------------------------------------------------------------------
|
||||
DropdownGroup Container
|
||||
Container controlled by a dropdown on the top.
|
||||
-------------------------------------------------------------------------------]]
|
||||
local Type, Version = "DropdownGroup", 20
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local assert, pairs, type = assert, pairs, type
|
||||
|
||||
-- WoW APIs
|
||||
local CreateFrame = CreateFrame
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function SelectedGroup(self, event, value)
|
||||
local group = self.parentgroup
|
||||
local status = group.status or group.localstatus
|
||||
status.selected = value
|
||||
self.parentgroup:Fire("OnGroupSelected", value)
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self.dropdown:SetText("")
|
||||
self:SetDropdownWidth(200)
|
||||
self:SetTitle("")
|
||||
end,
|
||||
|
||||
["OnRelease"] = function(self)
|
||||
self.dropdown.list = nil
|
||||
self.status = nil
|
||||
for k in pairs(self.localstatus) do
|
||||
self.localstatus[k] = nil
|
||||
end
|
||||
end,
|
||||
|
||||
["SetTitle"] = function(self, title)
|
||||
self.titletext:SetText(title)
|
||||
self.dropdown.frame:ClearAllPoints()
|
||||
if title and title ~= "" then
|
||||
self.dropdown.frame:SetPoint("TOPRIGHT", -2, 0)
|
||||
else
|
||||
self.dropdown.frame:SetPoint("TOPLEFT", -1, 0)
|
||||
end
|
||||
end,
|
||||
|
||||
["SetGroupList"] = function(self,list)
|
||||
self.dropdown:SetList(list)
|
||||
end,
|
||||
|
||||
["SetStatusTable"] = function(self, status)
|
||||
assert(type(status) == "table")
|
||||
self.status = status
|
||||
end,
|
||||
|
||||
["SetGroup"] = function(self,group)
|
||||
self.dropdown:SetValue(group)
|
||||
local status = self.status or self.localstatus
|
||||
status.selected = group
|
||||
self:Fire("OnGroupSelected", group)
|
||||
end,
|
||||
|
||||
["OnWidthSet"] = function(self, width)
|
||||
local content = self.content
|
||||
local contentwidth = width - 26
|
||||
if contentwidth < 0 then
|
||||
contentwidth = 0
|
||||
end
|
||||
content:SetWidth(contentwidth)
|
||||
content.width = contentwidth
|
||||
end,
|
||||
|
||||
["OnHeightSet"] = function(self, height)
|
||||
local content = self.content
|
||||
local contentheight = height - 63
|
||||
if contentheight < 0 then
|
||||
contentheight = 0
|
||||
end
|
||||
content:SetHeight(contentheight)
|
||||
content.height = contentheight
|
||||
end,
|
||||
|
||||
["LayoutFinished"] = function(self, width, height)
|
||||
self:SetHeight((height or 0) + 63)
|
||||
end,
|
||||
|
||||
["SetDropdownWidth"] = function(self, width)
|
||||
self.dropdown:SetWidth(width)
|
||||
end
|
||||
}
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
local PaneBackdrop = {
|
||||
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
|
||||
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
||||
tile = true, tileSize = 16, edgeSize = 16,
|
||||
insets = { left = 3, right = 3, top = 5, bottom = 3 }
|
||||
}
|
||||
|
||||
local function Constructor()
|
||||
local frame = CreateFrame("Frame")
|
||||
frame:SetHeight(100)
|
||||
frame:SetWidth(100)
|
||||
frame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
|
||||
local titletext = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
||||
titletext:SetPoint("TOPLEFT", 4, -5)
|
||||
titletext:SetPoint("TOPRIGHT", -4, -5)
|
||||
titletext:SetJustifyH("LEFT")
|
||||
titletext:SetHeight(18)
|
||||
|
||||
local dropdown = AceGUI:Create("Dropdown")
|
||||
dropdown.frame:SetParent(frame)
|
||||
dropdown.frame:SetFrameLevel(dropdown.frame:GetFrameLevel() + 2)
|
||||
dropdown:SetCallback("OnValueChanged", SelectedGroup)
|
||||
dropdown.frame:SetPoint("TOPLEFT", -1, 0)
|
||||
dropdown.frame:Show()
|
||||
dropdown:SetLabel("")
|
||||
|
||||
local border = CreateFrame("Frame", nil, frame)
|
||||
border:SetPoint("TOPLEFT", 0, -26)
|
||||
border:SetPoint("BOTTOMRIGHT", 0, 3)
|
||||
border:SetBackdrop(PaneBackdrop)
|
||||
border:SetBackdropColor(0.1,0.1,0.1,0.5)
|
||||
border:SetBackdropBorderColor(0.4,0.4,0.4)
|
||||
|
||||
--Container Support
|
||||
local content = CreateFrame("Frame", nil, border)
|
||||
content:SetPoint("TOPLEFT", 10, -10)
|
||||
content:SetPoint("BOTTOMRIGHT", -10, 10)
|
||||
|
||||
local widget = {
|
||||
frame = frame,
|
||||
localstatus = {},
|
||||
titletext = titletext,
|
||||
dropdown = dropdown,
|
||||
border = border,
|
||||
content = content,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
dropdown.parentgroup = widget
|
||||
|
||||
return AceGUI:RegisterAsContainer(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
298
MogIt/Libs/AceGUI-3.0/widgets/AceGUIContainer-Frame.lua
Normal file
@@ -0,0 +1,298 @@
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Frame Container
|
||||
-------------------------------------------------------------------------------]]
|
||||
local Type, Version = "Frame", 21
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local pairs, assert, type = pairs, assert, type
|
||||
local wipe = table.wipe
|
||||
|
||||
-- WoW APIs
|
||||
local PlaySound = PlaySound
|
||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||
|
||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||
-- List them here for Mikk's FindGlobals script
|
||||
-- GLOBALS: CLOSE
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Button_OnClick(frame)
|
||||
PlaySound("gsTitleOptionExit")
|
||||
frame.obj:Hide()
|
||||
end
|
||||
|
||||
local function Frame_OnClose(frame)
|
||||
frame.obj:Fire("OnClose")
|
||||
end
|
||||
|
||||
local function Frame_OnMouseDown(frame)
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function Title_OnMouseDown(frame)
|
||||
frame:GetParent():StartMoving()
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function MoverSizer_OnMouseUp(mover)
|
||||
local frame = mover:GetParent()
|
||||
frame:StopMovingOrSizing()
|
||||
local self = frame.obj
|
||||
local status = self.status or self.localstatus
|
||||
status.width = frame:GetWidth()
|
||||
status.height = frame:GetHeight()
|
||||
status.top = frame:GetTop()
|
||||
status.left = frame:GetLeft()
|
||||
end
|
||||
|
||||
local function SizerSE_OnMouseDown(frame)
|
||||
frame:GetParent():StartSizing("BOTTOMRIGHT")
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function SizerS_OnMouseDown(frame)
|
||||
frame:GetParent():StartSizing("BOTTOM")
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function SizerE_OnMouseDown(frame)
|
||||
frame:GetParent():StartSizing("RIGHT")
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function StatusBar_OnEnter(frame)
|
||||
frame.obj:Fire("OnEnterStatusBar")
|
||||
end
|
||||
|
||||
local function StatusBar_OnLeave(frame)
|
||||
frame.obj:Fire("OnLeaveStatusBar")
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self.frame:SetParent(UIParent)
|
||||
self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
self:SetTitle()
|
||||
self:SetStatusText()
|
||||
self:ApplyStatus()
|
||||
self:Show()
|
||||
end,
|
||||
|
||||
["OnRelease"] = function(self)
|
||||
self.status = nil
|
||||
wipe(self.localstatus)
|
||||
end,
|
||||
|
||||
["OnWidthSet"] = function(self, width)
|
||||
local content = self.content
|
||||
local contentwidth = width - 34
|
||||
if contentwidth < 0 then
|
||||
contentwidth = 0
|
||||
end
|
||||
content:SetWidth(contentwidth)
|
||||
content.width = contentwidth
|
||||
end,
|
||||
|
||||
["OnHeightSet"] = function(self, height)
|
||||
local content = self.content
|
||||
local contentheight = height - 57
|
||||
if contentheight < 0 then
|
||||
contentheight = 0
|
||||
end
|
||||
content:SetHeight(contentheight)
|
||||
content.height = contentheight
|
||||
end,
|
||||
|
||||
["SetTitle"] = function(self, title)
|
||||
self.titletext:SetText(title)
|
||||
end,
|
||||
|
||||
["SetStatusText"] = function(self, text)
|
||||
self.statustext:SetText(text)
|
||||
end,
|
||||
|
||||
["Hide"] = function(self)
|
||||
self.frame:Hide()
|
||||
end,
|
||||
|
||||
["Show"] = function(self)
|
||||
self.frame:Show()
|
||||
end,
|
||||
|
||||
-- called to set an external table to store status in
|
||||
["SetStatusTable"] = function(self, status)
|
||||
assert(type(status) == "table")
|
||||
self.status = status
|
||||
self:ApplyStatus()
|
||||
end,
|
||||
|
||||
["ApplyStatus"] = function(self)
|
||||
local status = self.status or self.localstatus
|
||||
local frame = self.frame
|
||||
self:SetWidth(status.width or 700)
|
||||
self:SetHeight(status.height or 500)
|
||||
frame:ClearAllPoints()
|
||||
if status.top and status.left then
|
||||
frame:SetPoint("TOP", UIParent, "BOTTOM", 0, status.top)
|
||||
frame:SetPoint("LEFT", UIParent, "LEFT", status.left, 0)
|
||||
else
|
||||
frame:SetPoint("CENTER")
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
local FrameBackdrop = {
|
||||
bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
|
||||
edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
|
||||
tile = true, tileSize = 32, edgeSize = 32,
|
||||
insets = { left = 8, right = 8, top = 8, bottom = 8 }
|
||||
}
|
||||
|
||||
local PaneBackdrop = {
|
||||
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
|
||||
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
||||
tile = true, tileSize = 16, edgeSize = 16,
|
||||
insets = { left = 3, right = 3, top = 5, bottom = 3 }
|
||||
}
|
||||
|
||||
local function Constructor()
|
||||
local frame = CreateFrame("Frame", nil, UIParent)
|
||||
frame:Hide()
|
||||
|
||||
frame:EnableMouse(true)
|
||||
frame:SetMovable(true)
|
||||
frame:SetResizable(true)
|
||||
frame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
frame:SetBackdrop(FrameBackdrop)
|
||||
frame:SetBackdropColor(0, 0, 0, 1)
|
||||
frame:SetMinResize(400, 200)
|
||||
frame:SetToplevel(true)
|
||||
frame:SetScript("OnHide", Frame_OnClose)
|
||||
frame:SetScript("OnMouseDown", Frame_OnMouseDown)
|
||||
|
||||
local closebutton = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
|
||||
closebutton:SetScript("OnClick", Button_OnClick)
|
||||
closebutton:SetPoint("BOTTOMRIGHT", -27, 17)
|
||||
closebutton:SetHeight(20)
|
||||
closebutton:SetWidth(100)
|
||||
closebutton:SetText(CLOSE)
|
||||
|
||||
local statusbg = CreateFrame("Button", nil, frame)
|
||||
statusbg:SetPoint("BOTTOMLEFT", 15, 15)
|
||||
statusbg:SetPoint("BOTTOMRIGHT", -132, 15)
|
||||
statusbg:SetHeight(24)
|
||||
statusbg:SetBackdrop(PaneBackdrop)
|
||||
statusbg:SetBackdropColor(0.1,0.1,0.1)
|
||||
statusbg:SetBackdropBorderColor(0.4,0.4,0.4)
|
||||
statusbg:SetScript("OnEnter", StatusBar_OnEnter)
|
||||
statusbg:SetScript("OnLeave", StatusBar_OnLeave)
|
||||
|
||||
local statustext = statusbg:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
||||
statustext:SetPoint("TOPLEFT", 7, -2)
|
||||
statustext:SetPoint("BOTTOMRIGHT", -7, 2)
|
||||
statustext:SetHeight(20)
|
||||
statustext:SetJustifyH("LEFT")
|
||||
statustext:SetText("")
|
||||
|
||||
local titlebg = frame:CreateTexture(nil, "OVERLAY")
|
||||
titlebg:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header")
|
||||
titlebg:SetTexCoord(0.31, 0.67, 0, 0.63)
|
||||
titlebg:SetPoint("TOP", 0, 12)
|
||||
titlebg:SetWidth(100)
|
||||
titlebg:SetHeight(40)
|
||||
|
||||
local title = CreateFrame("Frame", nil, frame)
|
||||
title:EnableMouse(true)
|
||||
title:SetScript("OnMouseDown", Title_OnMouseDown)
|
||||
title:SetScript("OnMouseUp", MoverSizer_OnMouseUp)
|
||||
title:SetAllPoints(titlebg)
|
||||
|
||||
local titletext = title:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
||||
titletext:SetPoint("TOP", titlebg, "TOP", 0, -14)
|
||||
|
||||
local titlebg_l = frame:CreateTexture(nil, "OVERLAY")
|
||||
titlebg_l:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header")
|
||||
titlebg_l:SetTexCoord(0.21, 0.31, 0, 0.63)
|
||||
titlebg_l:SetPoint("RIGHT", titlebg, "LEFT")
|
||||
titlebg_l:SetWidth(30)
|
||||
titlebg_l:SetHeight(40)
|
||||
|
||||
local titlebg_r = frame:CreateTexture(nil, "OVERLAY")
|
||||
titlebg_r:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header")
|
||||
titlebg_r:SetTexCoord(0.67, 0.77, 0, 0.63)
|
||||
titlebg_r:SetPoint("LEFT", titlebg, "RIGHT")
|
||||
titlebg_r:SetWidth(30)
|
||||
titlebg_r:SetHeight(40)
|
||||
|
||||
local sizer_se = CreateFrame("Frame", nil, frame)
|
||||
sizer_se:SetPoint("BOTTOMRIGHT")
|
||||
sizer_se:SetWidth(25)
|
||||
sizer_se:SetHeight(25)
|
||||
sizer_se:EnableMouse()
|
||||
sizer_se:SetScript("OnMouseDown",SizerSE_OnMouseDown)
|
||||
sizer_se:SetScript("OnMouseUp", MoverSizer_OnMouseUp)
|
||||
|
||||
local line1 = sizer_se:CreateTexture(nil, "BACKGROUND")
|
||||
line1:SetWidth(14)
|
||||
line1:SetHeight(14)
|
||||
line1:SetPoint("BOTTOMRIGHT", -8, 8)
|
||||
line1:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
|
||||
local x = 0.1 * 14/17
|
||||
line1:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
|
||||
|
||||
local line2 = sizer_se:CreateTexture(nil, "BACKGROUND")
|
||||
line2:SetWidth(8)
|
||||
line2:SetHeight(8)
|
||||
line2:SetPoint("BOTTOMRIGHT", -8, 8)
|
||||
line2:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
|
||||
local x = 0.1 * 8/17
|
||||
line2:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
|
||||
|
||||
local sizer_s = CreateFrame("Frame", nil, frame)
|
||||
sizer_s:SetPoint("BOTTOMRIGHT", -25, 0)
|
||||
sizer_s:SetPoint("BOTTOMLEFT")
|
||||
sizer_s:SetHeight(25)
|
||||
sizer_s:EnableMouse(true)
|
||||
sizer_s:SetScript("OnMouseDown", SizerS_OnMouseDown)
|
||||
sizer_s:SetScript("OnMouseUp", MoverSizer_OnMouseUp)
|
||||
|
||||
local sizer_e = CreateFrame("Frame", nil, frame)
|
||||
sizer_e:SetPoint("BOTTOMRIGHT", 0, 25)
|
||||
sizer_e:SetPoint("TOPRIGHT")
|
||||
sizer_e:SetWidth(25)
|
||||
sizer_e:EnableMouse(true)
|
||||
sizer_e:SetScript("OnMouseDown", SizerE_OnMouseDown)
|
||||
sizer_e:SetScript("OnMouseUp", MoverSizer_OnMouseUp)
|
||||
|
||||
--Container Support
|
||||
local content = CreateFrame("Frame", nil, frame)
|
||||
content:SetPoint("TOPLEFT", 17, -27)
|
||||
content:SetPoint("BOTTOMRIGHT", -17, 40)
|
||||
|
||||
local widget = {
|
||||
localstatus = {},
|
||||
titletext = titletext,
|
||||
statustext = statustext,
|
||||
content = content,
|
||||
frame = frame,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
closebutton.obj, statusbg.obj = widget, widget
|
||||
|
||||
return AceGUI:RegisterAsContainer(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
102
MogIt/Libs/AceGUI-3.0/widgets/AceGUIContainer-InlineGroup.lua
Normal file
@@ -0,0 +1,102 @@
|
||||
--[[-----------------------------------------------------------------------------
|
||||
InlineGroup Container
|
||||
Simple container widget that creates a visible "box" with an optional title.
|
||||
-------------------------------------------------------------------------------]]
|
||||
local Type, Version = "InlineGroup", 20
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local pairs = pairs
|
||||
|
||||
-- WoW APIs
|
||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self:SetWidth(300)
|
||||
self:SetHeight(100)
|
||||
end,
|
||||
|
||||
-- ["OnRelease"] = nil,
|
||||
|
||||
["SetTitle"] = function(self,title)
|
||||
self.titletext:SetText(title)
|
||||
end,
|
||||
|
||||
|
||||
["LayoutFinished"] = function(self, width, height)
|
||||
if self.noAutoHeight then return end
|
||||
self:SetHeight((height or 0) + 40)
|
||||
end,
|
||||
|
||||
["OnWidthSet"] = function(self, width)
|
||||
local content = self.content
|
||||
local contentwidth = width - 20
|
||||
if contentwidth < 0 then
|
||||
contentwidth = 0
|
||||
end
|
||||
content:SetWidth(contentwidth)
|
||||
content.width = contentwidth
|
||||
end,
|
||||
|
||||
["OnHeightSet"] = function(self, height)
|
||||
local content = self.content
|
||||
local contentheight = height - 20
|
||||
if contentheight < 0 then
|
||||
contentheight = 0
|
||||
end
|
||||
content:SetHeight(contentheight)
|
||||
content.height = contentheight
|
||||
end
|
||||
}
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
local PaneBackdrop = {
|
||||
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
|
||||
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
||||
tile = true, tileSize = 16, edgeSize = 16,
|
||||
insets = { left = 3, right = 3, top = 5, bottom = 3 }
|
||||
}
|
||||
|
||||
local function Constructor()
|
||||
local frame = CreateFrame("Frame", nil, UIParent)
|
||||
frame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
|
||||
local titletext = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
||||
titletext:SetPoint("TOPLEFT", 14, 0)
|
||||
titletext:SetPoint("TOPRIGHT", -14, 0)
|
||||
titletext:SetJustifyH("LEFT")
|
||||
titletext:SetHeight(18)
|
||||
|
||||
local border = CreateFrame("Frame", nil, frame)
|
||||
border:SetPoint("TOPLEFT", 0, -17)
|
||||
border:SetPoint("BOTTOMRIGHT", -1, 3)
|
||||
border:SetBackdrop(PaneBackdrop)
|
||||
border:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
|
||||
border:SetBackdropBorderColor(0.4, 0.4, 0.4)
|
||||
|
||||
--Container Support
|
||||
local content = CreateFrame("Frame", nil, border)
|
||||
content:SetPoint("TOPLEFT", 10, -10)
|
||||
content:SetPoint("BOTTOMRIGHT", -10, 10)
|
||||
|
||||
local widget = {
|
||||
frame = frame,
|
||||
content = content,
|
||||
titletext = titletext,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
|
||||
return AceGUI:RegisterAsContainer(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
203
MogIt/Libs/AceGUI-3.0/widgets/AceGUIContainer-ScrollFrame.lua
Normal file
@@ -0,0 +1,203 @@
|
||||
--[[-----------------------------------------------------------------------------
|
||||
ScrollFrame Container
|
||||
Plain container that scrolls its content and doesn't grow in height.
|
||||
-------------------------------------------------------------------------------]]
|
||||
local Type, Version = "ScrollFrame", 21
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local pairs, assert, type = pairs, assert, type
|
||||
local min, max, floor, abs = math.min, math.max, math.floor, math.abs
|
||||
|
||||
-- WoW APIs
|
||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Support functions
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function FixScrollOnUpdate(frame)
|
||||
frame:SetScript("OnUpdate", nil)
|
||||
frame.obj:FixScroll()
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function ScrollFrame_OnMouseWheel(frame, value)
|
||||
frame.obj:MoveScroll(value)
|
||||
end
|
||||
|
||||
local function ScrollFrame_OnSizeChanged(frame)
|
||||
frame:SetScript("OnUpdate", FixScrollOnUpdate)
|
||||
end
|
||||
|
||||
local function ScrollBar_OnScrollValueChanged(frame, value)
|
||||
frame.obj:SetScroll(value)
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self:SetScroll(0)
|
||||
end,
|
||||
|
||||
["OnRelease"] = function(self)
|
||||
self.status = nil
|
||||
for k in pairs(self.localstatus) do
|
||||
self.localstatus[k] = nil
|
||||
end
|
||||
self.scrollframe:SetPoint("BOTTOMRIGHT")
|
||||
self.scrollbar:Hide()
|
||||
self.scrollBarShown = nil
|
||||
self.content.height, self.content.width = nil, nil
|
||||
end,
|
||||
|
||||
["SetScroll"] = function(self, value)
|
||||
local status = self.status or self.localstatus
|
||||
local viewheight = self.scrollframe:GetHeight()
|
||||
local height = self.content:GetHeight()
|
||||
local offset
|
||||
|
||||
if viewheight > height then
|
||||
offset = 0
|
||||
else
|
||||
offset = floor((height - viewheight) / 1000.0 * value)
|
||||
end
|
||||
self.content:ClearAllPoints()
|
||||
self.content:SetPoint("TOPLEFT", 0, offset)
|
||||
self.content:SetPoint("TOPRIGHT", 0, offset)
|
||||
status.offset = offset
|
||||
status.scrollvalue = value
|
||||
end,
|
||||
|
||||
["MoveScroll"] = function(self, value)
|
||||
local status = self.status or self.localstatus
|
||||
local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight()
|
||||
|
||||
if self.scrollBarShown then
|
||||
local diff = height - viewheight
|
||||
local delta = 1
|
||||
if value < 0 then
|
||||
delta = -1
|
||||
end
|
||||
self.scrollbar:SetValue(min(max(status.scrollvalue + delta*(1000/(diff/45)),0), 1000))
|
||||
end
|
||||
end,
|
||||
|
||||
["FixScroll"] = function(self)
|
||||
if self.updateLock then return end
|
||||
self.updateLock = true
|
||||
local status = self.status or self.localstatus
|
||||
local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight()
|
||||
local offset = status.offset or 0
|
||||
local curvalue = self.scrollbar:GetValue()
|
||||
-- Give us a margin of error of 2 pixels to stop some conditions that i would blame on floating point inaccuracys
|
||||
-- No-one is going to miss 2 pixels at the bottom of the frame, anyhow!
|
||||
if viewheight < height + 2 then
|
||||
if self.scrollBarShown then
|
||||
self.scrollBarShown = nil
|
||||
self.scrollbar:Hide()
|
||||
self.scrollbar:SetValue(0)
|
||||
self.scrollframe:SetPoint("BOTTOMRIGHT")
|
||||
self:DoLayout()
|
||||
end
|
||||
else
|
||||
if not self.scrollBarShown then
|
||||
self.scrollBarShown = true
|
||||
self.scrollbar:Show()
|
||||
self.scrollframe:SetPoint("BOTTOMRIGHT", -20, 0)
|
||||
self:DoLayout()
|
||||
end
|
||||
local value = (offset / (viewheight - height) * 1000)
|
||||
if value > 1000 then value = 1000 end
|
||||
self.scrollbar:SetValue(value)
|
||||
self:SetScroll(value)
|
||||
if value < 1000 then
|
||||
self.content:ClearAllPoints()
|
||||
self.content:SetPoint("TOPLEFT", 0, offset)
|
||||
self.content:SetPoint("TOPRIGHT", 0, offset)
|
||||
status.offset = offset
|
||||
end
|
||||
end
|
||||
self.updateLock = nil
|
||||
end,
|
||||
|
||||
["LayoutFinished"] = function(self, width, height)
|
||||
self.content:SetHeight(height or 0 + 20)
|
||||
self.scrollframe:SetScript("OnUpdate", FixScrollOnUpdate)
|
||||
end,
|
||||
|
||||
["SetStatusTable"] = function(self, status)
|
||||
assert(type(status) == "table")
|
||||
self.status = status
|
||||
if not status.scrollvalue then
|
||||
status.scrollvalue = 0
|
||||
end
|
||||
end,
|
||||
|
||||
["OnWidthSet"] = function(self, width)
|
||||
local content = self.content
|
||||
content.width = width
|
||||
end,
|
||||
|
||||
["OnHeightSet"] = function(self, height)
|
||||
local content = self.content
|
||||
content.height = height
|
||||
end
|
||||
}
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Constructor()
|
||||
local frame = CreateFrame("Frame", nil, UIParent)
|
||||
local num = AceGUI:GetNextWidgetNum(Type)
|
||||
|
||||
local scrollframe = CreateFrame("ScrollFrame", nil, frame)
|
||||
scrollframe:SetPoint("TOPLEFT")
|
||||
scrollframe:SetPoint("BOTTOMRIGHT")
|
||||
scrollframe:EnableMouseWheel(true)
|
||||
scrollframe:SetScript("OnMouseWheel", ScrollFrame_OnMouseWheel)
|
||||
scrollframe:SetScript("OnSizeChanged", ScrollFrame_OnSizeChanged)
|
||||
|
||||
local scrollbar = CreateFrame("Slider", ("AceConfigDialogScrollFrame%dScrollBar"):format(num), scrollframe, "UIPanelScrollBarTemplate")
|
||||
scrollbar:SetPoint("TOPLEFT", scrollframe, "TOPRIGHT", 4, -16)
|
||||
scrollbar:SetPoint("BOTTOMLEFT", scrollframe, "BOTTOMRIGHT", 4, 16)
|
||||
scrollbar:SetMinMaxValues(0, 1000)
|
||||
scrollbar:SetValueStep(1)
|
||||
scrollbar:SetValue(0)
|
||||
scrollbar:SetWidth(16)
|
||||
scrollbar:Hide()
|
||||
-- set the script as the last step, so it doesn't fire yet
|
||||
scrollbar:SetScript("OnValueChanged", ScrollBar_OnScrollValueChanged)
|
||||
|
||||
local scrollbg = scrollbar:CreateTexture(nil, "BACKGROUND")
|
||||
scrollbg:SetAllPoints(scrollbar)
|
||||
scrollbg:SetTexture(0, 0, 0, 0.4)
|
||||
|
||||
--Container Support
|
||||
local content = CreateFrame("Frame", nil, scrollframe)
|
||||
content:SetPoint("TOPLEFT")
|
||||
content:SetPoint("TOPRIGHT")
|
||||
content:SetHeight(400)
|
||||
scrollframe:SetScrollChild(content)
|
||||
|
||||
local widget = {
|
||||
localstatus = { scrollvalue = 0 },
|
||||
scrollframe = scrollframe,
|
||||
scrollbar = scrollbar,
|
||||
content = content,
|
||||
frame = frame,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
scrollframe.obj, scrollbar.obj = widget, widget
|
||||
|
||||
return AceGUI:RegisterAsContainer(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
@@ -0,0 +1,69 @@
|
||||
--[[-----------------------------------------------------------------------------
|
||||
SimpleGroup Container
|
||||
Simple container widget that just groups widgets.
|
||||
-------------------------------------------------------------------------------]]
|
||||
local Type, Version = "SimpleGroup", 20
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local pairs = pairs
|
||||
|
||||
-- WoW APIs
|
||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self:SetWidth(300)
|
||||
self:SetHeight(100)
|
||||
end,
|
||||
|
||||
-- ["OnRelease"] = nil,
|
||||
|
||||
["LayoutFinished"] = function(self, width, height)
|
||||
if self.noAutoHeight then return end
|
||||
self:SetHeight(height or 0)
|
||||
end,
|
||||
|
||||
["OnWidthSet"] = function(self, width)
|
||||
local content = self.content
|
||||
content:SetWidth(width)
|
||||
content.width = width
|
||||
end,
|
||||
|
||||
["OnHeightSet"] = function(self, height)
|
||||
local content = self.content
|
||||
content:SetHeight(height)
|
||||
content.height = height
|
||||
end
|
||||
}
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Constructor()
|
||||
local frame = CreateFrame("Frame", nil, UIParent)
|
||||
frame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
|
||||
--Container Support
|
||||
local content = CreateFrame("Frame", nil, frame)
|
||||
content:SetPoint("TOPLEFT")
|
||||
content:SetPoint("BOTTOMRIGHT")
|
||||
|
||||
local widget = {
|
||||
frame = frame,
|
||||
content = content,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
|
||||
return AceGUI:RegisterAsContainer(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
348
MogIt/Libs/AceGUI-3.0/widgets/AceGUIContainer-TabGroup.lua
Normal file
@@ -0,0 +1,348 @@
|
||||
--[[-----------------------------------------------------------------------------
|
||||
TabGroup Container
|
||||
Container that uses tabs on top to switch between groups.
|
||||
-------------------------------------------------------------------------------]]
|
||||
local Type, Version = "TabGroup", 30
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local pairs, ipairs, assert, type, wipe = pairs, ipairs, assert, type, wipe
|
||||
|
||||
-- WoW APIs
|
||||
local PlaySound = PlaySound
|
||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||
local _G = _G
|
||||
|
||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||
-- List them here for Mikk's FindGlobals script
|
||||
-- GLOBALS: PanelTemplates_TabResize, PanelTemplates_SetDisabledTabState, PanelTemplates_SelectTab, PanelTemplates_DeselectTab
|
||||
|
||||
-- local upvalue storage used by BuildTabs
|
||||
local widths = {}
|
||||
local rowwidths = {}
|
||||
local rowends = {}
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Support functions
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function UpdateTabLook(frame)
|
||||
if frame.disabled then
|
||||
PanelTemplates_SetDisabledTabState(frame)
|
||||
elseif frame.selected then
|
||||
PanelTemplates_SelectTab(frame)
|
||||
else
|
||||
PanelTemplates_DeselectTab(frame)
|
||||
end
|
||||
end
|
||||
|
||||
local function Tab_SetText(frame, text)
|
||||
frame:_SetText(text)
|
||||
local width = frame.obj.frame.width or frame.obj.frame:GetWidth() or 0
|
||||
PanelTemplates_TabResize(frame, 0, nil, width)
|
||||
end
|
||||
|
||||
local function Tab_SetSelected(frame, selected)
|
||||
frame.selected = selected
|
||||
UpdateTabLook(frame)
|
||||
end
|
||||
|
||||
local function Tab_SetDisabled(frame, disabled)
|
||||
frame.disabled = disabled
|
||||
UpdateTabLook(frame)
|
||||
end
|
||||
|
||||
local function BuildTabsOnUpdate(frame)
|
||||
local self = frame.obj
|
||||
self:BuildTabs()
|
||||
frame:SetScript("OnUpdate", nil)
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Tab_OnClick(frame)
|
||||
if not (frame.selected or frame.disabled) then
|
||||
PlaySound("igCharacterInfoTab")
|
||||
frame.obj:SelectTab(frame.value)
|
||||
end
|
||||
end
|
||||
|
||||
local function Tab_OnEnter(frame)
|
||||
local self = frame.obj
|
||||
self:Fire("OnTabEnter", self.tabs[frame.id].value, frame)
|
||||
end
|
||||
|
||||
local function Tab_OnLeave(frame)
|
||||
local self = frame.obj
|
||||
self:Fire("OnTabLeave", self.tabs[frame.id].value, frame)
|
||||
end
|
||||
|
||||
local function Tab_OnShow(frame)
|
||||
_G[frame:GetName().."HighlightTexture"]:SetWidth(frame:GetTextWidth() + 30)
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self:SetTitle()
|
||||
end,
|
||||
|
||||
["OnRelease"] = function(self)
|
||||
self.status = nil
|
||||
for k in pairs(self.localstatus) do
|
||||
self.localstatus[k] = nil
|
||||
end
|
||||
self.tablist = nil
|
||||
for _, tab in pairs(self.tabs) do
|
||||
tab:Hide()
|
||||
end
|
||||
end,
|
||||
|
||||
["CreateTab"] = function(self, id)
|
||||
local tabname = ("AceGUITabGroup%dTab%d"):format(self.num, id)
|
||||
local tab = CreateFrame("Button", tabname, self.border, "OptionsFrameTabButtonTemplate")
|
||||
tab.obj = self
|
||||
tab.id = id
|
||||
|
||||
tab.text = _G[tabname .. "Text"]
|
||||
tab.text:ClearAllPoints()
|
||||
tab.text:SetPoint("LEFT", 14, -3)
|
||||
tab.text:SetPoint("RIGHT", -12, -3)
|
||||
|
||||
tab:SetScript("OnClick", Tab_OnClick)
|
||||
tab:SetScript("OnEnter", Tab_OnEnter)
|
||||
tab:SetScript("OnLeave", Tab_OnLeave)
|
||||
tab:SetScript("OnShow", Tab_OnShow)
|
||||
|
||||
tab._SetText = tab.SetText
|
||||
tab.SetText = Tab_SetText
|
||||
tab.SetSelected = Tab_SetSelected
|
||||
tab.SetDisabled = Tab_SetDisabled
|
||||
|
||||
return tab
|
||||
end,
|
||||
|
||||
["SetTitle"] = function(self, text)
|
||||
self.titletext:SetText(text or "")
|
||||
if text and text ~= "" then
|
||||
self.alignoffset = 25
|
||||
else
|
||||
self.alignoffset = 18
|
||||
end
|
||||
self:BuildTabs()
|
||||
end,
|
||||
|
||||
["SetStatusTable"] = function(self, status)
|
||||
assert(type(status) == "table")
|
||||
self.status = status
|
||||
end,
|
||||
|
||||
["SelectTab"] = function(self, value)
|
||||
local status = self.status or self.localstatus
|
||||
local found
|
||||
for i, v in ipairs(self.tabs) do
|
||||
if v.value == value then
|
||||
v:SetSelected(true)
|
||||
found = true
|
||||
else
|
||||
v:SetSelected(false)
|
||||
end
|
||||
end
|
||||
status.selected = value
|
||||
if found then
|
||||
self:Fire("OnGroupSelected",value)
|
||||
end
|
||||
end,
|
||||
|
||||
["SetTabs"] = function(self, tabs)
|
||||
self.tablist = tabs
|
||||
self:BuildTabs()
|
||||
end,
|
||||
|
||||
|
||||
["BuildTabs"] = function(self)
|
||||
local hastitle = (self.titletext:GetText() and self.titletext:GetText() ~= "")
|
||||
local status = self.status or self.localstatus
|
||||
local tablist = self.tablist
|
||||
local tabs = self.tabs
|
||||
|
||||
if not tablist then return end
|
||||
|
||||
local width = self.frame.width or self.frame:GetWidth() or 0
|
||||
|
||||
wipe(widths)
|
||||
wipe(rowwidths)
|
||||
wipe(rowends)
|
||||
|
||||
--Place Text into tabs and get thier initial width
|
||||
for i, v in ipairs(tablist) do
|
||||
local tab = tabs[i]
|
||||
if not tab then
|
||||
tab = self:CreateTab(i)
|
||||
tabs[i] = tab
|
||||
end
|
||||
|
||||
tab:Show()
|
||||
tab:SetText(v.text)
|
||||
tab:SetDisabled(v.disabled)
|
||||
tab.value = v.value
|
||||
|
||||
widths[i] = tab:GetWidth() - 6 --tabs are anchored 10 pixels from the right side of the previous one to reduce spacing, but add a fixed 4px padding for the text
|
||||
end
|
||||
|
||||
for i = (#tablist)+1, #tabs, 1 do
|
||||
tabs[i]:Hide()
|
||||
end
|
||||
|
||||
--First pass, find the minimum number of rows needed to hold all tabs and the initial tab layout
|
||||
local numtabs = #tablist
|
||||
local numrows = 1
|
||||
local usedwidth = 0
|
||||
|
||||
for i = 1, #tablist do
|
||||
--If this is not the first tab of a row and there isn't room for it
|
||||
if usedwidth ~= 0 and (width - usedwidth - widths[i]) < 0 then
|
||||
rowwidths[numrows] = usedwidth + 10 --first tab in each row takes up an extra 10px
|
||||
rowends[numrows] = i - 1
|
||||
numrows = numrows + 1
|
||||
usedwidth = 0
|
||||
end
|
||||
usedwidth = usedwidth + widths[i]
|
||||
end
|
||||
rowwidths[numrows] = usedwidth + 10 --first tab in each row takes up an extra 10px
|
||||
rowends[numrows] = #tablist
|
||||
|
||||
--Fix for single tabs being left on the last row, move a tab from the row above if applicable
|
||||
if numrows > 1 then
|
||||
--if the last row has only one tab
|
||||
if rowends[numrows-1] == numtabs-1 then
|
||||
--if there are more than 2 tabs in the 2nd last row
|
||||
if (numrows == 2 and rowends[numrows-1] > 2) or (rowends[numrows] - rowends[numrows-1] > 2) then
|
||||
--move 1 tab from the second last row to the last, if there is enough space
|
||||
if (rowwidths[numrows] + widths[numtabs-1]) <= width then
|
||||
rowends[numrows-1] = rowends[numrows-1] - 1
|
||||
rowwidths[numrows] = rowwidths[numrows] + widths[numtabs-1]
|
||||
rowwidths[numrows-1] = rowwidths[numrows-1] - widths[numtabs-1]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--anchor the rows as defined and resize tabs to fill thier row
|
||||
local starttab = 1
|
||||
for row, endtab in ipairs(rowends) do
|
||||
local first = true
|
||||
for tabno = starttab, endtab do
|
||||
local tab = tabs[tabno]
|
||||
tab:ClearAllPoints()
|
||||
if first then
|
||||
tab:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 0, -(hastitle and 14 or 7)-(row-1)*20 )
|
||||
first = false
|
||||
else
|
||||
tab:SetPoint("LEFT", tabs[tabno-1], "RIGHT", -10, 0)
|
||||
end
|
||||
end
|
||||
|
||||
-- equal padding for each tab to fill the available width,
|
||||
-- if the used space is above 75% already
|
||||
local padding = 0
|
||||
if not (numrows == 1 and rowwidths[1] < width*0.75) then
|
||||
padding = (width - rowwidths[row]) / (endtab - starttab+1)
|
||||
end
|
||||
|
||||
for i = starttab, endtab do
|
||||
PanelTemplates_TabResize(tabs[i], padding + 4, nil, width)
|
||||
end
|
||||
starttab = endtab + 1
|
||||
end
|
||||
|
||||
self.borderoffset = (hastitle and 17 or 10)+((numrows)*20)
|
||||
self.border:SetPoint("TOPLEFT", 1, -self.borderoffset)
|
||||
end,
|
||||
|
||||
["OnWidthSet"] = function(self, width)
|
||||
local content = self.content
|
||||
local contentwidth = width - 60
|
||||
if contentwidth < 0 then
|
||||
contentwidth = 0
|
||||
end
|
||||
content:SetWidth(contentwidth)
|
||||
content.width = contentwidth
|
||||
self:BuildTabs(self)
|
||||
self.frame:SetScript("OnUpdate", BuildTabsOnUpdate)
|
||||
end,
|
||||
|
||||
["OnHeightSet"] = function(self, height)
|
||||
local content = self.content
|
||||
local contentheight = height - (self.borderoffset + 23)
|
||||
if contentheight < 0 then
|
||||
contentheight = 0
|
||||
end
|
||||
content:SetHeight(contentheight)
|
||||
content.height = contentheight
|
||||
end,
|
||||
|
||||
["LayoutFinished"] = function(self, width, height)
|
||||
if self.noAutoHeight then return end
|
||||
self:SetHeight((height or 0) + (self.borderoffset + 23))
|
||||
end
|
||||
}
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
local PaneBackdrop = {
|
||||
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
|
||||
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
||||
tile = true, tileSize = 16, edgeSize = 16,
|
||||
insets = { left = 3, right = 3, top = 5, bottom = 3 }
|
||||
}
|
||||
|
||||
local function Constructor()
|
||||
local num = AceGUI:GetNextWidgetNum(Type)
|
||||
local frame = CreateFrame("Frame",nil,UIParent)
|
||||
frame:SetHeight(100)
|
||||
frame:SetWidth(100)
|
||||
frame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
|
||||
local titletext = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
|
||||
titletext:SetPoint("TOPLEFT", 14, 0)
|
||||
titletext:SetPoint("TOPRIGHT", -14, 0)
|
||||
titletext:SetJustifyH("LEFT")
|
||||
titletext:SetHeight(18)
|
||||
titletext:SetText("")
|
||||
|
||||
local border = CreateFrame("Frame", nil, frame)
|
||||
border:SetPoint("TOPLEFT", 1, -27)
|
||||
border:SetPoint("BOTTOMRIGHT", -1, 3)
|
||||
border:SetBackdrop(PaneBackdrop)
|
||||
border:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
|
||||
border:SetBackdropBorderColor(0.4, 0.4, 0.4)
|
||||
|
||||
local content = CreateFrame("Frame", nil, border)
|
||||
content:SetPoint("TOPLEFT", 10, -7)
|
||||
content:SetPoint("BOTTOMRIGHT", -10, 7)
|
||||
|
||||
local widget = {
|
||||
num = num,
|
||||
frame = frame,
|
||||
localstatus = {},
|
||||
alignoffset = 18,
|
||||
titletext = titletext,
|
||||
border = border,
|
||||
borderoffset = 27,
|
||||
tabs = {},
|
||||
content = content,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
|
||||
return AceGUI:RegisterAsContainer(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
670
MogIt/Libs/AceGUI-3.0/widgets/AceGUIContainer-TreeGroup.lua
Normal file
@@ -0,0 +1,670 @@
|
||||
--[[-----------------------------------------------------------------------------
|
||||
TreeGroup Container
|
||||
Container that uses a tree control to switch between groups.
|
||||
-------------------------------------------------------------------------------]]
|
||||
local Type, Version = "TreeGroup", 30
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local next, pairs, ipairs, assert, type = next, pairs, ipairs, assert, type
|
||||
local math_min, math_max, floor = math.min, math.max, floor
|
||||
local select, tremove, unpack = select, table.remove, unpack
|
||||
|
||||
-- WoW APIs
|
||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||
|
||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||
-- List them here for Mikk's FindGlobals script
|
||||
-- GLOBALS: GameTooltip, FONT_COLOR_CODE_CLOSE
|
||||
|
||||
-- Recycling functions
|
||||
local new, del
|
||||
do
|
||||
local pool = setmetatable({},{__mode='k'})
|
||||
function new()
|
||||
local t = next(pool)
|
||||
if t then
|
||||
pool[t] = nil
|
||||
return t
|
||||
else
|
||||
return {}
|
||||
end
|
||||
end
|
||||
function del(t)
|
||||
for k in pairs(t) do
|
||||
t[k] = nil
|
||||
end
|
||||
pool[t] = true
|
||||
end
|
||||
end
|
||||
|
||||
local DEFAULT_TREE_WIDTH = 175
|
||||
local DEFAULT_TREE_SIZABLE = true
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Support functions
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function GetButtonUniqueValue(line)
|
||||
local parent = line.parent
|
||||
if parent and parent.value then
|
||||
return GetButtonUniqueValue(parent).."\001"..line.value
|
||||
else
|
||||
return line.value
|
||||
end
|
||||
end
|
||||
|
||||
local function UpdateButton(button, treeline, selected, canExpand, isExpanded)
|
||||
local self = button.obj
|
||||
local toggle = button.toggle
|
||||
local frame = self.frame
|
||||
local text = treeline.text or ""
|
||||
local icon = treeline.icon
|
||||
local iconCoords = treeline.iconCoords
|
||||
local level = treeline.level
|
||||
local value = treeline.value
|
||||
local uniquevalue = treeline.uniquevalue
|
||||
local disabled = treeline.disabled
|
||||
|
||||
button.treeline = treeline
|
||||
button.value = value
|
||||
button.uniquevalue = uniquevalue
|
||||
if selected then
|
||||
button:LockHighlight()
|
||||
button.selected = true
|
||||
else
|
||||
button:UnlockHighlight()
|
||||
button.selected = false
|
||||
end
|
||||
local normalTexture = button:GetNormalTexture()
|
||||
local line = button.line
|
||||
button.level = level
|
||||
if ( level == 1 ) then
|
||||
button:SetNormalFontObject("GameFontNormal")
|
||||
button:SetHighlightFontObject("GameFontHighlight")
|
||||
button.text:SetPoint("LEFT", (icon and 16 or 0) + 8, 2)
|
||||
else
|
||||
button:SetNormalFontObject("GameFontHighlightSmall")
|
||||
button:SetHighlightFontObject("GameFontHighlightSmall")
|
||||
button.text:SetPoint("LEFT", (icon and 16 or 0) + 8 * level, 2)
|
||||
end
|
||||
|
||||
if disabled then
|
||||
button:EnableMouse(false)
|
||||
button.text:SetText("|cff808080"..text..FONT_COLOR_CODE_CLOSE)
|
||||
else
|
||||
button.text:SetText(text)
|
||||
button:EnableMouse(true)
|
||||
end
|
||||
|
||||
if icon then
|
||||
button.icon:SetTexture(icon)
|
||||
button.icon:SetPoint("LEFT", 8 * level, (level == 1) and 0 or 1)
|
||||
else
|
||||
button.icon:SetTexture(nil)
|
||||
end
|
||||
|
||||
if iconCoords then
|
||||
button.icon:SetTexCoord(unpack(iconCoords))
|
||||
else
|
||||
button.icon:SetTexCoord(0, 1, 0, 1)
|
||||
end
|
||||
|
||||
if canExpand then
|
||||
if not isExpanded then
|
||||
toggle:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-UP")
|
||||
toggle:SetPushedTexture("Interface\\Buttons\\UI-PlusButton-DOWN")
|
||||
else
|
||||
toggle:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-UP")
|
||||
toggle:SetPushedTexture("Interface\\Buttons\\UI-MinusButton-DOWN")
|
||||
end
|
||||
toggle:Show()
|
||||
else
|
||||
toggle:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
local function ShouldDisplayLevel(tree)
|
||||
local result = false
|
||||
for k, v in ipairs(tree) do
|
||||
if v.children == nil and v.visible ~= false then
|
||||
result = true
|
||||
elseif v.children then
|
||||
result = result or ShouldDisplayLevel(v.children)
|
||||
end
|
||||
if result then return result end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function addLine(self, v, tree, level, parent)
|
||||
local line = new()
|
||||
line.value = v.value
|
||||
line.text = v.text
|
||||
line.icon = v.icon
|
||||
line.iconCoords = v.iconCoords
|
||||
line.disabled = v.disabled
|
||||
line.tree = tree
|
||||
line.level = level
|
||||
line.parent = parent
|
||||
line.visible = v.visible
|
||||
line.uniquevalue = GetButtonUniqueValue(line)
|
||||
if v.children then
|
||||
line.hasChildren = true
|
||||
else
|
||||
line.hasChildren = nil
|
||||
end
|
||||
self.lines[#self.lines+1] = line
|
||||
return line
|
||||
end
|
||||
|
||||
--fire an update after one frame to catch the treeframes height
|
||||
local function FirstFrameUpdate(frame)
|
||||
local self = frame.obj
|
||||
frame:SetScript("OnUpdate", nil)
|
||||
self:RefreshTree()
|
||||
end
|
||||
|
||||
local function BuildUniqueValue(...)
|
||||
local n = select('#', ...)
|
||||
if n == 1 then
|
||||
return ...
|
||||
else
|
||||
return (...).."\001"..BuildUniqueValue(select(2,...))
|
||||
end
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Expand_OnClick(frame)
|
||||
local button = frame.button
|
||||
local self = button.obj
|
||||
local status = (self.status or self.localstatus).groups
|
||||
status[button.uniquevalue] = not status[button.uniquevalue]
|
||||
self:RefreshTree()
|
||||
end
|
||||
|
||||
local function Button_OnClick(frame)
|
||||
local self = frame.obj
|
||||
self:Fire("OnClick", frame.uniquevalue, frame.selected)
|
||||
if not frame.selected then
|
||||
self:SetSelected(frame.uniquevalue)
|
||||
frame.selected = true
|
||||
frame:LockHighlight()
|
||||
self:RefreshTree()
|
||||
end
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function Button_OnDoubleClick(button)
|
||||
local self = button.obj
|
||||
local status = self.status or self.localstatus
|
||||
local status = (self.status or self.localstatus).groups
|
||||
status[button.uniquevalue] = not status[button.uniquevalue]
|
||||
self:RefreshTree()
|
||||
end
|
||||
|
||||
local function Button_OnEnter(frame)
|
||||
local self = frame.obj
|
||||
self:Fire("OnButtonEnter", frame.uniquevalue, frame)
|
||||
|
||||
if self.enabletooltips then
|
||||
GameTooltip:SetOwner(frame, "ANCHOR_NONE")
|
||||
GameTooltip:SetPoint("LEFT",frame,"RIGHT")
|
||||
GameTooltip:SetText(frame.text:GetText() or "", 1, .82, 0, 1)
|
||||
|
||||
GameTooltip:Show()
|
||||
end
|
||||
end
|
||||
|
||||
local function Button_OnLeave(frame)
|
||||
local self = frame.obj
|
||||
self:Fire("OnButtonLeave", frame.uniquevalue, frame)
|
||||
|
||||
if self.enabletooltips then
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
local function OnScrollValueChanged(frame, value)
|
||||
if frame.obj.noupdate then return end
|
||||
local self = frame.obj
|
||||
local status = self.status or self.localstatus
|
||||
status.scrollvalue = value
|
||||
self:RefreshTree()
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function Tree_OnSizeChanged(frame)
|
||||
frame.obj:RefreshTree()
|
||||
end
|
||||
|
||||
local function Tree_OnMouseWheel(frame, delta)
|
||||
local self = frame.obj
|
||||
if self.showscroll then
|
||||
local scrollbar = self.scrollbar
|
||||
local min, max = scrollbar:GetMinMaxValues()
|
||||
local value = scrollbar:GetValue()
|
||||
local newvalue = math_min(max,math_max(min,value - delta))
|
||||
if value ~= newvalue then
|
||||
scrollbar:SetValue(newvalue)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function Dragger_OnLeave(frame)
|
||||
frame:SetBackdropColor(1, 1, 1, 0)
|
||||
end
|
||||
|
||||
local function Dragger_OnEnter(frame)
|
||||
frame:SetBackdropColor(1, 1, 1, 0.8)
|
||||
end
|
||||
|
||||
local function Dragger_OnMouseDown(frame)
|
||||
local treeframe = frame:GetParent()
|
||||
treeframe:StartSizing("RIGHT")
|
||||
end
|
||||
|
||||
local function Dragger_OnMouseUp(frame)
|
||||
local treeframe = frame:GetParent()
|
||||
local self = treeframe.obj
|
||||
local frame = treeframe:GetParent()
|
||||
treeframe:StopMovingOrSizing()
|
||||
--treeframe:SetScript("OnUpdate", nil)
|
||||
treeframe:SetUserPlaced(false)
|
||||
--Without this :GetHeight will get stuck on the current height, causing the tree contents to not resize
|
||||
treeframe:SetHeight(0)
|
||||
treeframe:SetPoint("TOPLEFT", frame, "TOPLEFT",0,0)
|
||||
treeframe:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT",0,0)
|
||||
|
||||
local status = self.status or self.localstatus
|
||||
status.treewidth = treeframe:GetWidth()
|
||||
|
||||
treeframe.obj:Fire("OnTreeResize",treeframe:GetWidth())
|
||||
-- recalculate the content width
|
||||
treeframe.obj:OnWidthSet(status.fullwidth)
|
||||
-- update the layout of the content
|
||||
treeframe.obj:DoLayout()
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self:SetTreeWidth(DEFAULT_TREE_WIDTH, DEFAULT_TREE_SIZABLE)
|
||||
self:EnableButtonTooltips(true)
|
||||
end,
|
||||
|
||||
["OnRelease"] = function(self)
|
||||
self.status = nil
|
||||
for k, v in pairs(self.localstatus) do
|
||||
if k == "groups" then
|
||||
for k2 in pairs(v) do
|
||||
v[k2] = nil
|
||||
end
|
||||
else
|
||||
self.localstatus[k] = nil
|
||||
end
|
||||
end
|
||||
self.localstatus.scrollvalue = 0
|
||||
self.localstatus.treewidth = DEFAULT_TREE_WIDTH
|
||||
self.localstatus.treesizable = DEFAULT_TREE_SIZABLE
|
||||
end,
|
||||
|
||||
["EnableButtonTooltips"] = function(self, enable)
|
||||
self.enabletooltips = enable
|
||||
end,
|
||||
|
||||
["CreateButton"] = function(self)
|
||||
local num = AceGUI:GetNextWidgetNum("TreeGroupButton")
|
||||
local button = CreateFrame("Button", ("AceGUI30TreeButton%d"):format(num), self.treeframe, "OptionsListButtonTemplate")
|
||||
button.obj = self
|
||||
|
||||
local icon = button:CreateTexture(nil, "OVERLAY")
|
||||
icon:SetWidth(14)
|
||||
icon:SetHeight(14)
|
||||
button.icon = icon
|
||||
|
||||
button:SetScript("OnClick",Button_OnClick)
|
||||
button:SetScript("OnDoubleClick", Button_OnDoubleClick)
|
||||
button:SetScript("OnEnter",Button_OnEnter)
|
||||
button:SetScript("OnLeave",Button_OnLeave)
|
||||
|
||||
button.toggle.button = button
|
||||
button.toggle:SetScript("OnClick",Expand_OnClick)
|
||||
|
||||
return button
|
||||
end,
|
||||
|
||||
["SetStatusTable"] = function(self, status)
|
||||
assert(type(status) == "table")
|
||||
self.status = status
|
||||
if not status.groups then
|
||||
status.groups = {}
|
||||
end
|
||||
if not status.scrollvalue then
|
||||
status.scrollvalue = 0
|
||||
end
|
||||
if not status.treewidth then
|
||||
status.treewidth = DEFAULT_TREE_WIDTH
|
||||
end
|
||||
if not status.treesizable then
|
||||
status.treesizable = DEFAULT_TREE_SIZABLE
|
||||
end
|
||||
self:SetTreeWidth(status.treewidth,status.treesizable)
|
||||
self:RefreshTree()
|
||||
end,
|
||||
|
||||
--sets the tree to be displayed
|
||||
["SetTree"] = function(self, tree, filter)
|
||||
self.filter = filter
|
||||
if tree then
|
||||
assert(type(tree) == "table")
|
||||
end
|
||||
self.tree = tree
|
||||
self:RefreshTree()
|
||||
end,
|
||||
|
||||
["BuildLevel"] = function(self, tree, level, parent)
|
||||
local groups = (self.status or self.localstatus).groups
|
||||
local hasChildren = self.hasChildren
|
||||
|
||||
for i, v in ipairs(tree) do
|
||||
if v.children then
|
||||
if not self.filter or ShouldDisplayLevel(v.children) then
|
||||
local line = addLine(self, v, tree, level, parent)
|
||||
if groups[line.uniquevalue] then
|
||||
self:BuildLevel(v.children, level+1, line)
|
||||
end
|
||||
end
|
||||
elseif v.visible ~= false or not self.filter then
|
||||
addLine(self, v, tree, level, parent)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
["RefreshTree"] = function(self)
|
||||
local buttons = self.buttons
|
||||
local lines = self.lines
|
||||
|
||||
for i, v in ipairs(buttons) do
|
||||
v:Hide()
|
||||
end
|
||||
while lines[1] do
|
||||
local t = tremove(lines)
|
||||
for k in pairs(t) do
|
||||
t[k] = nil
|
||||
end
|
||||
del(t)
|
||||
end
|
||||
|
||||
if not self.tree then return end
|
||||
--Build the list of visible entries from the tree and status tables
|
||||
local status = self.status or self.localstatus
|
||||
local groupstatus = status.groups
|
||||
local tree = self.tree
|
||||
|
||||
local treeframe = self.treeframe
|
||||
|
||||
self:BuildLevel(tree, 1)
|
||||
|
||||
local numlines = #lines
|
||||
|
||||
local maxlines = (floor(((self.treeframe:GetHeight()or 0) - 20 ) / 18))
|
||||
|
||||
local first, last
|
||||
|
||||
if numlines <= maxlines then
|
||||
--the whole tree fits in the frame
|
||||
status.scrollvalue = 0
|
||||
self:ShowScroll(false)
|
||||
first, last = 1, numlines
|
||||
else
|
||||
self:ShowScroll(true)
|
||||
--scrolling will be needed
|
||||
self.noupdate = true
|
||||
self.scrollbar:SetMinMaxValues(0, numlines - maxlines)
|
||||
--check if we are scrolled down too far
|
||||
if numlines - status.scrollvalue < maxlines then
|
||||
status.scrollvalue = numlines - maxlines
|
||||
self.scrollbar:SetValue(status.scrollvalue)
|
||||
end
|
||||
self.noupdate = nil
|
||||
first, last = status.scrollvalue+1, status.scrollvalue + maxlines
|
||||
end
|
||||
|
||||
local buttonnum = 1
|
||||
for i = first, last do
|
||||
local line = lines[i]
|
||||
local button = buttons[buttonnum]
|
||||
if not button then
|
||||
button = self:CreateButton()
|
||||
|
||||
buttons[buttonnum] = button
|
||||
button:SetParent(treeframe)
|
||||
button:SetFrameLevel(treeframe:GetFrameLevel()+1)
|
||||
button:ClearAllPoints()
|
||||
if i == 1 then
|
||||
if self.showscroll then
|
||||
button:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",-22,-10)
|
||||
button:SetPoint("TOPLEFT", self.treeframe, "TOPLEFT", 0, -10)
|
||||
else
|
||||
button:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",0,-10)
|
||||
button:SetPoint("TOPLEFT", self.treeframe, "TOPLEFT", 0, -10)
|
||||
end
|
||||
else
|
||||
button:SetPoint("TOPRIGHT", buttons[buttonnum-1], "BOTTOMRIGHT",0,0)
|
||||
button:SetPoint("TOPLEFT", buttons[buttonnum-1], "BOTTOMLEFT",0,0)
|
||||
end
|
||||
end
|
||||
|
||||
UpdateButton(button, line, status.selected == line.uniquevalue, line.hasChildren, groupstatus[line.uniquevalue] )
|
||||
button:Show()
|
||||
buttonnum = buttonnum + 1
|
||||
end
|
||||
end,
|
||||
|
||||
["SetSelected"] = function(self, value)
|
||||
local status = self.status or self.localstatus
|
||||
if status.selected ~= value then
|
||||
status.selected = value
|
||||
self:Fire("OnGroupSelected", value)
|
||||
end
|
||||
end,
|
||||
|
||||
["Select"] = function(self, uniquevalue, ...)
|
||||
self.filter = false
|
||||
local status = self.status or self.localstatus
|
||||
local groups = status.groups
|
||||
for i = 1, select('#', ...) do
|
||||
groups[BuildUniqueValue(select(i, ...))] = true
|
||||
end
|
||||
status.selected = uniquevalue
|
||||
self:RefreshTree()
|
||||
self:Fire("OnGroupSelected", uniquevalue)
|
||||
end,
|
||||
|
||||
["SelectByPath"] = function(self, ...)
|
||||
self:Select(BuildUniqueValue(...), ...)
|
||||
end,
|
||||
|
||||
["SelectByValue"] = function(self, uniquevalue)
|
||||
self:Select(uniquevalue, ("\001"):split(uniquevalue))
|
||||
end,
|
||||
|
||||
["ShowScroll"] = function(self, show)
|
||||
self.showscroll = show
|
||||
if show then
|
||||
self.scrollbar:Show()
|
||||
if self.buttons[1] then
|
||||
self.buttons[1]:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",-22,-10)
|
||||
end
|
||||
else
|
||||
self.scrollbar:Hide()
|
||||
if self.buttons[1] then
|
||||
self.buttons[1]:SetPoint("TOPRIGHT", self.treeframe,"TOPRIGHT",0,-10)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
["OnWidthSet"] = function(self, width)
|
||||
local content = self.content
|
||||
local treeframe = self.treeframe
|
||||
local status = self.status or self.localstatus
|
||||
status.fullwidth = width
|
||||
|
||||
local contentwidth = width - status.treewidth - 20
|
||||
if contentwidth < 0 then
|
||||
contentwidth = 0
|
||||
end
|
||||
content:SetWidth(contentwidth)
|
||||
content.width = contentwidth
|
||||
|
||||
local maxtreewidth = math_min(400, width - 50)
|
||||
|
||||
if maxtreewidth > 100 and status.treewidth > maxtreewidth then
|
||||
self:SetTreeWidth(maxtreewidth, status.treesizable)
|
||||
end
|
||||
treeframe:SetMaxResize(maxtreewidth, 1600)
|
||||
end,
|
||||
|
||||
["OnHeightSet"] = function(self, height)
|
||||
local content = self.content
|
||||
local contentheight = height - 20
|
||||
if contentheight < 0 then
|
||||
contentheight = 0
|
||||
end
|
||||
content:SetHeight(contentheight)
|
||||
content.height = contentheight
|
||||
end,
|
||||
|
||||
["SetTreeWidth"] = function(self, treewidth, resizable)
|
||||
if not resizable then
|
||||
if type(treewidth) == 'number' then
|
||||
resizable = false
|
||||
elseif type(treewidth) == 'boolean' then
|
||||
resizable = treewidth
|
||||
treewidth = DEFAULT_TREE_WIDTH
|
||||
else
|
||||
resizable = false
|
||||
treewidth = DEFAULT_TREE_WIDTH
|
||||
end
|
||||
end
|
||||
self.treeframe:SetWidth(treewidth)
|
||||
self.dragger:EnableMouse(resizable)
|
||||
|
||||
local status = self.status or self.localstatus
|
||||
status.treewidth = treewidth
|
||||
status.treesizable = resizable
|
||||
|
||||
-- recalculate the content width
|
||||
if status.fullwidth then
|
||||
self:OnWidthSet(status.fullwidth)
|
||||
end
|
||||
end,
|
||||
|
||||
["LayoutFinished"] = function(self, width, height)
|
||||
if self.noAutoHeight then return end
|
||||
self:SetHeight((height or 0) + 20)
|
||||
end
|
||||
}
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
local PaneBackdrop = {
|
||||
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
|
||||
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
||||
tile = true, tileSize = 16, edgeSize = 16,
|
||||
insets = { left = 3, right = 3, top = 5, bottom = 3 }
|
||||
}
|
||||
|
||||
local DraggerBackdrop = {
|
||||
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
|
||||
edgeFile = nil,
|
||||
tile = true, tileSize = 16, edgeSize = 0,
|
||||
insets = { left = 3, right = 3, top = 7, bottom = 7 }
|
||||
}
|
||||
|
||||
local function Constructor()
|
||||
local num = AceGUI:GetNextWidgetNum(Type)
|
||||
local frame = CreateFrame("Frame", nil, UIParent)
|
||||
|
||||
local treeframe = CreateFrame("Frame", nil, frame)
|
||||
treeframe:SetPoint("TOPLEFT")
|
||||
treeframe:SetPoint("BOTTOMLEFT")
|
||||
treeframe:SetWidth(DEFAULT_TREE_WIDTH)
|
||||
treeframe:EnableMouseWheel(true)
|
||||
treeframe:SetBackdrop(PaneBackdrop)
|
||||
treeframe:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
|
||||
treeframe:SetBackdropBorderColor(0.4, 0.4, 0.4)
|
||||
treeframe:SetResizable(true)
|
||||
treeframe:SetMinResize(100, 1)
|
||||
treeframe:SetMaxResize(400, 1600)
|
||||
treeframe:SetScript("OnUpdate", FirstFrameUpdate)
|
||||
treeframe:SetScript("OnSizeChanged", Tree_OnSizeChanged)
|
||||
treeframe:SetScript("OnMouseWheel", Tree_OnMouseWheel)
|
||||
|
||||
local dragger = CreateFrame("Frame", nil, treeframe)
|
||||
dragger:SetWidth(8)
|
||||
dragger:SetPoint("TOP", treeframe, "TOPRIGHT")
|
||||
dragger:SetPoint("BOTTOM", treeframe, "BOTTOMRIGHT")
|
||||
dragger:SetBackdrop(DraggerBackdrop)
|
||||
dragger:SetBackdropColor(1, 1, 1, 0)
|
||||
dragger:SetScript("OnEnter", Dragger_OnEnter)
|
||||
dragger:SetScript("OnLeave", Dragger_OnLeave)
|
||||
dragger:SetScript("OnMouseDown", Dragger_OnMouseDown)
|
||||
dragger:SetScript("OnMouseUp", Dragger_OnMouseUp)
|
||||
|
||||
local scrollbar = CreateFrame("Slider", ("AceConfigDialogTreeGroup%dScrollBar"):format(num), treeframe, "UIPanelScrollBarTemplate")
|
||||
scrollbar:SetScript("OnValueChanged", nil)
|
||||
scrollbar:SetPoint("TOPRIGHT", -10, -26)
|
||||
scrollbar:SetPoint("BOTTOMRIGHT", -10, 26)
|
||||
scrollbar:SetMinMaxValues(0,0)
|
||||
scrollbar:SetValueStep(1)
|
||||
scrollbar:SetValue(0)
|
||||
scrollbar:SetWidth(16)
|
||||
scrollbar:SetScript("OnValueChanged", OnScrollValueChanged)
|
||||
|
||||
local scrollbg = scrollbar:CreateTexture(nil, "BACKGROUND")
|
||||
scrollbg:SetAllPoints(scrollbar)
|
||||
scrollbg:SetTexture(0,0,0,0.4)
|
||||
|
||||
local border = CreateFrame("Frame",nil,frame)
|
||||
border:SetPoint("TOPLEFT", treeframe, "TOPRIGHT")
|
||||
border:SetPoint("BOTTOMRIGHT")
|
||||
border:SetBackdrop(PaneBackdrop)
|
||||
border:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
|
||||
border:SetBackdropBorderColor(0.4, 0.4, 0.4)
|
||||
|
||||
--Container Support
|
||||
local content = CreateFrame("Frame", nil, border)
|
||||
content:SetPoint("TOPLEFT", 10, -10)
|
||||
content:SetPoint("BOTTOMRIGHT", -10, 10)
|
||||
|
||||
local widget = {
|
||||
frame = frame,
|
||||
lines = {},
|
||||
levels = {},
|
||||
buttons = {},
|
||||
hasChildren = {},
|
||||
localstatus = { groups = {}, scrollvalue = 0 },
|
||||
filter = false,
|
||||
treeframe = treeframe,
|
||||
dragger = dragger,
|
||||
scrollbar = scrollbar,
|
||||
border = border,
|
||||
content = content,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
treeframe.obj, dragger.obj, scrollbar.obj = widget, widget, widget
|
||||
|
||||
return AceGUI:RegisterAsContainer(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
331
MogIt/Libs/AceGUI-3.0/widgets/AceGUIContainer-Window.lua
Normal file
@@ -0,0 +1,331 @@
|
||||
local AceGUI = LibStub("AceGUI-3.0")
|
||||
|
||||
-- Lua APIs
|
||||
local pairs, assert, type = pairs, assert, type
|
||||
|
||||
-- WoW APIs
|
||||
local PlaySound = PlaySound
|
||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||
|
||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||
-- List them here for Mikk's FindGlobals script
|
||||
-- GLOBALS: GameFontNormal
|
||||
|
||||
----------------
|
||||
-- Main Frame --
|
||||
----------------
|
||||
--[[
|
||||
Events :
|
||||
OnClose
|
||||
|
||||
]]
|
||||
do
|
||||
local Type = "Window"
|
||||
local Version = 4
|
||||
|
||||
local function frameOnClose(this)
|
||||
this.obj:Fire("OnClose")
|
||||
end
|
||||
|
||||
local function closeOnClick(this)
|
||||
PlaySound("gsTitleOptionExit")
|
||||
this.obj:Hide()
|
||||
end
|
||||
|
||||
local function frameOnMouseDown(this)
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function titleOnMouseDown(this)
|
||||
this:GetParent():StartMoving()
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function frameOnMouseUp(this)
|
||||
local frame = this:GetParent()
|
||||
frame:StopMovingOrSizing()
|
||||
local self = frame.obj
|
||||
local status = self.status or self.localstatus
|
||||
status.width = frame:GetWidth()
|
||||
status.height = frame:GetHeight()
|
||||
status.top = frame:GetTop()
|
||||
status.left = frame:GetLeft()
|
||||
end
|
||||
|
||||
local function sizerseOnMouseDown(this)
|
||||
this:GetParent():StartSizing("BOTTOMRIGHT")
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function sizersOnMouseDown(this)
|
||||
this:GetParent():StartSizing("BOTTOM")
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function sizereOnMouseDown(this)
|
||||
this:GetParent():StartSizing("RIGHT")
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function sizerOnMouseUp(this)
|
||||
this:GetParent():StopMovingOrSizing()
|
||||
end
|
||||
|
||||
local function SetTitle(self,title)
|
||||
self.titletext:SetText(title)
|
||||
end
|
||||
|
||||
local function SetStatusText(self,text)
|
||||
-- self.statustext:SetText(text)
|
||||
end
|
||||
|
||||
local function Hide(self)
|
||||
self.frame:Hide()
|
||||
end
|
||||
|
||||
local function Show(self)
|
||||
self.frame:Show()
|
||||
end
|
||||
|
||||
local function OnAcquire(self)
|
||||
self.frame:SetParent(UIParent)
|
||||
self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
self:ApplyStatus()
|
||||
self:EnableResize(true)
|
||||
self:Show()
|
||||
end
|
||||
|
||||
local function OnRelease(self)
|
||||
self.status = nil
|
||||
for k in pairs(self.localstatus) do
|
||||
self.localstatus[k] = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- called to set an external table to store status in
|
||||
local function SetStatusTable(self, status)
|
||||
assert(type(status) == "table")
|
||||
self.status = status
|
||||
self:ApplyStatus()
|
||||
end
|
||||
|
||||
local function ApplyStatus(self)
|
||||
local status = self.status or self.localstatus
|
||||
local frame = self.frame
|
||||
self:SetWidth(status.width or 700)
|
||||
self:SetHeight(status.height or 500)
|
||||
if status.top and status.left then
|
||||
frame:SetPoint("TOP",UIParent,"BOTTOM",0,status.top)
|
||||
frame:SetPoint("LEFT",UIParent,"LEFT",status.left,0)
|
||||
else
|
||||
frame:SetPoint("CENTER",UIParent,"CENTER")
|
||||
end
|
||||
end
|
||||
|
||||
local function OnWidthSet(self, width)
|
||||
local content = self.content
|
||||
local contentwidth = width - 34
|
||||
if contentwidth < 0 then
|
||||
contentwidth = 0
|
||||
end
|
||||
content:SetWidth(contentwidth)
|
||||
content.width = contentwidth
|
||||
end
|
||||
|
||||
|
||||
local function OnHeightSet(self, height)
|
||||
local content = self.content
|
||||
local contentheight = height - 57
|
||||
if contentheight < 0 then
|
||||
contentheight = 0
|
||||
end
|
||||
content:SetHeight(contentheight)
|
||||
content.height = contentheight
|
||||
end
|
||||
|
||||
local function EnableResize(self, state)
|
||||
local func = state and "Show" or "Hide"
|
||||
self.sizer_se[func](self.sizer_se)
|
||||
self.sizer_s[func](self.sizer_s)
|
||||
self.sizer_e[func](self.sizer_e)
|
||||
end
|
||||
|
||||
local function Constructor()
|
||||
local frame = CreateFrame("Frame",nil,UIParent)
|
||||
local self = {}
|
||||
self.type = "Window"
|
||||
|
||||
self.Hide = Hide
|
||||
self.Show = Show
|
||||
self.SetTitle = SetTitle
|
||||
self.OnRelease = OnRelease
|
||||
self.OnAcquire = OnAcquire
|
||||
self.SetStatusText = SetStatusText
|
||||
self.SetStatusTable = SetStatusTable
|
||||
self.ApplyStatus = ApplyStatus
|
||||
self.OnWidthSet = OnWidthSet
|
||||
self.OnHeightSet = OnHeightSet
|
||||
self.EnableResize = EnableResize
|
||||
|
||||
self.localstatus = {}
|
||||
|
||||
self.frame = frame
|
||||
frame.obj = self
|
||||
frame:SetWidth(700)
|
||||
frame:SetHeight(500)
|
||||
frame:SetPoint("CENTER",UIParent,"CENTER",0,0)
|
||||
frame:EnableMouse()
|
||||
frame:SetMovable(true)
|
||||
frame:SetResizable(true)
|
||||
frame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
frame:SetScript("OnMouseDown", frameOnMouseDown)
|
||||
|
||||
frame:SetScript("OnHide",frameOnClose)
|
||||
frame:SetMinResize(240,240)
|
||||
frame:SetToplevel(true)
|
||||
|
||||
local titlebg = frame:CreateTexture(nil, "BACKGROUND")
|
||||
titlebg:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Title-Background]])
|
||||
titlebg:SetPoint("TOPLEFT", 9, -6)
|
||||
titlebg:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT", -28, -24)
|
||||
|
||||
local dialogbg = frame:CreateTexture(nil, "BACKGROUND")
|
||||
dialogbg:SetTexture([[Interface\Tooltips\UI-Tooltip-Background]])
|
||||
dialogbg:SetPoint("TOPLEFT", 8, -24)
|
||||
dialogbg:SetPoint("BOTTOMRIGHT", -6, 8)
|
||||
dialogbg:SetVertexColor(0, 0, 0, .75)
|
||||
|
||||
local topleft = frame:CreateTexture(nil, "BORDER")
|
||||
topleft:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
|
||||
topleft:SetWidth(64)
|
||||
topleft:SetHeight(64)
|
||||
topleft:SetPoint("TOPLEFT")
|
||||
topleft:SetTexCoord(0.501953125, 0.625, 0, 1)
|
||||
|
||||
local topright = frame:CreateTexture(nil, "BORDER")
|
||||
topright:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
|
||||
topright:SetWidth(64)
|
||||
topright:SetHeight(64)
|
||||
topright:SetPoint("TOPRIGHT")
|
||||
topright:SetTexCoord(0.625, 0.75, 0, 1)
|
||||
|
||||
local top = frame:CreateTexture(nil, "BORDER")
|
||||
top:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
|
||||
top:SetHeight(64)
|
||||
top:SetPoint("TOPLEFT", topleft, "TOPRIGHT")
|
||||
top:SetPoint("TOPRIGHT", topright, "TOPLEFT")
|
||||
top:SetTexCoord(0.25, 0.369140625, 0, 1)
|
||||
|
||||
local bottomleft = frame:CreateTexture(nil, "BORDER")
|
||||
bottomleft:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
|
||||
bottomleft:SetWidth(64)
|
||||
bottomleft:SetHeight(64)
|
||||
bottomleft:SetPoint("BOTTOMLEFT")
|
||||
bottomleft:SetTexCoord(0.751953125, 0.875, 0, 1)
|
||||
|
||||
local bottomright = frame:CreateTexture(nil, "BORDER")
|
||||
bottomright:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
|
||||
bottomright:SetWidth(64)
|
||||
bottomright:SetHeight(64)
|
||||
bottomright:SetPoint("BOTTOMRIGHT")
|
||||
bottomright:SetTexCoord(0.875, 1, 0, 1)
|
||||
|
||||
local bottom = frame:CreateTexture(nil, "BORDER")
|
||||
bottom:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
|
||||
bottom:SetHeight(64)
|
||||
bottom:SetPoint("BOTTOMLEFT", bottomleft, "BOTTOMRIGHT")
|
||||
bottom:SetPoint("BOTTOMRIGHT", bottomright, "BOTTOMLEFT")
|
||||
bottom:SetTexCoord(0.376953125, 0.498046875, 0, 1)
|
||||
|
||||
local left = frame:CreateTexture(nil, "BORDER")
|
||||
left:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
|
||||
left:SetWidth(64)
|
||||
left:SetPoint("TOPLEFT", topleft, "BOTTOMLEFT")
|
||||
left:SetPoint("BOTTOMLEFT", bottomleft, "TOPLEFT")
|
||||
left:SetTexCoord(0.001953125, 0.125, 0, 1)
|
||||
|
||||
local right = frame:CreateTexture(nil, "BORDER")
|
||||
right:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]])
|
||||
right:SetWidth(64)
|
||||
right:SetPoint("TOPRIGHT", topright, "BOTTOMRIGHT")
|
||||
right:SetPoint("BOTTOMRIGHT", bottomright, "TOPRIGHT")
|
||||
right:SetTexCoord(0.1171875, 0.2421875, 0, 1)
|
||||
|
||||
local close = CreateFrame("Button", nil, frame, "UIPanelCloseButton")
|
||||
close:SetPoint("TOPRIGHT", 2, 1)
|
||||
close:SetScript("OnClick", closeOnClick)
|
||||
self.closebutton = close
|
||||
close.obj = self
|
||||
|
||||
local titletext = frame:CreateFontString(nil, "ARTWORK")
|
||||
titletext:SetFontObject(GameFontNormal)
|
||||
titletext:SetPoint("TOPLEFT", 12, -8)
|
||||
titletext:SetPoint("TOPRIGHT", -32, -8)
|
||||
self.titletext = titletext
|
||||
|
||||
local title = CreateFrame("Button", nil, frame)
|
||||
title:SetPoint("TOPLEFT", titlebg)
|
||||
title:SetPoint("BOTTOMRIGHT", titlebg)
|
||||
title:EnableMouse()
|
||||
title:SetScript("OnMouseDown",titleOnMouseDown)
|
||||
title:SetScript("OnMouseUp", frameOnMouseUp)
|
||||
self.title = title
|
||||
|
||||
local sizer_se = CreateFrame("Frame",nil,frame)
|
||||
sizer_se:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0)
|
||||
sizer_se:SetWidth(25)
|
||||
sizer_se:SetHeight(25)
|
||||
sizer_se:EnableMouse()
|
||||
sizer_se:SetScript("OnMouseDown",sizerseOnMouseDown)
|
||||
sizer_se:SetScript("OnMouseUp", sizerOnMouseUp)
|
||||
self.sizer_se = sizer_se
|
||||
|
||||
local line1 = sizer_se:CreateTexture(nil, "BACKGROUND")
|
||||
self.line1 = line1
|
||||
line1:SetWidth(14)
|
||||
line1:SetHeight(14)
|
||||
line1:SetPoint("BOTTOMRIGHT", -8, 8)
|
||||
line1:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
|
||||
local x = 0.1 * 14/17
|
||||
line1:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
|
||||
|
||||
local line2 = sizer_se:CreateTexture(nil, "BACKGROUND")
|
||||
self.line2 = line2
|
||||
line2:SetWidth(8)
|
||||
line2:SetHeight(8)
|
||||
line2:SetPoint("BOTTOMRIGHT", -8, 8)
|
||||
line2:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
|
||||
local x = 0.1 * 8/17
|
||||
line2:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
|
||||
|
||||
local sizer_s = CreateFrame("Frame",nil,frame)
|
||||
sizer_s:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-25,0)
|
||||
sizer_s:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",0,0)
|
||||
sizer_s:SetHeight(25)
|
||||
sizer_s:EnableMouse()
|
||||
sizer_s:SetScript("OnMouseDown",sizersOnMouseDown)
|
||||
sizer_s:SetScript("OnMouseUp", sizerOnMouseUp)
|
||||
self.sizer_s = sizer_s
|
||||
|
||||
local sizer_e = CreateFrame("Frame",nil,frame)
|
||||
sizer_e:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,25)
|
||||
sizer_e:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0)
|
||||
sizer_e:SetWidth(25)
|
||||
sizer_e:EnableMouse()
|
||||
sizer_e:SetScript("OnMouseDown",sizereOnMouseDown)
|
||||
sizer_e:SetScript("OnMouseUp", sizerOnMouseUp)
|
||||
self.sizer_e = sizer_e
|
||||
|
||||
--Container Support
|
||||
local content = CreateFrame("Frame",nil,frame)
|
||||
self.content = content
|
||||
content.obj = self
|
||||
content:SetPoint("TOPLEFT",frame,"TOPLEFT",12,-32)
|
||||
content:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-12,13)
|
||||
|
||||
AceGUI:RegisterAsContainer(self)
|
||||
return self
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type,Constructor,Version)
|
||||
end
|
||||
92
MogIt/Libs/AceGUI-3.0/widgets/AceGUIWidget-Button.lua
Normal file
@@ -0,0 +1,92 @@
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Button Widget
|
||||
Graphical Button.
|
||||
-------------------------------------------------------------------------------]]
|
||||
local Type, Version = "Button", 20
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local pairs = pairs
|
||||
|
||||
-- WoW APIs
|
||||
local _G = _G
|
||||
local PlaySound, CreateFrame, UIParent = PlaySound, CreateFrame, UIParent
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Button_OnClick(frame, ...)
|
||||
PlaySound("igMainMenuOption")
|
||||
frame.obj:Fire("OnClick", ...)
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function Control_OnEnter(frame)
|
||||
frame.obj:Fire("OnEnter")
|
||||
end
|
||||
|
||||
local function Control_OnLeave(frame)
|
||||
frame.obj:Fire("OnLeave")
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
-- restore default values
|
||||
self:SetHeight(24)
|
||||
self:SetWidth(200)
|
||||
self:SetDisabled(false)
|
||||
self:SetText()
|
||||
end,
|
||||
|
||||
-- ["OnRelease"] = nil,
|
||||
|
||||
["SetText"] = function(self, text)
|
||||
self.text:SetText(text)
|
||||
end,
|
||||
|
||||
["SetDisabled"] = function(self, disabled)
|
||||
self.disabled = disabled
|
||||
if disabled then
|
||||
self.frame:Disable()
|
||||
else
|
||||
self.frame:Enable()
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Constructor()
|
||||
local name = "AceGUI30Button" .. AceGUI:GetNextWidgetNum(Type)
|
||||
local frame = CreateFrame("Button", name, UIParent, "UIPanelButtonTemplate2")
|
||||
frame:Hide()
|
||||
|
||||
frame:EnableMouse(true)
|
||||
frame:SetScript("OnClick", Button_OnClick)
|
||||
frame:SetScript("OnEnter", Control_OnEnter)
|
||||
frame:SetScript("OnLeave", Control_OnLeave)
|
||||
|
||||
local text = frame:GetFontString()
|
||||
text:ClearAllPoints()
|
||||
text:SetPoint("TOPLEFT", 15, -1)
|
||||
text:SetPoint("BOTTOMRIGHT", -15, 1)
|
||||
text:SetJustifyV("MIDDLE")
|
||||
|
||||
local widget = {
|
||||
text = text,
|
||||
frame = frame,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
|
||||
return AceGUI:RegisterAsWidget(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
289
MogIt/Libs/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua
Normal file
@@ -0,0 +1,289 @@
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Checkbox Widget
|
||||
-------------------------------------------------------------------------------]]
|
||||
local Type, Version = "CheckBox", 21
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local select, pairs = select, pairs
|
||||
|
||||
-- WoW APIs
|
||||
local PlaySound = PlaySound
|
||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||
|
||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||
-- List them here for Mikk's FindGlobals script
|
||||
-- GLOBALS: SetDesaturation, GameFontHighlight
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Support functions
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function AlignImage(self)
|
||||
local img = self.image:GetTexture()
|
||||
self.text:ClearAllPoints()
|
||||
if not img then
|
||||
self.text:SetPoint("LEFT", self.checkbg, "RIGHT")
|
||||
self.text:SetPoint("RIGHT")
|
||||
else
|
||||
self.text:SetPoint("LEFT", self.image,"RIGHT", 1, 0)
|
||||
self.text:SetPoint("RIGHT")
|
||||
end
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Control_OnEnter(frame)
|
||||
frame.obj:Fire("OnEnter")
|
||||
end
|
||||
|
||||
local function Control_OnLeave(frame)
|
||||
frame.obj:Fire("OnLeave")
|
||||
end
|
||||
|
||||
local function CheckBox_OnMouseDown(frame)
|
||||
local self = frame.obj
|
||||
if not self.disabled then
|
||||
if self.image:GetTexture() then
|
||||
self.text:SetPoint("LEFT", self.image,"RIGHT", 2, -1)
|
||||
else
|
||||
self.text:SetPoint("LEFT", self.checkbg, "RIGHT", 1, -1)
|
||||
end
|
||||
end
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function CheckBox_OnMouseUp(frame)
|
||||
local self = frame.obj
|
||||
if not self.disabled then
|
||||
self:ToggleChecked()
|
||||
|
||||
if self.checked then
|
||||
PlaySound("igMainMenuOptionCheckBoxOn")
|
||||
else -- for both nil and false (tristate)
|
||||
PlaySound("igMainMenuOptionCheckBoxOff")
|
||||
end
|
||||
|
||||
self:Fire("OnValueChanged", self.checked)
|
||||
AlignImage(self)
|
||||
end
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self:SetType()
|
||||
self:SetValue(false)
|
||||
self:SetTriState(nil)
|
||||
-- height is calculated from the width and required space for the description
|
||||
self:SetWidth(200)
|
||||
self:SetImage()
|
||||
self:SetDisabled(nil)
|
||||
self:SetDescription(nil)
|
||||
end,
|
||||
|
||||
-- ["OnRelease"] = nil,
|
||||
|
||||
["OnWidthSet"] = function(self, width)
|
||||
if self.desc then
|
||||
self.desc:SetWidth(width - 30)
|
||||
if self.desc:GetText() and self.desc:GetText() ~= "" then
|
||||
self:SetHeight(28 + self.desc:GetHeight())
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
["SetDisabled"] = function(self, disabled)
|
||||
self.disabled = disabled
|
||||
if disabled then
|
||||
self.frame:Disable()
|
||||
self.text:SetTextColor(0.5, 0.5, 0.5)
|
||||
SetDesaturation(self.check, true)
|
||||
else
|
||||
self.frame:Enable()
|
||||
self.text:SetTextColor(1, 1, 1)
|
||||
if self.tristate and self.checked == nil then
|
||||
SetDesaturation(self.check, true)
|
||||
else
|
||||
SetDesaturation(self.check, false)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
["SetValue"] = function(self,value)
|
||||
local check = self.check
|
||||
self.checked = value
|
||||
if value then
|
||||
SetDesaturation(self.check, false)
|
||||
self.check:Show()
|
||||
else
|
||||
--Nil is the unknown tristate value
|
||||
if self.tristate and value == nil then
|
||||
SetDesaturation(self.check, true)
|
||||
self.check:Show()
|
||||
else
|
||||
SetDesaturation(self.check, false)
|
||||
self.check:Hide()
|
||||
end
|
||||
end
|
||||
self:SetDisabled(self.disabled)
|
||||
end,
|
||||
|
||||
["GetValue"] = function(self)
|
||||
return self.checked
|
||||
end,
|
||||
|
||||
["SetTriState"] = function(self, enabled)
|
||||
self.tristate = enabled
|
||||
self:SetValue(self:GetValue())
|
||||
end,
|
||||
|
||||
["SetType"] = function(self, type)
|
||||
local checkbg = self.checkbg
|
||||
local check = self.check
|
||||
local highlight = self.highlight
|
||||
|
||||
local size
|
||||
if type == "radio" then
|
||||
size = 16
|
||||
checkbg:SetTexture("Interface\\Buttons\\UI-RadioButton")
|
||||
checkbg:SetTexCoord(0, 0.25, 0, 1)
|
||||
check:SetTexture("Interface\\Buttons\\UI-RadioButton")
|
||||
check:SetTexCoord(0.25, 0.5, 0, 1)
|
||||
check:SetBlendMode("ADD")
|
||||
highlight:SetTexture("Interface\\Buttons\\UI-RadioButton")
|
||||
highlight:SetTexCoord(0.5, 0.75, 0, 1)
|
||||
else
|
||||
size = 24
|
||||
checkbg:SetTexture("Interface\\Buttons\\UI-CheckBox-Up")
|
||||
checkbg:SetTexCoord(0, 1, 0, 1)
|
||||
check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
|
||||
check:SetTexCoord(0, 1, 0, 1)
|
||||
check:SetBlendMode("BLEND")
|
||||
highlight:SetTexture("Interface\\Buttons\\UI-CheckBox-Highlight")
|
||||
highlight:SetTexCoord(0, 1, 0, 1)
|
||||
end
|
||||
checkbg:SetHeight(size)
|
||||
checkbg:SetWidth(size)
|
||||
end,
|
||||
|
||||
["ToggleChecked"] = function(self)
|
||||
local value = self:GetValue()
|
||||
if self.tristate then
|
||||
--cycle in true, nil, false order
|
||||
if value then
|
||||
self:SetValue(nil)
|
||||
elseif value == nil then
|
||||
self:SetValue(false)
|
||||
else
|
||||
self:SetValue(true)
|
||||
end
|
||||
else
|
||||
self:SetValue(not self:GetValue())
|
||||
end
|
||||
end,
|
||||
|
||||
["SetLabel"] = function(self, label)
|
||||
self.text:SetText(label)
|
||||
end,
|
||||
|
||||
["SetDescription"] = function(self, desc)
|
||||
if desc then
|
||||
if not self.desc then
|
||||
local desc = self.frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
|
||||
desc:ClearAllPoints()
|
||||
desc:SetPoint("TOPLEFT", self.checkbg, "TOPRIGHT", 5, -21)
|
||||
desc:SetWidth(self.frame.width - 30)
|
||||
desc:SetJustifyH("LEFT")
|
||||
desc:SetJustifyV("TOP")
|
||||
self.desc = desc
|
||||
end
|
||||
self.desc:Show()
|
||||
--self.text:SetFontObject(GameFontNormal)
|
||||
self.desc:SetText(desc)
|
||||
self:SetHeight(28 + self.desc:GetHeight())
|
||||
else
|
||||
if self.desc then
|
||||
self.desc:SetText("")
|
||||
self.desc:Hide()
|
||||
end
|
||||
--self.text:SetFontObject(GameFontHighlight)
|
||||
self:SetHeight(24)
|
||||
end
|
||||
end,
|
||||
|
||||
["SetImage"] = function(self, path, ...)
|
||||
local image = self.image
|
||||
image:SetTexture(path)
|
||||
|
||||
if image:GetTexture() then
|
||||
local n = select("#", ...)
|
||||
if n == 4 or n == 8 then
|
||||
image:SetTexCoord(...)
|
||||
else
|
||||
image:SetTexCoord(0, 1, 0, 1)
|
||||
end
|
||||
end
|
||||
AlignImage(self)
|
||||
end
|
||||
}
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Constructor()
|
||||
local frame = CreateFrame("Button", nil, UIParent)
|
||||
frame:Hide()
|
||||
|
||||
frame:EnableMouse(true)
|
||||
frame:SetScript("OnEnter", Control_OnEnter)
|
||||
frame:SetScript("OnLeave", Control_OnLeave)
|
||||
frame:SetScript("OnMouseDown", CheckBox_OnMouseDown)
|
||||
frame:SetScript("OnMouseUp", CheckBox_OnMouseUp)
|
||||
|
||||
local checkbg = frame:CreateTexture(nil, "ARTWORK")
|
||||
checkbg:SetWidth(24)
|
||||
checkbg:SetHeight(24)
|
||||
checkbg:SetPoint("TOPLEFT")
|
||||
checkbg:SetTexture("Interface\\Buttons\\UI-CheckBox-Up")
|
||||
|
||||
local check = frame:CreateTexture(nil, "OVERLAY")
|
||||
check:SetAllPoints(checkbg)
|
||||
check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
|
||||
|
||||
local text = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
|
||||
text:SetJustifyH("LEFT")
|
||||
text:SetHeight(18)
|
||||
text:SetPoint("LEFT", checkbg, "RIGHT")
|
||||
text:SetPoint("RIGHT")
|
||||
|
||||
local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
|
||||
highlight:SetTexture("Interface\\Buttons\\UI-CheckBox-Highlight")
|
||||
highlight:SetBlendMode("ADD")
|
||||
highlight:SetAllPoints(checkbg)
|
||||
|
||||
local image = frame:CreateTexture(nil, "OVERLAY")
|
||||
image:SetHeight(16)
|
||||
image:SetWidth(16)
|
||||
image:SetPoint("LEFT", checkbg, "RIGHT", 1, 0)
|
||||
|
||||
local widget = {
|
||||
checkbg = checkbg,
|
||||
check = check,
|
||||
text = text,
|
||||
highlight = highlight,
|
||||
image = image,
|
||||
frame = frame,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
|
||||
return AceGUI:RegisterAsWidget(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
186
MogIt/Libs/AceGUI-3.0/widgets/AceGUIWidget-ColorPicker.lua
Normal file
@@ -0,0 +1,186 @@
|
||||
--[[-----------------------------------------------------------------------------
|
||||
ColorPicker Widget
|
||||
-------------------------------------------------------------------------------]]
|
||||
local Type, Version = "ColorPicker", 20
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local pairs = pairs
|
||||
|
||||
-- WoW APIs
|
||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||
|
||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||
-- List them here for Mikk's FindGlobals script
|
||||
-- GLOBALS: ShowUIPanel, HideUIPanel, ColorPickerFrame, OpacitySliderFrame
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Support functions
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function ColorCallback(self, r, g, b, a, isAlpha)
|
||||
if not self.HasAlpha then
|
||||
a = 1
|
||||
end
|
||||
self:SetColor(r, g, b, a)
|
||||
if ColorPickerFrame:IsVisible() then
|
||||
--colorpicker is still open
|
||||
self:Fire("OnValueChanged", r, g, b, a)
|
||||
else
|
||||
--colorpicker is closed, color callback is first, ignore it,
|
||||
--alpha callback is the final call after it closes so confirm now
|
||||
if isAlpha then
|
||||
self:Fire("OnValueConfirmed", r, g, b, a)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Control_OnEnter(frame)
|
||||
frame.obj:Fire("OnEnter")
|
||||
end
|
||||
|
||||
local function Control_OnLeave(frame)
|
||||
frame.obj:Fire("OnLeave")
|
||||
end
|
||||
|
||||
local function ColorSwatch_OnClick(frame)
|
||||
HideUIPanel(ColorPickerFrame)
|
||||
local self = frame.obj
|
||||
if not self.disabled then
|
||||
ColorPickerFrame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
|
||||
ColorPickerFrame.func = function()
|
||||
local r, g, b = ColorPickerFrame:GetColorRGB()
|
||||
local a = 1 - OpacitySliderFrame:GetValue()
|
||||
ColorCallback(self, r, g, b, a)
|
||||
end
|
||||
|
||||
ColorPickerFrame.hasOpacity = self.HasAlpha
|
||||
ColorPickerFrame.opacityFunc = function()
|
||||
local r, g, b = ColorPickerFrame:GetColorRGB()
|
||||
local a = 1 - OpacitySliderFrame:GetValue()
|
||||
ColorCallback(self, r, g, b, a, true)
|
||||
end
|
||||
|
||||
local r, g, b, a = self.r, self.g, self.b, self.a
|
||||
if self.HasAlpha then
|
||||
ColorPickerFrame.opacity = 1 - (a or 0)
|
||||
end
|
||||
ColorPickerFrame:SetColorRGB(r, g, b)
|
||||
|
||||
ColorPickerFrame.cancelFunc = function()
|
||||
ColorCallback(self, r, g, b, a, true)
|
||||
end
|
||||
|
||||
ShowUIPanel(ColorPickerFrame)
|
||||
end
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self:SetHeight(24)
|
||||
self:SetWidth(200)
|
||||
self:SetHasAlpha(false)
|
||||
self:SetColor(0, 0, 0, 1)
|
||||
self:SetDisabled(nil)
|
||||
self:SetLabel(nil)
|
||||
end,
|
||||
|
||||
-- ["OnRelease"] = nil,
|
||||
|
||||
["SetLabel"] = function(self, text)
|
||||
self.text:SetText(text)
|
||||
end,
|
||||
|
||||
["SetColor"] = function(self, r, g, b, a)
|
||||
self.r = r
|
||||
self.g = g
|
||||
self.b = b
|
||||
self.a = a or 1
|
||||
self.colorSwatch:SetVertexColor(r, g, b, a)
|
||||
end,
|
||||
|
||||
["SetHasAlpha"] = function(self, HasAlpha)
|
||||
self.HasAlpha = HasAlpha
|
||||
end,
|
||||
|
||||
["SetDisabled"] = function(self, disabled)
|
||||
self.disabled = disabled
|
||||
if self.disabled then
|
||||
self.frame:Disable()
|
||||
self.text:SetTextColor(0.5, 0.5, 0.5)
|
||||
else
|
||||
self.frame:Enable()
|
||||
self.text:SetTextColor(1, 1, 1)
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Constructor()
|
||||
local frame = CreateFrame("Button", nil, UIParent)
|
||||
frame:Hide()
|
||||
|
||||
frame:EnableMouse(true)
|
||||
frame:SetScript("OnEnter", Control_OnEnter)
|
||||
frame:SetScript("OnLeave", Control_OnLeave)
|
||||
frame:SetScript("OnClick", ColorSwatch_OnClick)
|
||||
|
||||
local colorSwatch = frame:CreateTexture(nil, "OVERLAY")
|
||||
colorSwatch:SetWidth(19)
|
||||
colorSwatch:SetHeight(19)
|
||||
colorSwatch:SetTexture("Interface\\ChatFrame\\ChatFrameColorSwatch")
|
||||
colorSwatch:SetPoint("LEFT")
|
||||
|
||||
local texture = frame:CreateTexture(nil, "BACKGROUND")
|
||||
texture:SetWidth(16)
|
||||
texture:SetHeight(16)
|
||||
texture:SetTexture(1, 1, 1)
|
||||
texture:SetPoint("CENTER", colorSwatch)
|
||||
texture:Show()
|
||||
|
||||
local checkers = frame:CreateTexture(nil, "BACKGROUND")
|
||||
checkers:SetWidth(14)
|
||||
checkers:SetHeight(14)
|
||||
checkers:SetTexture("Tileset\\Generic\\Checkers")
|
||||
checkers:SetTexCoord(.25, 0, 0.5, .25)
|
||||
checkers:SetDesaturated(true)
|
||||
checkers:SetVertexColor(1, 1, 1, 0.75)
|
||||
checkers:SetPoint("CENTER", colorSwatch)
|
||||
checkers:Show()
|
||||
|
||||
local text = frame:CreateFontString(nil,"OVERLAY","GameFontHighlight")
|
||||
text:SetHeight(24)
|
||||
text:SetJustifyH("LEFT")
|
||||
text:SetTextColor(1, 1, 1)
|
||||
text:SetPoint("LEFT", colorSwatch, "RIGHT", 2, 0)
|
||||
text:SetPoint("RIGHT")
|
||||
|
||||
--local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
|
||||
--highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
|
||||
--highlight:SetBlendMode("ADD")
|
||||
--highlight:SetAllPoints(frame)
|
||||
|
||||
local widget = {
|
||||
colorSwatch = colorSwatch,
|
||||
text = text,
|
||||
frame = frame,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
|
||||
return AceGUI:RegisterAsWidget(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
465
MogIt/Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown-Items.lua
Normal file
@@ -0,0 +1,465 @@
|
||||
--[[ $Id: AceGUIWidget-DropDown-Items.lua 916 2010-03-15 12:24:36Z nevcairiel $ ]]--
|
||||
|
||||
local AceGUI = LibStub("AceGUI-3.0")
|
||||
|
||||
-- Lua APIs
|
||||
local select, assert = select, assert
|
||||
|
||||
-- WoW APIs
|
||||
local PlaySound = PlaySound
|
||||
local CreateFrame = CreateFrame
|
||||
|
||||
local function fixlevels(parent,...)
|
||||
local i = 1
|
||||
local child = select(i, ...)
|
||||
while child do
|
||||
child:SetFrameLevel(parent:GetFrameLevel()+1)
|
||||
fixlevels(child, child:GetChildren())
|
||||
i = i + 1
|
||||
child = select(i, ...)
|
||||
end
|
||||
end
|
||||
|
||||
local function fixstrata(strata, parent, ...)
|
||||
local i = 1
|
||||
local child = select(i, ...)
|
||||
parent:SetFrameStrata(strata)
|
||||
while child do
|
||||
fixstrata(strata, child, child:GetChildren())
|
||||
i = i + 1
|
||||
child = select(i, ...)
|
||||
end
|
||||
end
|
||||
|
||||
-- ItemBase is the base "class" for all dropdown items.
|
||||
-- Each item has to use ItemBase.Create(widgetType) to
|
||||
-- create an initial 'self' value.
|
||||
-- ItemBase will add common functions and ui event handlers.
|
||||
-- Be sure to keep basic usage when you override functions.
|
||||
|
||||
local ItemBase = {
|
||||
-- NOTE: The ItemBase version is added to each item's version number
|
||||
-- to ensure proper updates on ItemBase changes.
|
||||
-- Use at least 1000er steps.
|
||||
version = 1000,
|
||||
counter = 0,
|
||||
}
|
||||
|
||||
function ItemBase.Frame_OnEnter(this)
|
||||
local self = this.obj
|
||||
|
||||
if self.useHighlight then
|
||||
self.highlight:Show()
|
||||
end
|
||||
self:Fire("OnEnter")
|
||||
|
||||
if self.specialOnEnter then
|
||||
self.specialOnEnter(self)
|
||||
end
|
||||
end
|
||||
|
||||
function ItemBase.Frame_OnLeave(this)
|
||||
local self = this.obj
|
||||
|
||||
self.highlight:Hide()
|
||||
self:Fire("OnLeave")
|
||||
|
||||
if self.specialOnLeave then
|
||||
self.specialOnLeave(self)
|
||||
end
|
||||
end
|
||||
|
||||
-- exported, AceGUI callback
|
||||
function ItemBase.OnAcquire(self)
|
||||
self.frame:SetToplevel(true)
|
||||
self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
end
|
||||
|
||||
-- exported, AceGUI callback
|
||||
function ItemBase.OnRelease(self)
|
||||
self:SetDisabled(false)
|
||||
self.pullout = nil
|
||||
self.frame:SetParent(nil)
|
||||
self.frame:ClearAllPoints()
|
||||
self.frame:Hide()
|
||||
end
|
||||
|
||||
-- exported
|
||||
-- NOTE: this is called by a Dropdown-Pullout.
|
||||
-- Do not call this method directly
|
||||
function ItemBase.SetPullout(self, pullout)
|
||||
self.pullout = pullout
|
||||
|
||||
self.frame:SetParent(nil)
|
||||
self.frame:SetParent(pullout.itemFrame)
|
||||
self.parent = pullout.itemFrame
|
||||
fixlevels(pullout.itemFrame, pullout.itemFrame:GetChildren())
|
||||
end
|
||||
|
||||
-- exported
|
||||
function ItemBase.SetText(self, text)
|
||||
self.text:SetText(text or "")
|
||||
end
|
||||
|
||||
-- exported
|
||||
function ItemBase.GetText(self)
|
||||
return self.text:GetText()
|
||||
end
|
||||
|
||||
-- exported
|
||||
function ItemBase.SetPoint(self, ...)
|
||||
self.frame:SetPoint(...)
|
||||
end
|
||||
|
||||
-- exported
|
||||
function ItemBase.Show(self)
|
||||
self.frame:Show()
|
||||
end
|
||||
|
||||
-- exported
|
||||
function ItemBase.Hide(self)
|
||||
self.frame:Hide()
|
||||
end
|
||||
|
||||
-- exported
|
||||
function ItemBase.SetDisabled(self, disabled)
|
||||
self.disabled = disabled
|
||||
if disabled then
|
||||
self.useHighlight = false
|
||||
self.text:SetTextColor(.5, .5, .5)
|
||||
else
|
||||
self.useHighlight = true
|
||||
self.text:SetTextColor(1, 1, 1)
|
||||
end
|
||||
end
|
||||
|
||||
-- exported
|
||||
-- NOTE: this is called by a Dropdown-Pullout.
|
||||
-- Do not call this method directly
|
||||
function ItemBase.SetOnLeave(self, func)
|
||||
self.specialOnLeave = func
|
||||
end
|
||||
|
||||
-- exported
|
||||
-- NOTE: this is called by a Dropdown-Pullout.
|
||||
-- Do not call this method directly
|
||||
function ItemBase.SetOnEnter(self, func)
|
||||
self.specialOnEnter = func
|
||||
end
|
||||
|
||||
function ItemBase.Create(type)
|
||||
-- NOTE: Most of the following code is copied from AceGUI-3.0/Dropdown widget
|
||||
local count = AceGUI:GetNextWidgetNum(type)
|
||||
local frame = CreateFrame("Button", "AceGUI30DropDownItem"..count)
|
||||
local self = {}
|
||||
self.frame = frame
|
||||
frame.obj = self
|
||||
self.type = type
|
||||
|
||||
self.useHighlight = true
|
||||
|
||||
frame:SetHeight(17)
|
||||
frame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
|
||||
local text = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
|
||||
text:SetTextColor(1,1,1)
|
||||
text:SetJustifyH("LEFT")
|
||||
text:SetPoint("TOPLEFT",frame,"TOPLEFT",18,0)
|
||||
text:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-8,0)
|
||||
self.text = text
|
||||
|
||||
local highlight = frame:CreateTexture(nil, "OVERLAY")
|
||||
highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
|
||||
highlight:SetBlendMode("ADD")
|
||||
highlight:SetHeight(14)
|
||||
highlight:ClearAllPoints()
|
||||
highlight:SetPoint("RIGHT",frame,"RIGHT",-3,0)
|
||||
highlight:SetPoint("LEFT",frame,"LEFT",5,0)
|
||||
highlight:Hide()
|
||||
self.highlight = highlight
|
||||
|
||||
local check = frame:CreateTexture("OVERLAY")
|
||||
check:SetWidth(16)
|
||||
check:SetHeight(16)
|
||||
check:SetPoint("LEFT",frame,"LEFT",3,-1)
|
||||
check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
|
||||
check:Hide()
|
||||
self.check = check
|
||||
|
||||
local sub = frame:CreateTexture("OVERLAY")
|
||||
sub:SetWidth(16)
|
||||
sub:SetHeight(16)
|
||||
sub:SetPoint("RIGHT",frame,"RIGHT",-3,-1)
|
||||
sub:SetTexture("Interface\\ChatFrame\\ChatFrameExpandArrow")
|
||||
sub:Hide()
|
||||
self.sub = sub
|
||||
|
||||
frame:SetScript("OnEnter", ItemBase.Frame_OnEnter)
|
||||
frame:SetScript("OnLeave", ItemBase.Frame_OnLeave)
|
||||
|
||||
self.OnAcquire = ItemBase.OnAcquire
|
||||
self.OnRelease = ItemBase.OnRelease
|
||||
|
||||
self.SetPullout = ItemBase.SetPullout
|
||||
self.GetText = ItemBase.GetText
|
||||
self.SetText = ItemBase.SetText
|
||||
self.SetDisabled = ItemBase.SetDisabled
|
||||
|
||||
self.SetPoint = ItemBase.SetPoint
|
||||
self.Show = ItemBase.Show
|
||||
self.Hide = ItemBase.Hide
|
||||
|
||||
self.SetOnLeave = ItemBase.SetOnLeave
|
||||
self.SetOnEnter = ItemBase.SetOnEnter
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--[[
|
||||
Template for items:
|
||||
|
||||
-- Item:
|
||||
--
|
||||
do
|
||||
local widgetType = "Dropdown-Item-"
|
||||
local widgetVersion = 1
|
||||
|
||||
local function Constructor()
|
||||
local self = ItemBase.Create(widgetType)
|
||||
|
||||
AceGUI:RegisterAsWidget(self)
|
||||
return self
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
|
||||
end
|
||||
--]]
|
||||
|
||||
-- Item: Header
|
||||
-- A single text entry.
|
||||
-- Special: Different text color and no highlight
|
||||
do
|
||||
local widgetType = "Dropdown-Item-Header"
|
||||
local widgetVersion = 1
|
||||
|
||||
local function OnEnter(this)
|
||||
local self = this.obj
|
||||
self:Fire("OnEnter")
|
||||
|
||||
if self.specialOnEnter then
|
||||
self.specialOnEnter(self)
|
||||
end
|
||||
end
|
||||
|
||||
local function OnLeave(this)
|
||||
local self = this.obj
|
||||
self:Fire("OnLeave")
|
||||
|
||||
if self.specialOnLeave then
|
||||
self.specialOnLeave(self)
|
||||
end
|
||||
end
|
||||
|
||||
-- exported, override
|
||||
local function SetDisabled(self, disabled)
|
||||
ItemBase.SetDisabled(self, disabled)
|
||||
if not disabled then
|
||||
self.text:SetTextColor(1, 1, 0)
|
||||
end
|
||||
end
|
||||
|
||||
local function Constructor()
|
||||
local self = ItemBase.Create(widgetType)
|
||||
|
||||
self.SetDisabled = SetDisabled
|
||||
|
||||
self.frame:SetScript("OnEnter", OnEnter)
|
||||
self.frame:SetScript("OnLeave", OnLeave)
|
||||
|
||||
self.text:SetTextColor(1, 1, 0)
|
||||
|
||||
AceGUI:RegisterAsWidget(self)
|
||||
return self
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
|
||||
end
|
||||
|
||||
-- Item: Execute
|
||||
-- A simple button
|
||||
do
|
||||
local widgetType = "Dropdown-Item-Execute"
|
||||
local widgetVersion = 1
|
||||
|
||||
local function Frame_OnClick(this, button)
|
||||
local self = this.obj
|
||||
if self.disabled then return end
|
||||
self:Fire("OnClick")
|
||||
if self.pullout then
|
||||
self.pullout:Close()
|
||||
end
|
||||
end
|
||||
|
||||
local function Constructor()
|
||||
local self = ItemBase.Create(widgetType)
|
||||
|
||||
self.frame:SetScript("OnClick", Frame_OnClick)
|
||||
|
||||
AceGUI:RegisterAsWidget(self)
|
||||
return self
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
|
||||
end
|
||||
|
||||
-- Item: Toggle
|
||||
-- Some sort of checkbox for dropdown menus.
|
||||
-- Does not close the pullout on click.
|
||||
do
|
||||
local widgetType = "Dropdown-Item-Toggle"
|
||||
local widgetVersion = 3
|
||||
|
||||
local function UpdateToggle(self)
|
||||
if self.value then
|
||||
self.check:Show()
|
||||
else
|
||||
self.check:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
local function OnRelease(self)
|
||||
ItemBase.OnRelease(self)
|
||||
self:SetValue(nil)
|
||||
end
|
||||
|
||||
local function Frame_OnClick(this, button)
|
||||
local self = this.obj
|
||||
if self.disabled then return end
|
||||
self.value = not self.value
|
||||
if self.value then
|
||||
PlaySound("igMainMenuOptionCheckBoxOn")
|
||||
else
|
||||
PlaySound("igMainMenuOptionCheckBoxOff")
|
||||
end
|
||||
UpdateToggle(self)
|
||||
self:Fire("OnValueChanged", self.value)
|
||||
end
|
||||
|
||||
-- exported
|
||||
local function SetValue(self, value)
|
||||
self.value = value
|
||||
UpdateToggle(self)
|
||||
end
|
||||
|
||||
-- exported
|
||||
local function GetValue(self)
|
||||
return self.value
|
||||
end
|
||||
|
||||
local function Constructor()
|
||||
local self = ItemBase.Create(widgetType)
|
||||
|
||||
self.frame:SetScript("OnClick", Frame_OnClick)
|
||||
|
||||
self.SetValue = SetValue
|
||||
self.GetValue = GetValue
|
||||
self.OnRelease = OnRelease
|
||||
|
||||
AceGUI:RegisterAsWidget(self)
|
||||
return self
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
|
||||
end
|
||||
|
||||
-- Item: Menu
|
||||
-- Shows a submenu on mouse over
|
||||
-- Does not close the pullout on click
|
||||
do
|
||||
local widgetType = "Dropdown-Item-Menu"
|
||||
local widgetVersion = 2
|
||||
|
||||
local function OnEnter(this)
|
||||
local self = this.obj
|
||||
self:Fire("OnEnter")
|
||||
|
||||
if self.specialOnEnter then
|
||||
self.specialOnEnter(self)
|
||||
end
|
||||
|
||||
self.highlight:Show()
|
||||
|
||||
if not self.disabled and self.submenu then
|
||||
self.submenu:Open("TOPLEFT", self.frame, "TOPRIGHT", self.pullout:GetRightBorderWidth(), 0, self.frame:GetFrameLevel() + 100)
|
||||
end
|
||||
end
|
||||
|
||||
local function OnHide(this)
|
||||
local self = this.obj
|
||||
if self.submenu then
|
||||
self.submenu:Close()
|
||||
end
|
||||
end
|
||||
|
||||
-- exported
|
||||
local function SetMenu(self, menu)
|
||||
assert(menu.type == "Dropdown-Pullout")
|
||||
self.submenu = menu
|
||||
end
|
||||
|
||||
-- exported
|
||||
local function CloseMenu(self)
|
||||
self.submenu:Close()
|
||||
end
|
||||
|
||||
local function Constructor()
|
||||
local self = ItemBase.Create(widgetType)
|
||||
|
||||
self.sub:Show()
|
||||
|
||||
self.frame:SetScript("OnEnter", OnEnter)
|
||||
self.frame:SetScript("OnHide", OnHide)
|
||||
|
||||
self.SetMenu = SetMenu
|
||||
self.CloseMenu = CloseMenu
|
||||
|
||||
AceGUI:RegisterAsWidget(self)
|
||||
return self
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
|
||||
end
|
||||
|
||||
-- Item: Separator
|
||||
-- A single line to separate items
|
||||
do
|
||||
local widgetType = "Dropdown-Item-Separator"
|
||||
local widgetVersion = 1
|
||||
|
||||
-- exported, override
|
||||
local function SetDisabled(self, disabled)
|
||||
ItemBase.SetDisabled(self, disabled)
|
||||
self.useHighlight = false
|
||||
end
|
||||
|
||||
local function Constructor()
|
||||
local self = ItemBase.Create(widgetType)
|
||||
|
||||
self.SetDisabled = SetDisabled
|
||||
|
||||
local line = self.frame:CreateTexture(nil, "OVERLAY")
|
||||
line:SetHeight(1)
|
||||
line:SetTexture(.5, .5, .5)
|
||||
line:SetPoint("LEFT", self.frame, "LEFT", 10, 0)
|
||||
line:SetPoint("RIGHT", self.frame, "RIGHT", -10, 0)
|
||||
|
||||
self.text:Hide()
|
||||
|
||||
self.useHighlight = false
|
||||
|
||||
AceGUI:RegisterAsWidget(self)
|
||||
return self
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version)
|
||||
end
|
||||
707
MogIt/Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown.lua
Normal file
@@ -0,0 +1,707 @@
|
||||
--[[ $Id: AceGUIWidget-DropDown.lua 916 2010-03-15 12:24:36Z nevcairiel $ ]]--
|
||||
local AceGUI = LibStub("AceGUI-3.0")
|
||||
|
||||
-- Lua APIs
|
||||
local min, max, floor = math.min, math.max, math.floor
|
||||
local select, pairs, ipairs = select, pairs, ipairs
|
||||
local tsort = table.sort
|
||||
|
||||
-- WoW APIs
|
||||
local PlaySound = PlaySound
|
||||
local UIParent, CreateFrame = UIParent, CreateFrame
|
||||
local _G = _G
|
||||
|
||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||
-- List them here for Mikk's FindGlobals script
|
||||
-- GLOBALS: CLOSE
|
||||
|
||||
local function fixlevels(parent,...)
|
||||
local i = 1
|
||||
local child = select(i, ...)
|
||||
while child do
|
||||
child:SetFrameLevel(parent:GetFrameLevel()+1)
|
||||
fixlevels(child, child:GetChildren())
|
||||
i = i + 1
|
||||
child = select(i, ...)
|
||||
end
|
||||
end
|
||||
|
||||
local function fixstrata(strata, parent, ...)
|
||||
local i = 1
|
||||
local child = select(i, ...)
|
||||
parent:SetFrameStrata(strata)
|
||||
while child do
|
||||
fixstrata(strata, child, child:GetChildren())
|
||||
i = i + 1
|
||||
child = select(i, ...)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local widgetType = "Dropdown-Pullout"
|
||||
local widgetVersion = 3
|
||||
|
||||
--[[ Static data ]]--
|
||||
|
||||
local backdrop = {
|
||||
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
|
||||
edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
|
||||
edgeSize = 32,
|
||||
tileSize = 32,
|
||||
tile = true,
|
||||
insets = { left = 11, right = 12, top = 12, bottom = 11 },
|
||||
}
|
||||
local sliderBackdrop = {
|
||||
bgFile = "Interface\\Buttons\\UI-SliderBar-Background",
|
||||
edgeFile = "Interface\\Buttons\\UI-SliderBar-Border",
|
||||
tile = true, tileSize = 8, edgeSize = 8,
|
||||
insets = { left = 3, right = 3, top = 3, bottom = 3 }
|
||||
}
|
||||
|
||||
local defaultWidth = 200
|
||||
local defaultMaxHeight = 600
|
||||
|
||||
--[[ UI Event Handlers ]]--
|
||||
|
||||
-- HACK: This should be no part of the pullout, but there
|
||||
-- is no other 'clean' way to response to any item-OnEnter
|
||||
-- Used to close Submenus when an other item is entered
|
||||
local function OnEnter(item)
|
||||
local self = item.pullout
|
||||
for k, v in ipairs(self.items) do
|
||||
if v.CloseMenu and v ~= item then
|
||||
v:CloseMenu()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- See the note in Constructor() for each scroll related function
|
||||
local function OnMouseWheel(this, value)
|
||||
this.obj:MoveScroll(value)
|
||||
end
|
||||
|
||||
local function OnScrollValueChanged(this, value)
|
||||
this.obj:SetScroll(value)
|
||||
end
|
||||
|
||||
local function OnSizeChanged(this)
|
||||
this.obj:FixScroll()
|
||||
end
|
||||
|
||||
--[[ Exported methods ]]--
|
||||
|
||||
-- exported
|
||||
local function SetScroll(self, value)
|
||||
local status = self.scrollStatus
|
||||
local frame, child = self.scrollFrame, self.itemFrame
|
||||
local height, viewheight = frame:GetHeight(), child:GetHeight()
|
||||
|
||||
local offset
|
||||
if height > viewheight then
|
||||
offset = 0
|
||||
else
|
||||
offset = floor((viewheight - height) / 1000 * value)
|
||||
end
|
||||
child:ClearAllPoints()
|
||||
child:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, offset)
|
||||
child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", self.slider:IsShown() and -12 or 0, offset)
|
||||
status.offset = offset
|
||||
status.scrollvalue = value
|
||||
end
|
||||
|
||||
-- exported
|
||||
local function MoveScroll(self, value)
|
||||
local status = self.scrollStatus
|
||||
local frame, child = self.scrollFrame, self.itemFrame
|
||||
local height, viewheight = frame:GetHeight(), child:GetHeight()
|
||||
|
||||
if height > viewheight then
|
||||
self.slider:Hide()
|
||||
else
|
||||
self.slider:Show()
|
||||
local diff = height - viewheight
|
||||
local delta = 1
|
||||
if value < 0 then
|
||||
delta = -1
|
||||
end
|
||||
self.slider:SetValue(min(max(status.scrollvalue + delta*(1000/(diff/45)),0), 1000))
|
||||
end
|
||||
end
|
||||
|
||||
-- exported
|
||||
local function FixScroll(self)
|
||||
local status = self.scrollStatus
|
||||
local frame, child = self.scrollFrame, self.itemFrame
|
||||
local height, viewheight = frame:GetHeight(), child:GetHeight()
|
||||
local offset = status.offset or 0
|
||||
|
||||
if viewheight < height then
|
||||
self.slider:Hide()
|
||||
child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, offset)
|
||||
self.slider:SetValue(0)
|
||||
else
|
||||
self.slider:Show()
|
||||
local value = (offset / (viewheight - height) * 1000)
|
||||
if value > 1000 then value = 1000 end
|
||||
self.slider:SetValue(value)
|
||||
self:SetScroll(value)
|
||||
if value < 1000 then
|
||||
child:ClearAllPoints()
|
||||
child:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, offset)
|
||||
child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -12, offset)
|
||||
status.offset = offset
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- exported, AceGUI callback
|
||||
local function OnAcquire(self)
|
||||
self.frame:SetParent(UIParent)
|
||||
--self.itemFrame:SetToplevel(true)
|
||||
end
|
||||
|
||||
-- exported, AceGUI callback
|
||||
local function OnRelease(self)
|
||||
self:Clear()
|
||||
self.frame:ClearAllPoints()
|
||||
self.frame:Hide()
|
||||
end
|
||||
|
||||
-- exported
|
||||
local function AddItem(self, item)
|
||||
self.items[#self.items + 1] = item
|
||||
|
||||
local h = #self.items * 16
|
||||
self.itemFrame:SetHeight(h)
|
||||
self.frame:SetHeight(min(h + 34, self.maxHeight)) -- +34: 20 for scrollFrame placement (10 offset) and +14 for item placement
|
||||
|
||||
item.frame:SetPoint("LEFT", self.itemFrame, "LEFT")
|
||||
item.frame:SetPoint("RIGHT", self.itemFrame, "RIGHT")
|
||||
|
||||
item:SetPullout(self)
|
||||
item:SetOnEnter(OnEnter)
|
||||
end
|
||||
|
||||
-- exported
|
||||
local function Open(self, point, relFrame, relPoint, x, y)
|
||||
local items = self.items
|
||||
local frame = self.frame
|
||||
local itemFrame = self.itemFrame
|
||||
|
||||
frame:SetPoint(point, relFrame, relPoint, x, y)
|
||||
|
||||
|
||||
local height = 8
|
||||
for i, item in pairs(items) do
|
||||
if i == 1 then
|
||||
item:SetPoint("TOP", itemFrame, "TOP", 0, -2)
|
||||
else
|
||||
item:SetPoint("TOP", items[i-1].frame, "BOTTOM", 0, 1)
|
||||
end
|
||||
|
||||
item:Show()
|
||||
|
||||
height = height + 16
|
||||
end
|
||||
itemFrame:SetHeight(height)
|
||||
fixstrata("TOOLTIP", frame, frame:GetChildren())
|
||||
frame:Show()
|
||||
self:Fire("OnOpen")
|
||||
end
|
||||
|
||||
-- exported
|
||||
local function Close(self)
|
||||
self.frame:Hide()
|
||||
self:Fire("OnClose")
|
||||
end
|
||||
|
||||
-- exported
|
||||
local function Clear(self)
|
||||
local items = self.items
|
||||
for i, item in pairs(items) do
|
||||
AceGUI:Release(item)
|
||||
items[i] = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- exported
|
||||
local function IterateItems(self)
|
||||
return ipairs(self.items)
|
||||
end
|
||||
|
||||
-- exported
|
||||
local function SetHideOnLeave(self, val)
|
||||
self.hideOnLeave = val
|
||||
end
|
||||
|
||||
-- exported
|
||||
local function SetMaxHeight(self, height)
|
||||
self.maxHeight = height or defaultMaxHeight
|
||||
if self.frame:GetHeight() > height then
|
||||
self.frame:SetHeight(height)
|
||||
elseif (self.itemFrame:GetHeight() + 34) < height then
|
||||
self.frame:SetHeight(self.itemFrame:GetHeight() + 34) -- see :AddItem
|
||||
end
|
||||
end
|
||||
|
||||
-- exported
|
||||
local function GetRightBorderWidth(self)
|
||||
return 6 + (self.slider:IsShown() and 12 or 0)
|
||||
end
|
||||
|
||||
-- exported
|
||||
local function GetLeftBorderWidth(self)
|
||||
return 6
|
||||
end
|
||||
|
||||
--[[ Constructor ]]--
|
||||
|
||||
local function Constructor()
|
||||
local count = AceGUI:GetNextWidgetNum(widgetType)
|
||||
local frame = CreateFrame("Frame", "AceGUI30Pullout"..count, UIParent)
|
||||
local self = {}
|
||||
self.count = count
|
||||
self.type = widgetType
|
||||
self.frame = frame
|
||||
frame.obj = self
|
||||
|
||||
self.OnAcquire = OnAcquire
|
||||
self.OnRelease = OnRelease
|
||||
|
||||
self.AddItem = AddItem
|
||||
self.Open = Open
|
||||
self.Close = Close
|
||||
self.Clear = Clear
|
||||
self.IterateItems = IterateItems
|
||||
self.SetHideOnLeave = SetHideOnLeave
|
||||
|
||||
self.SetScroll = SetScroll
|
||||
self.MoveScroll = MoveScroll
|
||||
self.FixScroll = FixScroll
|
||||
|
||||
self.SetMaxHeight = SetMaxHeight
|
||||
self.GetRightBorderWidth = GetRightBorderWidth
|
||||
self.GetLeftBorderWidth = GetLeftBorderWidth
|
||||
|
||||
self.items = {}
|
||||
|
||||
self.scrollStatus = {
|
||||
scrollvalue = 0,
|
||||
}
|
||||
|
||||
self.maxHeight = defaultMaxHeight
|
||||
|
||||
frame:SetBackdrop(backdrop)
|
||||
frame:SetBackdropColor(0, 0, 0)
|
||||
frame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
frame:SetClampedToScreen(true)
|
||||
frame:SetWidth(defaultWidth)
|
||||
frame:SetHeight(self.maxHeight)
|
||||
--frame:SetToplevel(true)
|
||||
|
||||
-- NOTE: The whole scroll frame code is copied from the AceGUI-3.0 widget ScrollFrame
|
||||
local scrollFrame = CreateFrame("ScrollFrame", nil, frame)
|
||||
local itemFrame = CreateFrame("Frame", nil, scrollFrame)
|
||||
|
||||
self.scrollFrame = scrollFrame
|
||||
self.itemFrame = itemFrame
|
||||
|
||||
scrollFrame.obj = self
|
||||
itemFrame.obj = self
|
||||
|
||||
local slider = CreateFrame("Slider", "AceGUI30PulloutScrollbar"..count, scrollFrame)
|
||||
slider:SetOrientation("VERTICAL")
|
||||
slider:SetHitRectInsets(0, 0, -10, 0)
|
||||
slider:SetBackdrop(sliderBackdrop)
|
||||
slider:SetWidth(8)
|
||||
slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Vertical")
|
||||
slider:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
self.slider = slider
|
||||
slider.obj = self
|
||||
|
||||
scrollFrame:SetScrollChild(itemFrame)
|
||||
scrollFrame:SetPoint("TOPLEFT", frame, "TOPLEFT", 6, -12)
|
||||
scrollFrame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -6, 12)
|
||||
scrollFrame:EnableMouseWheel(true)
|
||||
scrollFrame:SetScript("OnMouseWheel", OnMouseWheel)
|
||||
scrollFrame:SetScript("OnSizeChanged", OnSizeChanged)
|
||||
scrollFrame:SetToplevel(true)
|
||||
scrollFrame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
|
||||
itemFrame:SetPoint("TOPLEFT", scrollFrame, "TOPLEFT", 0, 0)
|
||||
itemFrame:SetPoint("TOPRIGHT", scrollFrame, "TOPRIGHT", -12, 0)
|
||||
itemFrame:SetHeight(400)
|
||||
itemFrame:SetToplevel(true)
|
||||
itemFrame:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
|
||||
slider:SetPoint("TOPLEFT", scrollFrame, "TOPRIGHT", -16, 0)
|
||||
slider:SetPoint("BOTTOMLEFT", scrollFrame, "BOTTOMRIGHT", -16, 0)
|
||||
slider:SetScript("OnValueChanged", OnScrollValueChanged)
|
||||
slider:SetMinMaxValues(0, 1000)
|
||||
slider:SetValueStep(1)
|
||||
slider:SetValue(0)
|
||||
|
||||
scrollFrame:Show()
|
||||
itemFrame:Show()
|
||||
slider:Hide()
|
||||
|
||||
self:FixScroll()
|
||||
|
||||
AceGUI:RegisterAsWidget(self)
|
||||
return self
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion)
|
||||
end
|
||||
|
||||
do
|
||||
local widgetType = "Dropdown"
|
||||
local widgetVersion = 22
|
||||
|
||||
--[[ Static data ]]--
|
||||
|
||||
--[[ UI event handler ]]--
|
||||
|
||||
local function Control_OnEnter(this)
|
||||
this.obj:Fire("OnEnter")
|
||||
end
|
||||
|
||||
local function Control_OnLeave(this)
|
||||
this.obj:Fire("OnLeave")
|
||||
end
|
||||
|
||||
local function Dropdown_OnHide(this)
|
||||
local self = this.obj
|
||||
if self.open then
|
||||
self.pullout:Close()
|
||||
end
|
||||
end
|
||||
|
||||
local function Dropdown_TogglePullout(this)
|
||||
local self = this.obj
|
||||
PlaySound("igMainMenuOptionCheckBoxOn") -- missleading name, but the Blizzard code uses this sound
|
||||
if self.open then
|
||||
self.open = nil
|
||||
self.pullout:Close()
|
||||
AceGUI:ClearFocus()
|
||||
else
|
||||
self.open = true
|
||||
self.pullout:SetWidth(self.frame:GetWidth())
|
||||
self.pullout:Open("TOPLEFT", self.frame, "BOTTOMLEFT", 0, self.label:IsShown() and -2 or 0)
|
||||
AceGUI:SetFocus(self)
|
||||
end
|
||||
end
|
||||
|
||||
local function OnPulloutOpen(this)
|
||||
local self = this.userdata.obj
|
||||
local value = self.value
|
||||
|
||||
if not self.multiselect then
|
||||
for i, item in this:IterateItems() do
|
||||
item:SetValue(item.userdata.value == value)
|
||||
end
|
||||
end
|
||||
|
||||
self.open = true
|
||||
end
|
||||
|
||||
local function OnPulloutClose(this)
|
||||
local self = this.userdata.obj
|
||||
self.open = nil
|
||||
self:Fire("OnClosed")
|
||||
end
|
||||
|
||||
local function ShowMultiText(self)
|
||||
local text
|
||||
for i, widget in self.pullout:IterateItems() do
|
||||
if widget.type == "Dropdown-Item-Toggle" then
|
||||
if widget:GetValue() then
|
||||
if text then
|
||||
text = text..", "..widget:GetText()
|
||||
else
|
||||
text = widget:GetText()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
self:SetText(text)
|
||||
end
|
||||
|
||||
local function OnItemValueChanged(this, event, checked)
|
||||
local self = this.userdata.obj
|
||||
|
||||
if self.multiselect then
|
||||
self:Fire("OnValueChanged", this.userdata.value, checked)
|
||||
ShowMultiText(self)
|
||||
else
|
||||
if checked then
|
||||
self:SetValue(this.userdata.value)
|
||||
self:Fire("OnValueChanged", this.userdata.value)
|
||||
else
|
||||
this:SetValue(true)
|
||||
end
|
||||
if self.open then
|
||||
self.pullout:Close()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[ Exported methods ]]--
|
||||
|
||||
-- exported, AceGUI callback
|
||||
local function OnAcquire(self)
|
||||
local pullout = AceGUI:Create("Dropdown-Pullout")
|
||||
self.pullout = pullout
|
||||
pullout.userdata.obj = self
|
||||
pullout:SetCallback("OnClose", OnPulloutClose)
|
||||
pullout:SetCallback("OnOpen", OnPulloutOpen)
|
||||
self.pullout.frame:SetFrameLevel(self.frame:GetFrameLevel() + 1)
|
||||
fixlevels(self.pullout.frame, self.pullout.frame:GetChildren())
|
||||
|
||||
self:SetHeight(44)
|
||||
self:SetWidth(200)
|
||||
end
|
||||
|
||||
-- exported, AceGUI callback
|
||||
local function OnRelease(self)
|
||||
if self.open then
|
||||
self.pullout:Close()
|
||||
end
|
||||
AceGUI:Release(self.pullout)
|
||||
self.pullout = nil
|
||||
|
||||
self:SetText("")
|
||||
self:SetLabel("")
|
||||
self:SetDisabled(false)
|
||||
self:SetMultiselect(false)
|
||||
|
||||
self.value = nil
|
||||
self.list = nil
|
||||
self.open = nil
|
||||
self.hasClose = nil
|
||||
|
||||
self.frame:ClearAllPoints()
|
||||
self.frame:Hide()
|
||||
end
|
||||
|
||||
-- exported
|
||||
local function SetDisabled(self, disabled)
|
||||
self.disabled = disabled
|
||||
if disabled then
|
||||
self.text:SetTextColor(0.5,0.5,0.5)
|
||||
self.button:Disable()
|
||||
self.label:SetTextColor(0.5,0.5,0.5)
|
||||
else
|
||||
self.button:Enable()
|
||||
self.label:SetTextColor(1,.82,0)
|
||||
self.text:SetTextColor(1,1,1)
|
||||
end
|
||||
end
|
||||
|
||||
-- exported
|
||||
local function ClearFocus(self)
|
||||
if self.open then
|
||||
self.pullout:Close()
|
||||
end
|
||||
end
|
||||
|
||||
-- exported
|
||||
local function SetText(self, text)
|
||||
self.text:SetText(text or "")
|
||||
end
|
||||
|
||||
-- exported
|
||||
local function SetLabel(self, text)
|
||||
if text and text ~= "" then
|
||||
self.label:SetText(text)
|
||||
self.label:Show()
|
||||
self.dropdown:SetPoint("TOPLEFT",self.frame,"TOPLEFT",-15,-18)
|
||||
self.frame:SetHeight(44)
|
||||
else
|
||||
self.label:SetText("")
|
||||
self.label:Hide()
|
||||
self.dropdown:SetPoint("TOPLEFT",self.frame,"TOPLEFT",-15,0)
|
||||
self.frame:SetHeight(26)
|
||||
end
|
||||
end
|
||||
|
||||
-- exported
|
||||
local function SetValue(self, value)
|
||||
if self.list then
|
||||
self:SetText(self.list[value] or "")
|
||||
end
|
||||
self.value = value
|
||||
end
|
||||
|
||||
-- exported
|
||||
local function GetValue(self)
|
||||
return self.value
|
||||
end
|
||||
|
||||
-- exported
|
||||
local function SetItemValue(self, item, value)
|
||||
if not self.multiselect then return end
|
||||
for i, widget in self.pullout:IterateItems() do
|
||||
if widget.userdata.value == item then
|
||||
if widget.SetValue then
|
||||
widget:SetValue(value)
|
||||
end
|
||||
end
|
||||
end
|
||||
ShowMultiText(self)
|
||||
end
|
||||
|
||||
-- exported
|
||||
local function SetItemDisabled(self, item, disabled)
|
||||
for i, widget in self.pullout:IterateItems() do
|
||||
if widget.userdata.value == item then
|
||||
widget:SetDisabled(disabled)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function AddListItem(self, value, text)
|
||||
local item = AceGUI:Create("Dropdown-Item-Toggle")
|
||||
item:SetText(text)
|
||||
item.userdata.obj = self
|
||||
item.userdata.value = value
|
||||
item:SetCallback("OnValueChanged", OnItemValueChanged)
|
||||
self.pullout:AddItem(item)
|
||||
end
|
||||
|
||||
local function AddCloseButton(self)
|
||||
if not self.hasClose then
|
||||
local close = AceGUI:Create("Dropdown-Item-Execute")
|
||||
close:SetText(CLOSE)
|
||||
self.pullout:AddItem(close)
|
||||
self.hasClose = true
|
||||
end
|
||||
end
|
||||
|
||||
-- exported
|
||||
local sortlist = {}
|
||||
local function SetList(self, list)
|
||||
self.list = list
|
||||
self.pullout:Clear()
|
||||
self.hasClose = nil
|
||||
if not list then return end
|
||||
|
||||
for v in pairs(list) do
|
||||
sortlist[#sortlist + 1] = v
|
||||
end
|
||||
tsort(sortlist)
|
||||
|
||||
for i, value in pairs(sortlist) do
|
||||
AddListItem(self, value, list[value])
|
||||
sortlist[i] = nil
|
||||
end
|
||||
if self.multiselect then
|
||||
ShowMultiText(self)
|
||||
AddCloseButton(self)
|
||||
end
|
||||
end
|
||||
|
||||
-- exported
|
||||
local function AddItem(self, value, text)
|
||||
if self.list then
|
||||
self.list[value] = text
|
||||
AddListItem(self, value, text)
|
||||
end
|
||||
end
|
||||
|
||||
-- exported
|
||||
local function SetMultiselect(self, multi)
|
||||
self.multiselect = multi
|
||||
if multi then
|
||||
ShowMultiText(self)
|
||||
AddCloseButton(self)
|
||||
end
|
||||
end
|
||||
|
||||
-- exported
|
||||
local function GetMultiselect(self)
|
||||
return self.multiselect
|
||||
end
|
||||
|
||||
--[[ Constructor ]]--
|
||||
|
||||
local function Constructor()
|
||||
local count = AceGUI:GetNextWidgetNum(widgetType)
|
||||
local frame = CreateFrame("Frame", nil, UIParent)
|
||||
local dropdown = CreateFrame("Frame", "AceGUI30DropDown"..count, frame, "UIDropDownMenuTemplate")
|
||||
|
||||
local self = {}
|
||||
self.type = widgetType
|
||||
self.frame = frame
|
||||
self.dropdown = dropdown
|
||||
self.count = count
|
||||
frame.obj = self
|
||||
dropdown.obj = self
|
||||
|
||||
self.OnRelease = OnRelease
|
||||
self.OnAcquire = OnAcquire
|
||||
|
||||
self.ClearFocus = ClearFocus
|
||||
|
||||
self.SetText = SetText
|
||||
self.SetValue = SetValue
|
||||
self.GetValue = GetValue
|
||||
self.SetList = SetList
|
||||
self.SetLabel = SetLabel
|
||||
self.SetDisabled = SetDisabled
|
||||
self.AddItem = AddItem
|
||||
self.SetMultiselect = SetMultiselect
|
||||
self.GetMultiselect = GetMultiselect
|
||||
self.SetItemValue = SetItemValue
|
||||
self.SetItemDisabled = SetItemDisabled
|
||||
|
||||
self.alignoffset = 31
|
||||
|
||||
frame:SetHeight(44)
|
||||
frame:SetWidth(200)
|
||||
frame:SetScript("OnHide",Dropdown_OnHide)
|
||||
|
||||
dropdown:ClearAllPoints()
|
||||
dropdown:SetPoint("TOPLEFT",frame,"TOPLEFT",-15,0)
|
||||
dropdown:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",17,0)
|
||||
dropdown:SetScript("OnHide", nil)
|
||||
|
||||
local left = _G[dropdown:GetName() .. "Left"]
|
||||
local middle = _G[dropdown:GetName() .. "Middle"]
|
||||
local right = _G[dropdown:GetName() .. "Right"]
|
||||
|
||||
middle:ClearAllPoints()
|
||||
right:ClearAllPoints()
|
||||
|
||||
middle:SetPoint("LEFT", left, "RIGHT", 0, 0)
|
||||
middle:SetPoint("RIGHT", right, "LEFT", 0, 0)
|
||||
right:SetPoint("TOPRIGHT", dropdown, "TOPRIGHT", 0, 17)
|
||||
|
||||
local button = _G[dropdown:GetName() .. "Button"]
|
||||
self.button = button
|
||||
button.obj = self
|
||||
button:SetScript("OnEnter",Control_OnEnter)
|
||||
button:SetScript("OnLeave",Control_OnLeave)
|
||||
button:SetScript("OnClick",Dropdown_TogglePullout)
|
||||
|
||||
local text = _G[dropdown:GetName() .. "Text"]
|
||||
self.text = text
|
||||
text.obj = self
|
||||
text:ClearAllPoints()
|
||||
text:SetPoint("RIGHT", right, "RIGHT" ,-43, 2)
|
||||
text:SetPoint("LEFT", left, "LEFT", 25, 2)
|
||||
|
||||
local label = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
|
||||
label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0)
|
||||
label:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0)
|
||||
label:SetJustifyH("LEFT")
|
||||
label:SetHeight(18)
|
||||
label:Hide()
|
||||
self.label = label
|
||||
|
||||
AceGUI:RegisterAsWidget(self)
|
||||
return self
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion)
|
||||
end
|
||||
235
MogIt/Libs/AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua
Normal file
@@ -0,0 +1,235 @@
|
||||
--[[-----------------------------------------------------------------------------
|
||||
EditBox Widget
|
||||
-------------------------------------------------------------------------------]]
|
||||
local Type, Version = "EditBox", 22
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local tostring, pairs = tostring, pairs
|
||||
|
||||
-- WoW APIs
|
||||
local PlaySound = PlaySound
|
||||
local GetCursorInfo, ClearCursor, GetSpellName = GetCursorInfo, ClearCursor, GetSpellName
|
||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||
local _G = _G
|
||||
|
||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||
-- List them here for Mikk's FindGlobals script
|
||||
-- GLOBALS: AceGUIEditBoxInsertLink, ChatFontNormal, OKAY
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Support functions
|
||||
-------------------------------------------------------------------------------]]
|
||||
if not AceGUIEditBoxInsertLink then
|
||||
-- upgradeable hook
|
||||
hooksecurefunc("ChatEdit_InsertLink", function(...) return _G.AceGUIEditBoxInsertLink(...) end)
|
||||
end
|
||||
|
||||
function _G.AceGUIEditBoxInsertLink(text)
|
||||
for i = 1, AceGUI:GetWidgetCount(Type) do
|
||||
local editbox = _G["AceGUI-3.0EditBox"..i]
|
||||
if editbox and editbox:IsVisible() and editbox:HasFocus() then
|
||||
editbox:Insert(text)
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function ShowButton(self)
|
||||
if not self.disablebutton then
|
||||
self.button:Show()
|
||||
self.editbox:SetTextInsets(0, 20, 3, 3)
|
||||
end
|
||||
end
|
||||
|
||||
local function HideButton(self)
|
||||
self.button:Hide()
|
||||
self.editbox:SetTextInsets(0, 0, 3, 3)
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Control_OnEnter(frame)
|
||||
frame.obj:Fire("OnEnter")
|
||||
end
|
||||
|
||||
local function Control_OnLeave(frame)
|
||||
frame.obj:Fire("OnLeave")
|
||||
end
|
||||
|
||||
local function EditBox_OnEscapePressed(frame)
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function EditBox_OnEnterPressed(frame)
|
||||
local self = frame.obj
|
||||
local value = frame:GetText()
|
||||
local cancel = self:Fire("OnEnterPressed", value)
|
||||
if not cancel then
|
||||
PlaySound("igMainMenuOptionCheckBoxOn")
|
||||
HideButton(self)
|
||||
end
|
||||
end
|
||||
|
||||
local function EditBox_OnReceiveDrag(frame)
|
||||
local self = frame.obj
|
||||
local type, id, info = GetCursorInfo()
|
||||
if type == "item" then
|
||||
self:SetText(info)
|
||||
self:Fire("OnEnterPressed", info)
|
||||
ClearCursor()
|
||||
elseif type == "spell" then
|
||||
local name, rank = GetSpellName(id, info)
|
||||
if rank and rank:match("%d") then
|
||||
name = name.."("..rank..")"
|
||||
end
|
||||
self:SetText(name)
|
||||
self:Fire("OnEnterPressed", name)
|
||||
ClearCursor()
|
||||
end
|
||||
HideButton(self)
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function EditBox_OnTextChanged(frame)
|
||||
local self = frame.obj
|
||||
local value = frame:GetText()
|
||||
if tostring(value) ~= tostring(self.lasttext) then
|
||||
self:Fire("OnTextChanged", value)
|
||||
self.lasttext = value
|
||||
ShowButton(self)
|
||||
end
|
||||
end
|
||||
|
||||
local function Button_OnClick(frame)
|
||||
local editbox = frame.obj.editbox
|
||||
editbox:ClearFocus()
|
||||
EditBox_OnEnterPressed(editbox)
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
-- height is controlled by SetLabel
|
||||
self:SetWidth(200)
|
||||
self:SetDisabled(false)
|
||||
self:SetLabel()
|
||||
self:SetText()
|
||||
self:DisableButton(false)
|
||||
self:SetMaxLetters(0)
|
||||
end,
|
||||
|
||||
-- ["OnRelease"] = nil,
|
||||
|
||||
["SetDisabled"] = function(self, disabled)
|
||||
self.disabled = disabled
|
||||
if disabled then
|
||||
self.editbox:EnableMouse(false)
|
||||
self.editbox:ClearFocus()
|
||||
self.editbox:SetTextColor(0.5,0.5,0.5)
|
||||
self.label:SetTextColor(0.5,0.5,0.5)
|
||||
else
|
||||
self.editbox:EnableMouse(true)
|
||||
self.editbox:SetTextColor(1,1,1)
|
||||
self.label:SetTextColor(1,.82,0)
|
||||
end
|
||||
end,
|
||||
|
||||
["SetText"] = function(self, text)
|
||||
self.lasttext = text or ""
|
||||
self.editbox:SetText(text or "")
|
||||
self.editbox:SetCursorPosition(0)
|
||||
HideButton(self)
|
||||
end,
|
||||
|
||||
["GetText"] = function(self, text)
|
||||
return self.editbox:GetText()
|
||||
end,
|
||||
|
||||
["SetLabel"] = function(self, text)
|
||||
if text and text ~= "" then
|
||||
self.label:SetText(text)
|
||||
self.label:Show()
|
||||
self.editbox:SetPoint("TOPLEFT",self.frame,"TOPLEFT",7,-18)
|
||||
self:SetHeight(44)
|
||||
self.alignoffset = 30
|
||||
else
|
||||
self.label:SetText("")
|
||||
self.label:Hide()
|
||||
self.editbox:SetPoint("TOPLEFT",self.frame,"TOPLEFT",7,0)
|
||||
self:SetHeight(26)
|
||||
self.alignoffset = 12
|
||||
end
|
||||
end,
|
||||
|
||||
["DisableButton"] = function(self, disabled)
|
||||
self.disablebutton = disabled
|
||||
if disabled then
|
||||
HideButton(self)
|
||||
end
|
||||
end,
|
||||
|
||||
["SetMaxLetters"] = function (self, num)
|
||||
self.editbox:SetMaxLetters(num or 0)
|
||||
end
|
||||
}
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Constructor()
|
||||
local num = AceGUI:GetNextWidgetNum(Type)
|
||||
local frame = CreateFrame("Frame", nil, UIParent)
|
||||
frame:Hide()
|
||||
|
||||
local editbox = CreateFrame("EditBox", "AceGUI-3.0EditBox"..num, frame, "InputBoxTemplate")
|
||||
editbox:SetAutoFocus(false)
|
||||
editbox:SetFontObject(ChatFontNormal)
|
||||
editbox:SetScript("OnEnter", Control_OnEnter)
|
||||
editbox:SetScript("OnLeave", Control_OnLeave)
|
||||
editbox:SetScript("OnEscapePressed", EditBox_OnEscapePressed)
|
||||
editbox:SetScript("OnEnterPressed", EditBox_OnEnterPressed)
|
||||
editbox:SetScript("OnTextChanged", EditBox_OnTextChanged)
|
||||
editbox:SetScript("OnReceiveDrag", EditBox_OnReceiveDrag)
|
||||
editbox:SetScript("OnMouseDown", EditBox_OnReceiveDrag)
|
||||
editbox:SetTextInsets(0, 0, 3, 3)
|
||||
editbox:SetMaxLetters(256)
|
||||
editbox:SetPoint("BOTTOMLEFT", 6, 0)
|
||||
editbox:SetPoint("BOTTOMRIGHT")
|
||||
editbox:SetHeight(19)
|
||||
|
||||
local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
|
||||
label:SetPoint("TOPLEFT", 0, -2)
|
||||
label:SetPoint("TOPRIGHT", 0, -2)
|
||||
label:SetJustifyH("LEFT")
|
||||
label:SetHeight(18)
|
||||
|
||||
local button = CreateFrame("Button", nil, editbox, "UIPanelButtonTemplate")
|
||||
button:SetWidth(40)
|
||||
button:SetHeight(20)
|
||||
button:SetPoint("RIGHT", -2, 0)
|
||||
button:SetText(OKAY)
|
||||
button:SetScript("OnClick", Button_OnClick)
|
||||
button:Hide()
|
||||
|
||||
local widget = {
|
||||
alignoffset = 30,
|
||||
editbox = editbox,
|
||||
label = label,
|
||||
button = button,
|
||||
frame = frame,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
editbox.obj, button.obj = widget, widget
|
||||
|
||||
return AceGUI:RegisterAsWidget(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
78
MogIt/Libs/AceGUI-3.0/widgets/AceGUIWidget-Heading.lua
Normal file
@@ -0,0 +1,78 @@
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Heading Widget
|
||||
-------------------------------------------------------------------------------]]
|
||||
local Type, Version = "Heading", 20
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local pairs = pairs
|
||||
|
||||
-- WoW APIs
|
||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self:SetText()
|
||||
self:SetFullWidth()
|
||||
self:SetHeight(18)
|
||||
end,
|
||||
|
||||
-- ["OnRelease"] = nil,
|
||||
|
||||
["SetText"] = function(self, text)
|
||||
self.label:SetText(text or "")
|
||||
if text and text ~= "" then
|
||||
self.left:SetPoint("RIGHT", self.label, "LEFT", -5, 0)
|
||||
self.right:Show()
|
||||
else
|
||||
self.left:SetPoint("RIGHT", -3, 0)
|
||||
self.right:Hide()
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Constructor()
|
||||
local frame = CreateFrame("Frame", nil, UIParent)
|
||||
frame:Hide()
|
||||
|
||||
local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontNormal")
|
||||
label:SetPoint("TOP")
|
||||
label:SetPoint("BOTTOM")
|
||||
label:SetJustifyH("CENTER")
|
||||
|
||||
local left = frame:CreateTexture(nil, "BACKGROUND")
|
||||
left:SetHeight(8)
|
||||
left:SetPoint("LEFT", 3, 0)
|
||||
left:SetPoint("RIGHT", label, "LEFT", -5, 0)
|
||||
left:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
|
||||
left:SetTexCoord(0.81, 0.94, 0.5, 1)
|
||||
|
||||
local right = frame:CreateTexture(nil, "BACKGROUND")
|
||||
right:SetHeight(8)
|
||||
right:SetPoint("RIGHT", -3, 0)
|
||||
right:SetPoint("LEFT", label, "RIGHT", 5, 0)
|
||||
right:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border")
|
||||
right:SetTexCoord(0.81, 0.94, 0.5, 1)
|
||||
|
||||
local widget = {
|
||||
label = label,
|
||||
left = left,
|
||||
right = right,
|
||||
frame = frame,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
|
||||
return AceGUI:RegisterAsWidget(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
144
MogIt/Libs/AceGUI-3.0/widgets/AceGUIWidget-Icon.lua
Normal file
@@ -0,0 +1,144 @@
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Icon Widget
|
||||
-------------------------------------------------------------------------------]]
|
||||
local Type, Version = "Icon", 20
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local select, pairs, print = select, pairs, print
|
||||
|
||||
-- WoW APIs
|
||||
local CreateFrame, UIParent, GetBuildInfo = CreateFrame, UIParent, GetBuildInfo
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Control_OnEnter(frame)
|
||||
frame.obj:Fire("OnEnter")
|
||||
end
|
||||
|
||||
local function Control_OnLeave(frame)
|
||||
frame.obj:Fire("OnLeave")
|
||||
end
|
||||
|
||||
local function Button_OnClick(frame, button)
|
||||
frame.obj:Fire("OnClick", button)
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self:SetHeight(110)
|
||||
self:SetWidth(110)
|
||||
self:SetLabel()
|
||||
self:SetImage(nil)
|
||||
self:SetImageSize(64, 64)
|
||||
self:SetDisabled(false)
|
||||
end,
|
||||
|
||||
-- ["OnRelease"] = nil,
|
||||
|
||||
["SetLabel"] = function(self, text)
|
||||
if text and text ~= "" then
|
||||
self.label:Show()
|
||||
self.label:SetText(text)
|
||||
self:SetHeight(self.image:GetHeight() + 25)
|
||||
else
|
||||
self.label:Hide()
|
||||
self:SetHeight(self.image:GetHeight() + 10)
|
||||
end
|
||||
end,
|
||||
|
||||
["SetImage"] = function(self, path, ...)
|
||||
local image = self.image
|
||||
image:SetTexture(path)
|
||||
|
||||
if image:GetTexture() then
|
||||
local n = select("#", ...)
|
||||
if n == 4 or n == 8 then
|
||||
image:SetTexCoord(...)
|
||||
else
|
||||
image:SetTexCoord(0, 1, 0, 1)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
["SetImageSize"] = function(self, width, height)
|
||||
self.image:SetWidth(width)
|
||||
self.image:SetHeight(height)
|
||||
--self.frame:SetWidth(width + 30)
|
||||
if self.label:IsShown() then
|
||||
self:SetHeight(height + 25)
|
||||
else
|
||||
self:SetHeight(height + 10)
|
||||
end
|
||||
end,
|
||||
|
||||
["SetDisabled"] = function(self, disabled)
|
||||
self.disabled = disabled
|
||||
if disabled then
|
||||
self.frame:Disable()
|
||||
self.label:SetTextColor(0.5, 0.5, 0.5)
|
||||
self.image:SetVertexColor(0.5, 0.5, 0.5, 0.5)
|
||||
else
|
||||
self.frame:Enable()
|
||||
self.label:SetTextColor(1, 1, 1)
|
||||
self.image:SetVertexColor(1, 1, 1)
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Constructor()
|
||||
local frame = CreateFrame("Button", nil, UIParent)
|
||||
frame:Hide()
|
||||
|
||||
frame:EnableMouse(true)
|
||||
frame:SetScript("OnEnter", Control_OnEnter)
|
||||
frame:SetScript("OnLeave", Control_OnLeave)
|
||||
frame:SetScript("OnClick", Button_OnClick)
|
||||
|
||||
local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontHighlight")
|
||||
label:SetPoint("BOTTOMLEFT")
|
||||
label:SetPoint("BOTTOMRIGHT")
|
||||
label:SetJustifyH("CENTER")
|
||||
label:SetJustifyV("TOP")
|
||||
label:SetHeight(18)
|
||||
|
||||
local image = frame:CreateTexture(nil, "BACKGROUND")
|
||||
image:SetWidth(64)
|
||||
image:SetHeight(64)
|
||||
image:SetPoint("TOP", 0, -5)
|
||||
|
||||
local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
|
||||
highlight:SetAllPoints(image)
|
||||
highlight:SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-Tab-Highlight")
|
||||
highlight:SetTexCoord(0, 1, 0.23, 0.77)
|
||||
highlight:SetBlendMode("ADD")
|
||||
|
||||
local widget = {
|
||||
label = label,
|
||||
image = image,
|
||||
frame = frame,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
-- SetText is deprecated, but keep it around for a while. (say, to WoW 4.0)
|
||||
if (select(4, GetBuildInfo()) < 40000) then
|
||||
widget.SetText = widget.SetLabel
|
||||
else
|
||||
widget.SetText = function(self, ...) print("AceGUI-3.0-Icon: SetText is deprecated! Use SetLabel instead!"); self:SetLabel(...) end
|
||||
end
|
||||
|
||||
return AceGUI:RegisterAsWidget(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
101
MogIt/Libs/AceGUI-3.0/widgets/AceGUIWidget-InteractiveLabel.lua
Normal file
@@ -0,0 +1,101 @@
|
||||
--[[-----------------------------------------------------------------------------
|
||||
InteractiveLabel Widget
|
||||
-------------------------------------------------------------------------------]]
|
||||
local Type, Version = "InteractiveLabel", 20
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local select, pairs = select, pairs
|
||||
|
||||
-- WoW APIs
|
||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||
|
||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||
-- List them here for Mikk's FindGlobals script
|
||||
-- GLOBALS: GameFontHighlightSmall
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Control_OnEnter(frame)
|
||||
frame.obj:Fire("OnEnter")
|
||||
end
|
||||
|
||||
local function Control_OnLeave(frame)
|
||||
frame.obj:Fire("OnLeave")
|
||||
end
|
||||
|
||||
local function Label_OnClick(frame, button)
|
||||
frame.obj:Fire("OnClick", button)
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self:LabelOnAcquire()
|
||||
self:SetHighlight()
|
||||
self:SetHighlightTexCoord()
|
||||
self:SetDisabled(false)
|
||||
end,
|
||||
|
||||
-- ["OnRelease"] = nil,
|
||||
|
||||
["SetHighlight"] = function(self, ...)
|
||||
self.highlight:SetTexture(...)
|
||||
end,
|
||||
|
||||
["SetHighlightTexCoord"] = function(self, ...)
|
||||
local c = select("#", ...)
|
||||
if c == 4 or c == 8 then
|
||||
self.highlight:SetTexCoord(...)
|
||||
else
|
||||
self.highlight:SetTexCoord(0, 1, 0, 1)
|
||||
end
|
||||
end,
|
||||
|
||||
["SetDisabled"] = function(self,disabled)
|
||||
self.disabled = disabled
|
||||
if disabled then
|
||||
self.frame:EnableMouse(false)
|
||||
self.label:SetTextColor(0.5, 0.5, 0.5)
|
||||
else
|
||||
self.frame:EnableMouse(true)
|
||||
self.label:SetTextColor(1, 1, 1)
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Constructor()
|
||||
-- create a Label type that we will hijack
|
||||
local label = AceGUI:Create("Label")
|
||||
|
||||
local frame = label.frame
|
||||
frame:EnableMouse(true)
|
||||
frame:SetScript("OnEnter", Control_OnEnter)
|
||||
frame:SetScript("OnLeave", Control_OnLeave)
|
||||
frame:SetScript("OnMouseDown", Label_OnClick)
|
||||
|
||||
local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
|
||||
highlight:SetTexture(nil)
|
||||
highlight:SetAllPoints()
|
||||
highlight:SetBlendMode("ADD")
|
||||
|
||||
label.highlight = highlight
|
||||
label.type = Type
|
||||
label.LabelOnAcquire = label.OnAcquire
|
||||
for method, func in pairs(methods) do
|
||||
label[method] = func
|
||||
end
|
||||
|
||||
return label
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
|
||||
230
MogIt/Libs/AceGUI-3.0/widgets/AceGUIWidget-Keybinding.lua
Normal file
@@ -0,0 +1,230 @@
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Keybinding Widget
|
||||
Set Keybindings in the Config UI.
|
||||
-------------------------------------------------------------------------------]]
|
||||
local Type, Version = "Keybinding", 21
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local pairs = pairs
|
||||
|
||||
-- WoW APIs
|
||||
local IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown = IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown
|
||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||
|
||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||
-- List them here for Mikk's FindGlobals script
|
||||
-- GLOBALS: NOT_BOUND
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function Control_OnEnter(frame)
|
||||
frame.obj:Fire("OnEnter")
|
||||
end
|
||||
|
||||
local function Control_OnLeave(frame)
|
||||
frame.obj:Fire("OnLeave")
|
||||
end
|
||||
|
||||
local function Keybinding_OnClick(frame, button)
|
||||
if button == "LeftButton" or button == "RightButton" then
|
||||
local self = frame.obj
|
||||
if self.waitingForKey then
|
||||
frame:EnableKeyboard(false)
|
||||
self.msgframe:Hide()
|
||||
frame:UnlockHighlight()
|
||||
self.waitingForKey = nil
|
||||
else
|
||||
frame:EnableKeyboard(true)
|
||||
self.msgframe:Show()
|
||||
frame:LockHighlight()
|
||||
self.waitingForKey = true
|
||||
end
|
||||
end
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local ignoreKeys = {
|
||||
["BUTTON1"] = true, ["BUTTON2"] = true,
|
||||
["UNKNOWN"] = true,
|
||||
["LSHIFT"] = true, ["LCTRL"] = true, ["LALT"] = true,
|
||||
["RSHIFT"] = true, ["RCTRL"] = true, ["RALT"] = true,
|
||||
}
|
||||
local function Keybinding_OnKeyDown(frame, key)
|
||||
local self = frame.obj
|
||||
if self.waitingForKey then
|
||||
local keyPressed = key
|
||||
if keyPressed == "ESCAPE" then
|
||||
keyPressed = ""
|
||||
else
|
||||
if ignoreKeys[keyPressed] then return end
|
||||
if IsShiftKeyDown() then
|
||||
keyPressed = "SHIFT-"..keyPressed
|
||||
end
|
||||
if IsControlKeyDown() then
|
||||
keyPressed = "CTRL-"..keyPressed
|
||||
end
|
||||
if IsAltKeyDown() then
|
||||
keyPressed = "ALT-"..keyPressed
|
||||
end
|
||||
end
|
||||
|
||||
frame:EnableKeyboard(false)
|
||||
self.msgframe:Hide()
|
||||
frame:UnlockHighlight()
|
||||
self.waitingForKey = nil
|
||||
|
||||
if not self.disabled then
|
||||
self:SetKey(keyPressed)
|
||||
self:Fire("OnKeyChanged", keyPressed)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function Keybinding_OnMouseDown(frame, button)
|
||||
if button == "LeftButton" or button == "RightButton" then
|
||||
return
|
||||
elseif button == "MiddleButton" then
|
||||
button = "BUTTON3"
|
||||
elseif button == "Button4" then
|
||||
button = "BUTTON4"
|
||||
elseif button == "Button5" then
|
||||
button = "BUTTON5"
|
||||
end
|
||||
Keybinding_OnKeyDown(frame, button)
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self:SetWidth(200)
|
||||
self:SetLabel("")
|
||||
self:SetKey("")
|
||||
self.waitingForKey = nil
|
||||
self.msgframe:Hide()
|
||||
self:SetDisabled(false)
|
||||
end,
|
||||
|
||||
-- ["OnRelease"] = nil,
|
||||
|
||||
["SetDisabled"] = function(self, disabled)
|
||||
self.disabled = disabled
|
||||
if disabled then
|
||||
self.button:Disable()
|
||||
self.label:SetTextColor(0.5,0.5,0.5)
|
||||
else
|
||||
self.button:Enable()
|
||||
self.label:SetTextColor(1,1,1)
|
||||
end
|
||||
end,
|
||||
|
||||
["SetKey"] = function(self, key)
|
||||
if (key or "") == "" then
|
||||
self.button:SetText(NOT_BOUND)
|
||||
self.button:SetNormalFontObject("GameFontNormal")
|
||||
else
|
||||
self.button:SetText(key)
|
||||
self.button:SetNormalFontObject("GameFontHighlight")
|
||||
end
|
||||
end,
|
||||
|
||||
["GetKey"] = function(self)
|
||||
local key = self.button:GetText()
|
||||
if key == NOT_BOUND then
|
||||
key = nil
|
||||
end
|
||||
return key
|
||||
end,
|
||||
|
||||
["SetLabel"] = function(self, label)
|
||||
self.label:SetText(label or "")
|
||||
if (label or "") == "" then
|
||||
self.alignoffset = nil
|
||||
self:SetHeight(24)
|
||||
else
|
||||
self.alignoffset = 30
|
||||
self:SetHeight(44)
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local ControlBackdrop = {
|
||||
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
|
||||
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
||||
tile = true, tileSize = 16, edgeSize = 16,
|
||||
insets = { left = 3, right = 3, top = 3, bottom = 3 }
|
||||
}
|
||||
|
||||
local function keybindingMsgFixWidth(frame)
|
||||
frame:SetWidth(frame.msg:GetWidth() + 10)
|
||||
frame:SetScript("OnUpdate", nil)
|
||||
end
|
||||
|
||||
local function Constructor()
|
||||
local name = "AceGUI30KeybindingButton" .. AceGUI:GetNextWidgetNum(Type)
|
||||
|
||||
local frame = CreateFrame("Frame", nil, UIParent)
|
||||
local button = CreateFrame("Button", name, frame, "UIPanelButtonTemplate2")
|
||||
|
||||
button:EnableMouse(true)
|
||||
button:RegisterForClicks("AnyDown")
|
||||
button:SetScript("OnEnter", Control_OnEnter)
|
||||
button:SetScript("OnLeave", Control_OnLeave)
|
||||
button:SetScript("OnClick", Keybinding_OnClick)
|
||||
button:SetScript("OnKeyDown", Keybinding_OnKeyDown)
|
||||
button:SetScript("OnMouseDown", Keybinding_OnMouseDown)
|
||||
button:SetPoint("BOTTOMLEFT")
|
||||
button:SetPoint("BOTTOMRIGHT")
|
||||
button:SetHeight(24)
|
||||
|
||||
local text = button:GetFontString()
|
||||
text:SetPoint("LEFT", 7, 0)
|
||||
text:SetPoint("RIGHT", -7, 0)
|
||||
|
||||
local label = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
|
||||
label:SetPoint("TOPLEFT")
|
||||
label:SetPoint("TOPRIGHT")
|
||||
label:SetJustifyH("CENTER")
|
||||
label:SetHeight(18)
|
||||
|
||||
local msgframe = CreateFrame("Frame", nil, UIParent)
|
||||
msgframe:SetHeight(30)
|
||||
msgframe:SetBackdrop(ControlBackdrop)
|
||||
msgframe:SetBackdropColor(0,0,0)
|
||||
msgframe:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
msgframe:SetFrameLevel(1000)
|
||||
|
||||
local msg = msgframe:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
||||
msg:SetText("Press a key to bind, ESC to clear the binding or click the button again to cancel.")
|
||||
msgframe.msg = msg
|
||||
msg:SetPoint("TOPLEFT", 5, -5)
|
||||
msgframe:SetScript("OnUpdate", keybindingMsgFixWidth)
|
||||
msgframe:SetPoint("BOTTOM", button, "TOP")
|
||||
msgframe:Hide()
|
||||
|
||||
local widget = {
|
||||
button = button,
|
||||
label = label,
|
||||
msgframe = msgframe,
|
||||
frame = frame,
|
||||
alignoffset = 30,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
button.obj = widget
|
||||
|
||||
return AceGUI:RegisterAsWidget(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
162
MogIt/Libs/AceGUI-3.0/widgets/AceGUIWidget-Label.lua
Normal file
@@ -0,0 +1,162 @@
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Label Widget
|
||||
Displays text and optionally an icon.
|
||||
-------------------------------------------------------------------------------]]
|
||||
local Type, Version = "Label", 21
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local max, select, pairs = math.max, select, pairs
|
||||
|
||||
-- WoW APIs
|
||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||
|
||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||
-- List them here for Mikk's FindGlobals script
|
||||
-- GLOBALS: GameFontHighlightSmall
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Support functions
|
||||
-------------------------------------------------------------------------------]]
|
||||
|
||||
local function UpdateImageAnchor(self)
|
||||
if self.resizing then return end
|
||||
local frame = self.frame
|
||||
local width = frame.width or frame:GetWidth() or 0
|
||||
local image = self.image
|
||||
local label = self.label
|
||||
local height
|
||||
|
||||
label:ClearAllPoints()
|
||||
image:ClearAllPoints()
|
||||
|
||||
if self.imageshown then
|
||||
local imagewidth = image:GetWidth()
|
||||
if (width - imagewidth) < 200 or (label:GetText() or "") == "" then
|
||||
-- image goes on top centered when less than 200 width for the text, or if there is no text
|
||||
image:SetPoint("TOP")
|
||||
label:SetPoint("TOP", image, "BOTTOM")
|
||||
label:SetPoint("LEFT")
|
||||
label:SetWidth(width)
|
||||
height = image:GetHeight() + label:GetHeight()
|
||||
else
|
||||
-- image on the left
|
||||
image:SetPoint("TOPLEFT")
|
||||
label:SetPoint("TOPLEFT", image, "TOPRIGHT", 4, 0)
|
||||
label:SetWidth(width - imagewidth - 4)
|
||||
height = max(image:GetHeight(), label:GetHeight())
|
||||
end
|
||||
else
|
||||
-- no image shown
|
||||
label:SetPoint("TOPLEFT")
|
||||
label:SetWidth(width)
|
||||
height = label:GetHeight()
|
||||
end
|
||||
|
||||
self.resizing = true
|
||||
frame:SetHeight(height)
|
||||
frame.height = height
|
||||
self.resizing = nil
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
-- set the flag to stop constant size updates
|
||||
self.resizing = true
|
||||
-- height is set dynamically by the text and image size
|
||||
self:SetWidth(200)
|
||||
self:SetText()
|
||||
self:SetImage(nil)
|
||||
self:SetImageSize(16, 16)
|
||||
self:SetColor()
|
||||
self:SetFontObject()
|
||||
|
||||
-- reset the flag
|
||||
self.resizing = nil
|
||||
-- run the update explicitly
|
||||
UpdateImageAnchor(self)
|
||||
end,
|
||||
|
||||
-- ["OnRelease"] = nil,
|
||||
|
||||
["OnWidthSet"] = function(self, width)
|
||||
UpdateImageAnchor(self)
|
||||
end,
|
||||
|
||||
["SetText"] = function(self, text)
|
||||
self.label:SetText(text)
|
||||
UpdateImageAnchor(self)
|
||||
end,
|
||||
|
||||
["SetColor"] = function(self, r, g, b)
|
||||
if not (r and g and b) then
|
||||
r, g, b = 1, 1, 1
|
||||
end
|
||||
self.label:SetVertexColor(r, g, b)
|
||||
end,
|
||||
|
||||
["SetImage"] = function(self, path, ...)
|
||||
local image = self.image
|
||||
image:SetTexture(path)
|
||||
|
||||
if image:GetTexture() then
|
||||
self.imageshown = true
|
||||
local n = select("#", ...)
|
||||
if n == 4 or n == 8 then
|
||||
image:SetTexCoord(...)
|
||||
else
|
||||
image:SetTexCoord(0, 1, 0, 1)
|
||||
end
|
||||
else
|
||||
self.imageshown = nil
|
||||
end
|
||||
UpdateImageAnchor(self)
|
||||
end,
|
||||
|
||||
["SetFont"] = function(self, font, height, flags)
|
||||
self.label:SetFont(font, height, flags)
|
||||
end,
|
||||
|
||||
["SetFontObject"] = function(self, font)
|
||||
self:SetFont((font or GameFontHighlightSmall):GetFont())
|
||||
end,
|
||||
|
||||
["SetImageSize"] = function(self, width, height)
|
||||
self.image:SetWidth(width)
|
||||
self.image:SetHeight(height)
|
||||
UpdateImageAnchor(self)
|
||||
end,
|
||||
}
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Constructor()
|
||||
local frame = CreateFrame("Frame", nil, UIParent)
|
||||
frame:Hide()
|
||||
|
||||
local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontHighlightSmall")
|
||||
label:SetJustifyH("LEFT")
|
||||
label:SetJustifyV("TOP")
|
||||
|
||||
local image = frame:CreateTexture(nil, "BACKGROUND")
|
||||
|
||||
-- create widget
|
||||
local widget = {
|
||||
label = label,
|
||||
image = image,
|
||||
frame = frame,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
|
||||
return AceGUI:RegisterAsWidget(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
311
MogIt/Libs/AceGUI-3.0/widgets/AceGUIWidget-MultiLineEditBox.lua
Normal file
@@ -0,0 +1,311 @@
|
||||
local Type, Version = "MultiLineEditBox", 23
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local pairs = pairs
|
||||
|
||||
-- WoW APIs
|
||||
local GetCursorInfo, GetSpellName, ClearCursor = GetCursorInfo, GetSpellName, ClearCursor
|
||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||
local _G = _G
|
||||
|
||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||
-- List them here for Mikk's FindGlobals script
|
||||
-- GLOBALS: ACCEPT, ChatFontNormal
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Support functions
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Layout(self)
|
||||
self:SetHeight(self.numlines * 14 + (self.disablebutton and 19 or 41) + self.labelHeight)
|
||||
|
||||
if self.labelHeight == 0 then
|
||||
self.scrollBar:SetPoint("TOP", self.frame, "TOP", 0, -23)
|
||||
else
|
||||
self.scrollBar:SetPoint("TOP", self.label, "BOTTOM", 0, -19)
|
||||
end
|
||||
|
||||
if self.disablebutton then
|
||||
self.scrollBar:SetPoint("BOTTOM", self.frame, "BOTTOM", 0, 21)
|
||||
self.scrollBG:SetPoint("BOTTOMLEFT", 0, 4)
|
||||
else
|
||||
self.scrollBar:SetPoint("BOTTOM", self.button, "TOP", 0, 18)
|
||||
self.scrollBG:SetPoint("BOTTOMLEFT", self.button, "TOPLEFT")
|
||||
end
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function OnClick(self) -- Button
|
||||
self = self.obj
|
||||
self.editBox:ClearFocus()
|
||||
if not self:Fire("OnEnterPressed", self.editBox:GetText()) then
|
||||
self.button:Disable()
|
||||
end
|
||||
end
|
||||
|
||||
local function OnCursorChanged(self, _, y, _, cursorHeight) -- EditBox
|
||||
self, y = self.obj.scrollFrame, -y
|
||||
local offset = self:GetVerticalScroll()
|
||||
if y < offset then
|
||||
self:SetVerticalScroll(y)
|
||||
else
|
||||
y = y + cursorHeight - self:GetHeight()
|
||||
if y > offset then
|
||||
self:SetVerticalScroll(y)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function OnEditFocusLost(self) -- EditBox
|
||||
self:HighlightText(0, 0)
|
||||
end
|
||||
|
||||
local function OnEnter(self) -- EditBox / ScrollFrame
|
||||
self = self.obj
|
||||
if not self.entered then
|
||||
self.entered = true
|
||||
self:Fire("OnEnter")
|
||||
end
|
||||
end
|
||||
|
||||
local function OnLeave(self) -- EditBox / ScrollFrame
|
||||
self = self.obj
|
||||
if self.entered then
|
||||
self.entered = nil
|
||||
self:Fire("OnLeave")
|
||||
end
|
||||
end
|
||||
|
||||
local function OnMouseUp(self) -- ScrollFrame
|
||||
self = self.obj.editBox
|
||||
self:SetFocus()
|
||||
self:SetCursorPosition(self:GetNumLetters())
|
||||
end
|
||||
|
||||
local function OnReceiveDrag(self) -- EditBox / ScrollFrame
|
||||
local type, id, info = GetCursorInfo()
|
||||
if type == "spell" then
|
||||
info, id = GetSpellName(id, info)
|
||||
if id and id:match("%d") then
|
||||
info = info .. "(" .. id .. ")"
|
||||
end
|
||||
elseif type ~= "item" then
|
||||
return
|
||||
end
|
||||
ClearCursor()
|
||||
self = self.obj
|
||||
local editBox = self.editBox
|
||||
if not editBox:HasFocus() then
|
||||
editBox:SetFocus()
|
||||
editBox:SetCursorPosition(editBox:GetNumLetters())
|
||||
end
|
||||
editBox:Insert(info)
|
||||
self.button:Enable()
|
||||
end
|
||||
|
||||
local function OnSizeChanged(self, width, height) -- ScrollFrame
|
||||
self.obj.editBox:SetWidth(width)
|
||||
end
|
||||
|
||||
local function OnTextChanged(self, userInput) -- EditBox
|
||||
if userInput then
|
||||
self = self.obj
|
||||
self:Fire("OnTextChanged", self.editBox:GetText())
|
||||
self.button:Enable()
|
||||
end
|
||||
end
|
||||
|
||||
local function OnTextSet(self) -- EditBox
|
||||
self:HighlightText(0, 0)
|
||||
self:SetCursorPosition(self:GetNumLetters())
|
||||
self:SetCursorPosition(0)
|
||||
self.obj.button:Disable()
|
||||
end
|
||||
|
||||
local function OnVerticalScroll(self, offset) -- ScrollFrame
|
||||
local editBox = self.obj.editBox
|
||||
editBox:SetHitRectInsets(0, 0, offset, editBox:GetHeight() - offset - self:GetHeight())
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self.editBox:SetText("")
|
||||
self:SetDisabled(false)
|
||||
self:SetWidth(200)
|
||||
self:DisableButton(false)
|
||||
self:SetNumLines()
|
||||
self.entered = nil
|
||||
self:SetMaxLetters(0)
|
||||
end,
|
||||
|
||||
-- ["OnRelease"] = nil,
|
||||
|
||||
["SetDisabled"] = function(self, disabled)
|
||||
local editBox = self.editBox
|
||||
if disabled then
|
||||
editBox:ClearFocus()
|
||||
editBox:EnableMouse(false)
|
||||
editBox:SetTextColor(0.5, 0.5, 0.5)
|
||||
self.label:SetTextColor(0.5, 0.5, 0.5)
|
||||
self.scrollFrame:EnableMouse(false)
|
||||
self.button:Disable()
|
||||
else
|
||||
editBox:EnableMouse(true)
|
||||
editBox:SetTextColor(1, 1, 1)
|
||||
self.label:SetTextColor(1, 0.82, 0)
|
||||
self.scrollFrame:EnableMouse(true)
|
||||
end
|
||||
end,
|
||||
|
||||
["SetLabel"] = function(self, text)
|
||||
if text and text ~= "" then
|
||||
self.label:SetText(text)
|
||||
if self.labelHeight ~= 10 then
|
||||
self.labelHeight = 10
|
||||
self.label:Show()
|
||||
end
|
||||
elseif self.labelHeight ~= 0 then
|
||||
self.labelHeight = 0
|
||||
self.label:Hide()
|
||||
end
|
||||
Layout(self)
|
||||
end,
|
||||
|
||||
["SetNumLines"] = function(self, value)
|
||||
if not value or value < 4 then
|
||||
value = 4
|
||||
end
|
||||
self.numlines = value
|
||||
Layout(self)
|
||||
end,
|
||||
|
||||
["SetText"] = function(self, text)
|
||||
self.editBox:SetText(text)
|
||||
end,
|
||||
|
||||
["GetText"] = function(self)
|
||||
return self.editBox:GetText()
|
||||
end,
|
||||
|
||||
["SetMaxLetters"] = function (self, num)
|
||||
self.editBox:SetMaxLetters(num or 0)
|
||||
end,
|
||||
|
||||
["DisableButton"] = function(self, disabled)
|
||||
self.disablebutton = disabled
|
||||
if disabled then
|
||||
self.button:Hide()
|
||||
else
|
||||
self.button:Show()
|
||||
end
|
||||
Layout(self)
|
||||
end
|
||||
}
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
local backdrop = {
|
||||
bgFile = [[Interface\Tooltips\UI-Tooltip-Background]],
|
||||
edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]], edgeSize = 16,
|
||||
insets = { left = 4, right = 3, top = 4, bottom = 3 }
|
||||
}
|
||||
|
||||
local function Constructor()
|
||||
local frame = CreateFrame("Frame", nil, UIParent)
|
||||
frame:Hide()
|
||||
|
||||
local widgetNum = AceGUI:GetNextWidgetNum(Type)
|
||||
|
||||
local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
|
||||
label:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, -4)
|
||||
label:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, -4)
|
||||
label:SetJustifyH("LEFT")
|
||||
label:SetText(ACCEPT)
|
||||
label:SetHeight(10)
|
||||
|
||||
local button = CreateFrame("Button", ("%s%dButton"):format(Type, widgetNum), frame, "UIPanelButtonTemplate2")
|
||||
button:SetPoint("BOTTOMLEFT", 0, 4)
|
||||
button:SetHeight(22)
|
||||
button:SetWidth(label:GetStringWidth() + 24)
|
||||
button:SetText(ACCEPT)
|
||||
button:SetScript("OnClick", OnClick)
|
||||
button:Disable()
|
||||
|
||||
local text = button:GetFontString()
|
||||
text:ClearAllPoints()
|
||||
text:SetPoint("TOPLEFT", button, "TOPLEFT", 5, -5)
|
||||
text:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -5, 1)
|
||||
text:SetJustifyV("MIDDLE")
|
||||
|
||||
local scrollBG = CreateFrame("Frame", nil, frame)
|
||||
scrollBG:SetBackdrop(backdrop)
|
||||
scrollBG:SetBackdropColor(0, 0, 0)
|
||||
scrollBG:SetBackdropBorderColor(0.4, 0.4, 0.4)
|
||||
|
||||
local scrollFrame = CreateFrame("ScrollFrame", ("%s%dScrollFrame"):format(Type, widgetNum), frame, "UIPanelScrollFrameTemplate")
|
||||
|
||||
local scrollBar = _G[scrollFrame:GetName() .. "ScrollBar"]
|
||||
scrollBar:ClearAllPoints()
|
||||
scrollBar:SetPoint("TOP", label, "BOTTOM", 0, -19)
|
||||
scrollBar:SetPoint("BOTTOM", button, "TOP", 0, 18)
|
||||
scrollBar:SetPoint("RIGHT", frame, "RIGHT")
|
||||
|
||||
scrollBG:SetPoint("TOPRIGHT", scrollBar, "TOPLEFT", 0, 19)
|
||||
scrollBG:SetPoint("BOTTOMLEFT", button, "TOPLEFT")
|
||||
|
||||
scrollFrame:SetPoint("TOPLEFT", scrollBG, "TOPLEFT", 5, -6)
|
||||
scrollFrame:SetPoint("BOTTOMRIGHT", scrollBG, "BOTTOMRIGHT", -4, 4)
|
||||
scrollFrame:SetScript("OnEnter", OnEnter)
|
||||
scrollFrame:SetScript("OnLeave", OnLeave)
|
||||
scrollFrame:SetScript("OnMouseUp", OnMouseUp)
|
||||
scrollFrame:SetScript("OnReceiveDrag", OnReceiveDrag)
|
||||
scrollFrame:SetScript("OnSizeChanged", OnSizeChanged)
|
||||
scrollFrame:HookScript("OnVerticalScroll", OnVerticalScroll)
|
||||
|
||||
local editBox = CreateFrame("EditBox", nil, scrollFrame)
|
||||
editBox:SetAllPoints()
|
||||
editBox:SetFontObject(ChatFontNormal)
|
||||
editBox:SetMultiLine(true)
|
||||
editBox:EnableMouse(true)
|
||||
editBox:SetAutoFocus(false)
|
||||
editBox:SetCountInvisibleLetters(false)
|
||||
editBox:SetScript("OnCursorChanged", OnCursorChanged)
|
||||
editBox:SetScript("OnEditFocusLost", OnEditFocusLost)
|
||||
editBox:SetScript("OnEnter", OnEnter)
|
||||
editBox:SetScript("OnEscapePressed", editBox.ClearFocus)
|
||||
editBox:SetScript("OnLeave", OnLeave)
|
||||
editBox:SetScript("OnMouseDown", OnReceiveDrag)
|
||||
editBox:SetScript("OnReceiveDrag", OnReceiveDrag)
|
||||
editBox:SetScript("OnTextChanged", OnTextChanged)
|
||||
editBox:SetScript("OnTextSet", OnTextSet)
|
||||
|
||||
scrollFrame:SetScrollChild(editBox)
|
||||
|
||||
local widget = {
|
||||
button = button,
|
||||
editBox = editBox,
|
||||
frame = frame,
|
||||
label = label,
|
||||
labelHeight = 10,
|
||||
numlines = 4,
|
||||
scrollBar = scrollBar,
|
||||
scrollBG = scrollBG,
|
||||
scrollFrame = scrollFrame,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
button.obj, editBox.obj, scrollFrame.obj = widget, widget, widget
|
||||
|
||||
return AceGUI:RegisterAsWidget(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type, Constructor, Version)
|
||||
281
MogIt/Libs/AceGUI-3.0/widgets/AceGUIWidget-Slider.lua
Normal file
@@ -0,0 +1,281 @@
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Slider Widget
|
||||
Graphical Slider, like, for Range values.
|
||||
-------------------------------------------------------------------------------]]
|
||||
local Type, Version = "Slider", 20
|
||||
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
|
||||
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
|
||||
|
||||
-- Lua APIs
|
||||
local min, max, floor = math.min, math.max, math.floor
|
||||
local tonumber, pairs = tonumber, pairs
|
||||
|
||||
-- WoW APIs
|
||||
local PlaySound = PlaySound
|
||||
local CreateFrame, UIParent = CreateFrame, UIParent
|
||||
|
||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||
-- List them here for Mikk's FindGlobals script
|
||||
-- GLOBALS: GameFontHighlightSmall
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Support functions
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function UpdateText(self)
|
||||
local value = self.value or 0
|
||||
if self.ispercent then
|
||||
self.editbox:SetText(("%s%%"):format(floor(value * 1000 + 0.5) / 10))
|
||||
else
|
||||
self.editbox:SetText(floor(value * 100 + 0.5) / 100)
|
||||
end
|
||||
end
|
||||
|
||||
local function UpdateLabels(self)
|
||||
local min, max = (self.min or 0), (self.max or 100)
|
||||
if self.ispercent then
|
||||
self.lowtext:SetFormattedText("%s%%", (min * 100))
|
||||
self.hightext:SetFormattedText("%s%%", (max * 100))
|
||||
else
|
||||
self.lowtext:SetText(min)
|
||||
self.hightext:SetText(max)
|
||||
end
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Scripts
|
||||
-------------------------------------------------------------------------------]]
|
||||
local function Control_OnEnter(frame)
|
||||
frame.obj:Fire("OnEnter")
|
||||
end
|
||||
|
||||
local function Control_OnLeave(frame)
|
||||
frame.obj:Fire("OnLeave")
|
||||
end
|
||||
|
||||
local function Frame_OnMouseDown(frame)
|
||||
frame.obj.slider:EnableMouseWheel(true)
|
||||
AceGUI:ClearFocus()
|
||||
end
|
||||
|
||||
local function Slider_OnValueChanged(frame)
|
||||
local self = frame.obj
|
||||
if not frame.setup then
|
||||
local newvalue = frame:GetValue()
|
||||
if newvalue ~= self.value and not self.disabled then
|
||||
self.value = newvalue
|
||||
self:Fire("OnValueChanged", newvalue)
|
||||
end
|
||||
if self.value then
|
||||
UpdateText(self)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function Slider_OnMouseUp(frame)
|
||||
local self = frame.obj
|
||||
self:Fire("OnMouseUp", self.value)
|
||||
end
|
||||
|
||||
local function Slider_OnMouseWheel(frame, v)
|
||||
local self = frame.obj
|
||||
if not self.disabled then
|
||||
local value = self.value
|
||||
if v > 0 then
|
||||
value = min(value + (self.step or 1), self.max)
|
||||
else
|
||||
value = max(value - (self.step or 1), self.min)
|
||||
end
|
||||
self.slider:SetValue(value)
|
||||
end
|
||||
end
|
||||
|
||||
local function EditBox_OnEscapePressed(frame)
|
||||
frame:ClearFocus()
|
||||
end
|
||||
|
||||
local function EditBox_OnEnterPressed(frame)
|
||||
local self = frame.obj
|
||||
local value = frame:GetText()
|
||||
if self.ispercent then
|
||||
value = value:gsub('%%', '')
|
||||
value = tonumber(value) / 100
|
||||
else
|
||||
value = tonumber(value)
|
||||
end
|
||||
|
||||
if value then
|
||||
PlaySound("igMainMenuOptionCheckBoxOn")
|
||||
self.slider:SetValue(value)
|
||||
self:Fire("OnMouseUp", value)
|
||||
end
|
||||
end
|
||||
|
||||
local function EditBox_OnEnter(frame)
|
||||
frame:SetBackdropBorderColor(0.5, 0.5, 0.5, 1)
|
||||
end
|
||||
|
||||
local function EditBox_OnLeave(frame)
|
||||
frame:SetBackdropBorderColor(0.3, 0.3, 0.3, 0.8)
|
||||
end
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Methods
|
||||
-------------------------------------------------------------------------------]]
|
||||
local methods = {
|
||||
["OnAcquire"] = function(self)
|
||||
self:SetWidth(200)
|
||||
self:SetHeight(44)
|
||||
self:SetDisabled(false)
|
||||
self:SetIsPercent(nil)
|
||||
self:SetSliderValues(0,100,1)
|
||||
self:SetValue(0)
|
||||
self.slider:EnableMouseWheel(false)
|
||||
end,
|
||||
|
||||
-- ["OnRelease"] = nil,
|
||||
|
||||
["SetDisabled"] = function(self, disabled)
|
||||
self.disabled = disabled
|
||||
if disabled then
|
||||
self.slider:EnableMouse(false)
|
||||
self.label:SetTextColor(.5, .5, .5)
|
||||
self.hightext:SetTextColor(.5, .5, .5)
|
||||
self.lowtext:SetTextColor(.5, .5, .5)
|
||||
--self.valuetext:SetTextColor(.5, .5, .5)
|
||||
self.editbox:SetTextColor(.5, .5, .5)
|
||||
self.editbox:EnableMouse(false)
|
||||
self.editbox:ClearFocus()
|
||||
else
|
||||
self.slider:EnableMouse(true)
|
||||
self.label:SetTextColor(1, .82, 0)
|
||||
self.hightext:SetTextColor(1, 1, 1)
|
||||
self.lowtext:SetTextColor(1, 1, 1)
|
||||
--self.valuetext:SetTextColor(1, 1, 1)
|
||||
self.editbox:SetTextColor(1, 1, 1)
|
||||
self.editbox:EnableMouse(true)
|
||||
end
|
||||
end,
|
||||
|
||||
["SetValue"] = function(self, value)
|
||||
self.slider.setup = true
|
||||
self.slider:SetValue(value)
|
||||
self.value = value
|
||||
UpdateText(self)
|
||||
self.slider.setup = nil
|
||||
end,
|
||||
|
||||
["GetValue"] = function(self)
|
||||
return self.value
|
||||
end,
|
||||
|
||||
["SetLabel"] = function(self, text)
|
||||
self.label:SetText(text)
|
||||
end,
|
||||
|
||||
["SetSliderValues"] = function(self, min, max, step)
|
||||
local frame = self.slider
|
||||
frame.setup = true
|
||||
self.min = min
|
||||
self.max = max
|
||||
self.step = step
|
||||
frame:SetMinMaxValues(min or 0,max or 100)
|
||||
UpdateLabels(self)
|
||||
frame:SetValueStep(step or 1)
|
||||
if self.value then
|
||||
frame:SetValue(self.value)
|
||||
end
|
||||
frame.setup = nil
|
||||
end,
|
||||
|
||||
["SetIsPercent"] = function(self, value)
|
||||
self.ispercent = value
|
||||
UpdateLabels(self)
|
||||
UpdateText(self)
|
||||
end
|
||||
}
|
||||
|
||||
--[[-----------------------------------------------------------------------------
|
||||
Constructor
|
||||
-------------------------------------------------------------------------------]]
|
||||
local SliderBackdrop = {
|
||||
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 }
|
||||
}
|
||||
|
||||
local ManualBackdrop = {
|
||||
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
|
||||
edgeFile = "Interface\\ChatFrame\\ChatFrameBackground",
|
||||
tile = true, edgeSize = 1, tileSize = 5,
|
||||
}
|
||||
|
||||
local function Constructor()
|
||||
local frame = CreateFrame("Frame", nil, UIParent)
|
||||
|
||||
frame:EnableMouse(true)
|
||||
frame:SetScript("OnMouseDown", Frame_OnMouseDown)
|
||||
|
||||
local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
||||
label:SetPoint("TOPLEFT")
|
||||
label:SetPoint("TOPRIGHT")
|
||||
label:SetJustifyH("CENTER")
|
||||
label:SetHeight(15)
|
||||
|
||||
local slider = CreateFrame("Slider", nil, frame)
|
||||
slider:SetOrientation("HORIZONTAL")
|
||||
slider:SetHeight(15)
|
||||
slider:SetHitRectInsets(0, 0, -10, 0)
|
||||
slider:SetBackdrop(SliderBackdrop)
|
||||
slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Horizontal")
|
||||
slider:SetPoint("TOP", label, "BOTTOM")
|
||||
slider:SetPoint("LEFT", 3, 0)
|
||||
slider:SetPoint("RIGHT", -3, 0)
|
||||
slider:SetValue(0)
|
||||
slider:SetScript("OnValueChanged",Slider_OnValueChanged)
|
||||
slider:SetScript("OnEnter", Control_OnEnter)
|
||||
slider:SetScript("OnLeave", Control_OnLeave)
|
||||
slider:SetScript("OnMouseUp", Slider_OnMouseUp)
|
||||
slider:SetScript("OnMouseWheel", Slider_OnMouseWheel)
|
||||
|
||||
local lowtext = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
|
||||
lowtext:SetPoint("TOPLEFT", slider, "BOTTOMLEFT", 2, 3)
|
||||
|
||||
local hightext = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
|
||||
hightext:SetPoint("TOPRIGHT", slider, "BOTTOMRIGHT", -2, 3)
|
||||
|
||||
local editbox = CreateFrame("EditBox", nil, frame)
|
||||
editbox:SetAutoFocus(false)
|
||||
editbox:SetFontObject(GameFontHighlightSmall)
|
||||
editbox:SetPoint("TOP", slider, "BOTTOM")
|
||||
editbox:SetHeight(14)
|
||||
editbox:SetWidth(70)
|
||||
editbox:SetJustifyH("CENTER")
|
||||
editbox:EnableMouse(true)
|
||||
editbox:SetBackdrop(ManualBackdrop)
|
||||
editbox:SetBackdropColor(0, 0, 0, 0.5)
|
||||
editbox:SetBackdropBorderColor(0.3, 0.3, 0.30, 0.80)
|
||||
editbox:SetScript("OnEnter", EditBox_OnEnter)
|
||||
editbox:SetScript("OnLeave", EditBox_OnLeave)
|
||||
editbox:SetScript("OnEnterPressed", EditBox_OnEnterPressed)
|
||||
editbox:SetScript("OnEscapePressed", EditBox_OnEscapePressed)
|
||||
|
||||
local widget = {
|
||||
label = label,
|
||||
slider = slider,
|
||||
lowtext = lowtext,
|
||||
hightext = hightext,
|
||||
editbox = editbox,
|
||||
alignoffset = 25,
|
||||
frame = frame,
|
||||
type = Type
|
||||
}
|
||||
for method, func in pairs(methods) do
|
||||
widget[method] = func
|
||||
end
|
||||
slider.obj, editbox.obj = widget, widget
|
||||
|
||||
return AceGUI:RegisterAsWidget(widget)
|
||||
end
|
||||
|
||||
AceGUI:RegisterWidgetType(Type,Constructor,Version)
|
||||
240
MogIt/Libs/CallbackHandler-1.0/CallbackHandler-1.0.lua
Normal file
@@ -0,0 +1,240 @@
|
||||
--[[ $Id: CallbackHandler-1.0.lua 965 2010-08-09 00:47:52Z mikk $ ]]
|
||||
local MAJOR, MINOR = "CallbackHandler-1.0", 6
|
||||
local CallbackHandler = LibStub:NewLibrary(MAJOR, MINOR)
|
||||
|
||||
if not CallbackHandler then return end -- No upgrade needed
|
||||
|
||||
local meta = {__index = function(tbl, key) tbl[key] = {} return tbl[key] end}
|
||||
|
||||
-- Lua APIs
|
||||
local tconcat = table.concat
|
||||
local assert, error, loadstring = assert, error, loadstring
|
||||
local setmetatable, rawset, rawget = setmetatable, rawset, rawget
|
||||
local next, select, pairs, type, tostring = next, select, pairs, type, tostring
|
||||
|
||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||
-- List them here for Mikk's FindGlobals script
|
||||
-- GLOBALS: geterrorhandler
|
||||
|
||||
local xpcall = xpcall
|
||||
|
||||
local function errorhandler(err)
|
||||
return geterrorhandler()(err)
|
||||
end
|
||||
|
||||
local function CreateDispatcher(argCount)
|
||||
local code = [[
|
||||
local next, xpcall, eh = ...
|
||||
|
||||
local method, ARGS
|
||||
local function call() method(ARGS) end
|
||||
|
||||
local function dispatch(handlers, ...)
|
||||
local index
|
||||
index, method = next(handlers)
|
||||
if not method then return end
|
||||
local OLD_ARGS = ARGS
|
||||
ARGS = ...
|
||||
repeat
|
||||
xpcall(call, eh)
|
||||
index, method = next(handlers, index)
|
||||
until not method
|
||||
ARGS = OLD_ARGS
|
||||
end
|
||||
|
||||
return dispatch
|
||||
]]
|
||||
|
||||
local ARGS, OLD_ARGS = {}, {}
|
||||
for i = 1, argCount do ARGS[i], OLD_ARGS[i] = "arg"..i, "old_arg"..i end
|
||||
code = code:gsub("OLD_ARGS", tconcat(OLD_ARGS, ", ")):gsub("ARGS", tconcat(ARGS, ", "))
|
||||
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(next, xpcall, errorhandler)
|
||||
end
|
||||
|
||||
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
|
||||
local dispatcher = CreateDispatcher(argCount)
|
||||
rawset(self, argCount, dispatcher)
|
||||
return dispatcher
|
||||
end})
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- CallbackHandler:New
|
||||
--
|
||||
-- target - target object to embed public APIs in
|
||||
-- RegisterName - name of the callback registration API, default "RegisterCallback"
|
||||
-- UnregisterName - name of the callback unregistration API, default "UnregisterCallback"
|
||||
-- UnregisterAllName - name of the API to unregister all callbacks, default "UnregisterAllCallbacks". false == don't publish this API.
|
||||
|
||||
function CallbackHandler:New(target, RegisterName, UnregisterName, UnregisterAllName, OnUsed, OnUnused)
|
||||
-- TODO: Remove this after beta has gone out
|
||||
assert(not OnUsed and not OnUnused, "ACE-80: OnUsed/OnUnused are deprecated. Callbacks are now done to registry.OnUsed and registry.OnUnused")
|
||||
|
||||
RegisterName = RegisterName or "RegisterCallback"
|
||||
UnregisterName = UnregisterName or "UnregisterCallback"
|
||||
if UnregisterAllName==nil then -- false is used to indicate "don't want this method"
|
||||
UnregisterAllName = "UnregisterAllCallbacks"
|
||||
end
|
||||
|
||||
-- we declare all objects and exported APIs inside this closure to quickly gain access
|
||||
-- to e.g. function names, the "target" parameter, etc
|
||||
|
||||
|
||||
-- Create the registry object
|
||||
local events = setmetatable({}, meta)
|
||||
local registry = { recurse=0, events=events }
|
||||
|
||||
-- registry:Fire() - fires the given event/message into the registry
|
||||
function registry:Fire(eventname, ...)
|
||||
if not rawget(events, eventname) or not next(events[eventname]) then return end
|
||||
local oldrecurse = registry.recurse
|
||||
registry.recurse = oldrecurse + 1
|
||||
|
||||
Dispatchers[select('#', ...) + 1](events[eventname], eventname, ...)
|
||||
|
||||
registry.recurse = oldrecurse
|
||||
|
||||
if registry.insertQueue and oldrecurse==0 then
|
||||
-- Something in one of our callbacks wanted to register more callbacks; they got queued
|
||||
for eventname,callbacks in pairs(registry.insertQueue) do
|
||||
local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
|
||||
for self,func in pairs(callbacks) do
|
||||
events[eventname][self] = func
|
||||
-- fire OnUsed callback?
|
||||
if first and registry.OnUsed then
|
||||
registry.OnUsed(registry, target, eventname)
|
||||
first = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
registry.insertQueue = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Registration of a callback, handles:
|
||||
-- self["method"], leads to self["method"](self, ...)
|
||||
-- self with function ref, leads to functionref(...)
|
||||
-- "addonId" (instead of self) with function ref, leads to functionref(...)
|
||||
-- all with an optional arg, which, if present, gets passed as first argument (after self if present)
|
||||
target[RegisterName] = function(self, eventname, method, ... --[[actually just a single arg]])
|
||||
if type(eventname) ~= "string" then
|
||||
error("Usage: "..RegisterName.."(eventname, method[, arg]): 'eventname' - string expected.", 2)
|
||||
end
|
||||
|
||||
method = method or eventname
|
||||
|
||||
local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
|
||||
|
||||
if type(method) ~= "string" and type(method) ~= "function" then
|
||||
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - string or function expected.", 2)
|
||||
end
|
||||
|
||||
local regfunc
|
||||
|
||||
if type(method) == "string" then
|
||||
-- self["method"] calling style
|
||||
if type(self) ~= "table" then
|
||||
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): self was not a table?", 2)
|
||||
elseif self==target then
|
||||
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): do not use Library:"..RegisterName.."(), use your own 'self'", 2)
|
||||
elseif type(self[method]) ~= "function" then
|
||||
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - method '"..tostring(method).."' not found on self.", 2)
|
||||
end
|
||||
|
||||
if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
|
||||
local arg=select(1,...)
|
||||
regfunc = function(...) self[method](self,arg,...) end
|
||||
else
|
||||
regfunc = function(...) self[method](self,...) end
|
||||
end
|
||||
else
|
||||
-- function ref with self=object or self="addonId" or self=thread
|
||||
if type(self)~="table" and type(self)~="string" and type(self)~="thread" then
|
||||
error("Usage: "..RegisterName.."(self or \"addonId\", eventname, method): 'self or addonId': table or string or thread expected.", 2)
|
||||
end
|
||||
|
||||
if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
|
||||
local arg=select(1,...)
|
||||
regfunc = function(...) method(arg,...) end
|
||||
else
|
||||
regfunc = method
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if events[eventname][self] or registry.recurse<1 then
|
||||
-- if registry.recurse<1 then
|
||||
-- we're overwriting an existing entry, or not currently recursing. just set it.
|
||||
events[eventname][self] = regfunc
|
||||
-- fire OnUsed callback?
|
||||
if registry.OnUsed and first then
|
||||
registry.OnUsed(registry, target, eventname)
|
||||
end
|
||||
else
|
||||
-- we're currently processing a callback in this registry, so delay the registration of this new entry!
|
||||
-- yes, we're a bit wasteful on garbage, but this is a fringe case, so we're picking low implementation overhead over garbage efficiency
|
||||
registry.insertQueue = registry.insertQueue or setmetatable({},meta)
|
||||
registry.insertQueue[eventname][self] = regfunc
|
||||
end
|
||||
end
|
||||
|
||||
-- Unregister a callback
|
||||
target[UnregisterName] = function(self, eventname)
|
||||
if not self or self==target then
|
||||
error("Usage: "..UnregisterName.."(eventname): bad 'self'", 2)
|
||||
end
|
||||
if type(eventname) ~= "string" then
|
||||
error("Usage: "..UnregisterName.."(eventname): 'eventname' - string expected.", 2)
|
||||
end
|
||||
if rawget(events, eventname) and events[eventname][self] then
|
||||
events[eventname][self] = nil
|
||||
-- Fire OnUnused callback?
|
||||
if registry.OnUnused and not next(events[eventname]) then
|
||||
registry.OnUnused(registry, target, eventname)
|
||||
end
|
||||
end
|
||||
if registry.insertQueue and rawget(registry.insertQueue, eventname) and registry.insertQueue[eventname][self] then
|
||||
registry.insertQueue[eventname][self] = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- OPTIONAL: Unregister all callbacks for given selfs/addonIds
|
||||
if UnregisterAllName then
|
||||
target[UnregisterAllName] = function(...)
|
||||
if select("#",...)<1 then
|
||||
error("Usage: "..UnregisterAllName.."([whatFor]): missing 'self' or \"addonId\" to unregister events for.", 2)
|
||||
end
|
||||
if select("#",...)==1 and ...==target then
|
||||
error("Usage: "..UnregisterAllName.."([whatFor]): supply a meaningful 'self' or \"addonId\"", 2)
|
||||
end
|
||||
|
||||
|
||||
for i=1,select("#",...) do
|
||||
local self = select(i,...)
|
||||
if registry.insertQueue then
|
||||
for eventname, callbacks in pairs(registry.insertQueue) do
|
||||
if callbacks[self] then
|
||||
callbacks[self] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
for eventname, callbacks in pairs(events) do
|
||||
if callbacks[self] then
|
||||
callbacks[self] = nil
|
||||
-- Fire OnUnused callback?
|
||||
if registry.OnUnused and not next(callbacks) then
|
||||
registry.OnUnused(registry, target, eventname)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return registry
|
||||
end
|
||||
|
||||
|
||||
-- CallbackHandler purposefully does NOT do explicit embedding. Nor does it
|
||||
-- try to upgrade old implicit embeds since the system is selfcontained and
|
||||
-- relies on closures to work.
|
||||
|
||||
4
MogIt/Libs/CallbackHandler-1.0/CallbackHandler-1.0.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
..\FrameXML\UI.xsd">
|
||||
<Script file="CallbackHandler-1.0.lua"/>
|
||||
</Ui>
|
||||
26
MogIt/Libs/Embeds.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
..\FrameXML\UI.xsd">
|
||||
|
||||
<Script file="LibStub\LibStub.lua"/>
|
||||
<Include file="CallbackHandler-1.0\CallbackHandler-1.0.xml"/>
|
||||
|
||||
<Include file="AceGUI-3.0\AceGUI-3.0.xml"/>
|
||||
<Include file="AceConfig-3.0\AceConfig-3.0.xml"/>
|
||||
<Include file="AceDB-3.0\AceDB-3.0.xml"/>
|
||||
<Include file="AceDBOptions-3.0\AceDBOptions-3.0.xml"/>
|
||||
|
||||
<Include file="LibAddonInfo-1.0\lib.xml"/>
|
||||
|
||||
<Script file="LibDataBroker-1.1\LibDataBroker-1.1.lua"/>
|
||||
<Script file="LibDBIcon-1.0\LibDBIcon-1.0.lua"/>
|
||||
|
||||
<Include file="LibBabble-Boss-3.0\lib.xml"/>
|
||||
<Include file="LibBabble-Inventory-3.0\lib.xml"/>
|
||||
<Include file="LibBabble-Race-3.0\lib.xml"/>
|
||||
|
||||
<Include file="Libra\Libra.xml"/>
|
||||
|
||||
<Script file="LibItemInfo-1.0\LibItemInfo-1.0.lua"/>
|
||||
|
||||
</Ui>
|
||||
219
MogIt/Libs/LibAddonInfo-1.0/LibAddonInfo-1.0.lua
Normal file
@@ -0,0 +1,219 @@
|
||||
local lib,old = LibStub:NewLibrary("LibAddonInfo-1.0",1);
|
||||
if not lib then return end
|
||||
|
||||
local L = {};
|
||||
local locale = GetLocale();
|
||||
-- frFR
|
||||
if locale == "frFR" then
|
||||
L["About"] = "à propos de";
|
||||
L["Click and press Ctrl-C to copy"] = "Click and press Ctrl-C to copy";
|
||||
-- deDE
|
||||
elseif locale == "deDE" then
|
||||
L["About"] = "Über";
|
||||
L["Click and press Ctrl-C to copy"] = "Klicken und Strg-C drücken zum kopieren";
|
||||
-- esES
|
||||
elseif locale == "esES" then
|
||||
L["About"] = "Acerca de";
|
||||
L["Click and press Ctrl-C to copy"] = "Click and press Ctrl-C to copy";
|
||||
-- esMX
|
||||
elseif locale == "esMX" then
|
||||
L["About"] = "Sobre";
|
||||
L["Click and press Ctrl-C to copy"] = "Click and press Ctrl-C to copy";
|
||||
-- koKR
|
||||
elseif locale == "koKR" then
|
||||
L["About"] = "대하여";
|
||||
L["Click and press Ctrl-C to copy"] = "클릭 후 Ctrl-C 복사";
|
||||
-- ruRU
|
||||
elseif locale == "ruRU" then
|
||||
L["About"] = "Об аддоне";
|
||||
L["Click and press Ctrl-C to copy"] = "Click and press Ctrl-C to copy";
|
||||
-- zhCN
|
||||
elseif locale == "zhCN" then
|
||||
L["About"] = "关于";
|
||||
L["Click and press Ctrl-C to copy"] = "点击并 Ctrl-C 复制";
|
||||
-- zhTW
|
||||
elseif locale == "zhTW" then
|
||||
L["About"] = "關於";
|
||||
L["Click and press Ctrl-C to copy"] = "左鍵點擊並按下 Ctrl-C 以複製字串";
|
||||
-- enUS and non-localized
|
||||
else
|
||||
L["About"] ="About";
|
||||
L["Click and press Ctrl-C to copy"] = "Click and press Ctrl-C to copy";
|
||||
end
|
||||
|
||||
function lib:CreateFrame(addon,parent,path)
|
||||
local frame = CreateFrame("Frame",nil,UIParent);
|
||||
frame:Hide();
|
||||
frame.addon = addon:gsub(" ","");
|
||||
frame.name = parent and L["About"] or frame.addon;
|
||||
frame.parent = parent;
|
||||
frame.path = path;
|
||||
InterfaceOptions_AddCategory(frame);
|
||||
|
||||
lib:CreateLayout(frame);
|
||||
return frame;
|
||||
end
|
||||
|
||||
local editbox = CreateFrame('EditBox',nil,UIParent);
|
||||
editbox:Hide();
|
||||
editbox:SetAutoFocus(true);
|
||||
editbox:SetHeight(32);
|
||||
editbox:SetFontObject('GameFontHighlightSmall');
|
||||
|
||||
local left = editbox:CreateTexture(nil,"BACKGROUND");
|
||||
left:SetSize(8,20);
|
||||
left:SetPoint("LEFT",-5,0);
|
||||
left:SetTexture("Interface\\Common\\Common-Input-Border");
|
||||
left:SetTexCoord(0,0.0625,0,0.625);
|
||||
|
||||
local right = editbox:CreateTexture(nil,"BACKGROUND");
|
||||
right:SetSize(8,20);
|
||||
right:SetPoint("RIGHT",0,0);
|
||||
right:SetTexture("Interface\\Common\\Common-Input-Border");
|
||||
right:SetTexCoord(0.9375,1,0,0.625);
|
||||
|
||||
local center = editbox:CreateTexture(nil,"BACKGROUND");
|
||||
center:SetHeight(20);
|
||||
center:SetPoint("RIGHT",right,"LEFT",0,0);
|
||||
center:SetPoint("LEFT",left,"RIGHT",0,0);
|
||||
center:SetTexture("Interface\\Common\\Common-Input-Border");
|
||||
center:SetTexCoord(0.0625,0.9375,0,0.625);
|
||||
|
||||
editbox:SetScript("OnEscapePressed",editbox.ClearFocus);
|
||||
editbox:SetScript("OnEnterPressed",editbox.ClearFocus);
|
||||
editbox:SetScript("OnEditFocusLost",editbox.Hide);
|
||||
editbox:SetScript("OnEditFocusGained",editbox.HighlightText);
|
||||
editbox:SetScript("OnTextChanged",function(self)
|
||||
self:SetText(self:GetParent().value);
|
||||
self:HighlightText();
|
||||
end);
|
||||
|
||||
local function EditBoxEnter(self)
|
||||
GameTooltip:SetOwner(self,"ANCHOR_TOPRIGHT");
|
||||
GameTooltip:SetText(L["Click and press Ctrl-C to copy"]);
|
||||
end
|
||||
|
||||
local function EditBoxLeave()
|
||||
GameTooltip:Hide();
|
||||
end
|
||||
|
||||
local function EditBoxShow(self)
|
||||
editbox:SetText(self.value);
|
||||
editbox:SetParent(self);
|
||||
editbox:SetPoint("LEFT",self);
|
||||
editbox:SetPoint("RIGHT",self);
|
||||
editbox:Show();
|
||||
end
|
||||
|
||||
local fields = {"Version", "Author", "X-Category", "X-License", "X-Email", "Email", "eMail", "X-Website", "X-Credits", "X-Localizations", "X-Donate"};
|
||||
local haseditbox = {["X-Website"] = true, ["X-Email"] = true, ["Email"] = true, ["eMail"] = true, ["X-Donate"] = true};
|
||||
|
||||
local path;
|
||||
local flags = {
|
||||
["enus"] = "English",
|
||||
["frfr"] = "French",
|
||||
["dede"] = "German",
|
||||
["eses"] = "Spanish",
|
||||
["esmx"] = "Latin American Spanish",
|
||||
["ruru"] = "Russian",
|
||||
["kokr"] = "Korean",
|
||||
["zhcn"] = "Simplified Chinese",
|
||||
["zhtw"] = "Traditional Chinese",
|
||||
["ptbr"] = "Brazilian Portuguese",
|
||||
["itit"] = "Italian",
|
||||
};
|
||||
local function FormatLocale(newline,str)
|
||||
local output;
|
||||
local flag = str:lower();
|
||||
if flags[flag] then
|
||||
if path then
|
||||
output = "|T"..path.."\\"..flag..":16|t ";
|
||||
else
|
||||
output = "";
|
||||
end
|
||||
output = output..flags[flag];
|
||||
end
|
||||
return (newline > "" and "\n" or "")..(output or str);
|
||||
end
|
||||
|
||||
function lib:CreateLayout(frame)
|
||||
frame.title = frame:CreateFontString(nil,"ARTWORK","GameFontNormalLarge");
|
||||
frame.title:SetPoint("TOPLEFT",16,-16)
|
||||
frame.title:SetText(frame.name);
|
||||
|
||||
local notes = "Notes";
|
||||
if (locale ~= "enUS") then
|
||||
notes = notes.."-"..locale;
|
||||
end
|
||||
notes = GetAddOnMetadata(frame.addon,notes) or GetAddOnMetadata(frame.addon,"Notes");
|
||||
frame.notes = frame:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall");
|
||||
frame.notes:SetHeight(32);
|
||||
frame.notes:SetPoint("TOPLEFT",frame.title,"BOTTOMLEFT",0,-8);
|
||||
frame.notes:SetPoint("RIGHT",frame,-32,0);
|
||||
frame.notes:SetNonSpaceWrap(true);
|
||||
frame.notes:SetJustifyH("LEFT");
|
||||
frame.notes:SetJustifyV("TOP");
|
||||
frame.notes:SetText(notes or "");
|
||||
|
||||
frame.label = {};
|
||||
frame.info = {};
|
||||
|
||||
local anchor;
|
||||
for _,field in ipairs(fields) do
|
||||
local value = GetAddOnMetadata(frame.addon,field);
|
||||
if value then
|
||||
frame.label[field] = frame:CreateFontString(nil,"ARTWORK","GameFontNormalSmall");
|
||||
frame.label[field]:SetWidth(75);
|
||||
frame.label[field]:SetJustifyH("RIGHT");
|
||||
frame.label[field]:SetText(field:gsub("X%-",""));
|
||||
if not anchor then
|
||||
frame.label[field]:SetPoint("TOPLEFT",frame.notes,"BOTTOMLEFT",-2,-12);
|
||||
else
|
||||
frame.label[field]:SetPoint("TOPRIGHT",anchor,"BOTTOMLEFT",-4,-10);
|
||||
end
|
||||
|
||||
frame.info[field] = frame:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall");
|
||||
frame.info[field]:SetPoint("TOPLEFT",frame.label[field],"TOPRIGHT",4,0);
|
||||
frame.info[field]:SetPoint("RIGHT",frame,-16,0);
|
||||
frame.info[field]:SetJustifyH("LEFT");
|
||||
frame.info[field]:SetJustifyV("TOP");
|
||||
frame.info[field]:SetNonSpaceWrap(true);
|
||||
|
||||
value = value:gsub("^%s*","");
|
||||
value = value:gsub("%s*$","");
|
||||
if field == "Author" then
|
||||
value = value:gsub("%s*[,&]%s*","\n");
|
||||
elseif field == "Version" then
|
||||
value = value:gsub("@project.revision@","Repository");
|
||||
elseif field == "X-Localizations" then
|
||||
path = frame.path;
|
||||
value = value:gsub("(,?)%s*([^,]+)%s*",FormatLocale);
|
||||
--value = value:gsub("%s*[,]%s*","\n");
|
||||
end
|
||||
value = (haseditbox[field] and "|cff9999ff" or "")..value;
|
||||
frame.info[field]:SetText(value);
|
||||
|
||||
if haseditbox[field] then
|
||||
local button = CreateFrame("Button",nil,frame);
|
||||
button:SetAllPoints(frame.info[field]);
|
||||
button.value = value;
|
||||
button:SetScript("OnClick",EditBoxShow);
|
||||
button:SetScript("OnEnter",EditBoxEnter);
|
||||
button:SetScript("OnLeave",EditBoxLeave);
|
||||
end
|
||||
|
||||
anchor = frame.info[field];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- make work for 2nd pass layout
|
||||
-- make work for frame as input in create
|
||||
-- custom fields
|
||||
-- function/str for fields and/or editboxes
|
||||
|
||||
4
MogIt/Libs/LibAddonInfo-1.0/lib.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
..\FrameXML\UI.xsd">
|
||||
<Script file="LibAddonInfo-1.0.lua" />
|
||||
</Ui>
|
||||
@@ -0,0 +1,38 @@
|
||||
------------------------------------------------------------------------
|
||||
r305 | nevcairiel | 2010-10-10 12:18:04 +0000 (Sun, 10 Oct 2010) | 1 line
|
||||
Changed paths:
|
||||
A /tags/3.3-release42 (from /trunk:304)
|
||||
|
||||
Weekly Tag - #42
|
||||
------------------------------------------------------------------------
|
||||
r304 | nevcairiel | 2010-10-10 12:17:44 +0000 (Sun, 10 Oct 2010) | 1 line
|
||||
Changed paths:
|
||||
M /trunk/LibBabble-Boss-3.0.lua
|
||||
|
||||
Automated LibBabble re-generation from the localization system
|
||||
------------------------------------------------------------------------
|
||||
r302 | nevcairiel | 2010-09-18 12:45:36 +0000 (Sat, 18 Sep 2010) | 1 line
|
||||
Changed paths:
|
||||
M /trunk/LibBabble-Boss-3.0.lua
|
||||
|
||||
Automated LibBabble re-generation from the localization system
|
||||
------------------------------------------------------------------------
|
||||
r301 | nevcairiel | 2010-09-12 12:37:10 +0000 (Sun, 12 Sep 2010) | 1 line
|
||||
Changed paths:
|
||||
M /trunk/LibBabble-Boss-3.0.lua
|
||||
|
||||
Automated LibBabble re-generation from the localization system
|
||||
------------------------------------------------------------------------
|
||||
r300 | nevcairiel | 2010-09-12 12:29:18 +0000 (Sun, 12 Sep 2010) | 1 line
|
||||
Changed paths:
|
||||
M /trunk/.pkgmeta
|
||||
D /trunk/LibStub
|
||||
|
||||
Remove hard-embeded LibStub
|
||||
------------------------------------------------------------------------
|
||||
r298 | nevcairiel | 2010-09-10 17:22:40 +0000 (Fri, 10 Sep 2010) | 1 line
|
||||
Changed paths:
|
||||
M /trunk/LibBabble-Boss-3.0.lua
|
||||
|
||||
Automated LibBabble re-generation from the localization system
|
||||
------------------------------------------------------------------------
|
||||
292
MogIt/Libs/LibBabble-Boss-3.0/LibBabble-3.0.lua
Normal file
@@ -0,0 +1,292 @@
|
||||
-- LibBabble-3.0 is hereby placed in the Public Domain
|
||||
-- Credits: ckknight
|
||||
local LIBBABBLE_MAJOR, LIBBABBLE_MINOR = "LibBabble-3.0", 2
|
||||
|
||||
local LibBabble = LibStub:NewLibrary(LIBBABBLE_MAJOR, LIBBABBLE_MINOR)
|
||||
if not LibBabble then
|
||||
return
|
||||
end
|
||||
|
||||
local data = LibBabble.data or {}
|
||||
for k,v in pairs(LibBabble) do
|
||||
LibBabble[k] = nil
|
||||
end
|
||||
LibBabble.data = data
|
||||
|
||||
local tablesToDB = {}
|
||||
for namespace, db in pairs(data) do
|
||||
for k,v in pairs(db) do
|
||||
tablesToDB[v] = db
|
||||
end
|
||||
end
|
||||
|
||||
local function warn(message)
|
||||
local _, ret = pcall(error, message, 3)
|
||||
geterrorhandler()(ret)
|
||||
end
|
||||
|
||||
local lookup_mt = { __index = function(self, key)
|
||||
local db = tablesToDB[self]
|
||||
local current_key = db.current[key]
|
||||
if current_key then
|
||||
self[key] = current_key
|
||||
return current_key
|
||||
end
|
||||
local base_key = db.base[key]
|
||||
local real_MAJOR_VERSION
|
||||
for k,v in pairs(data) do
|
||||
if v == db then
|
||||
real_MAJOR_VERSION = k
|
||||
break
|
||||
end
|
||||
end
|
||||
if not real_MAJOR_VERSION then
|
||||
real_MAJOR_VERSION = LIBBABBLE_MAJOR
|
||||
end
|
||||
if base_key then
|
||||
warn(("%s: Translation %q not found for locale %q"):format(real_MAJOR_VERSION, key, GetLocale()))
|
||||
rawset(self, key, base_key)
|
||||
return base_key
|
||||
end
|
||||
warn(("%s: Translation %q not found."):format(real_MAJOR_VERSION, key))
|
||||
rawset(self, key, key)
|
||||
return key
|
||||
end }
|
||||
|
||||
local function initLookup(module, lookup)
|
||||
local db = tablesToDB[module]
|
||||
for k in pairs(lookup) do
|
||||
lookup[k] = nil
|
||||
end
|
||||
setmetatable(lookup, lookup_mt)
|
||||
tablesToDB[lookup] = db
|
||||
db.lookup = lookup
|
||||
return lookup
|
||||
end
|
||||
|
||||
local function initReverse(module, reverse)
|
||||
local db = tablesToDB[module]
|
||||
for k in pairs(reverse) do
|
||||
reverse[k] = nil
|
||||
end
|
||||
for k,v in pairs(db.current) do
|
||||
reverse[v] = k
|
||||
end
|
||||
tablesToDB[reverse] = db
|
||||
db.reverse = reverse
|
||||
db.reverseIterators = nil
|
||||
return reverse
|
||||
end
|
||||
|
||||
local prototype = {}
|
||||
local prototype_mt = {__index = prototype}
|
||||
|
||||
--[[---------------------------------------------------------------------------
|
||||
Notes:
|
||||
* If you try to access a nonexistent key, it will warn but allow the code to pass through.
|
||||
Returns:
|
||||
A lookup table for english to localized words.
|
||||
Example:
|
||||
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
|
||||
local BL = B:GetLookupTable()
|
||||
assert(BL["Some english word"] == "Some localized word")
|
||||
DoSomething(BL["Some english word that doesn't exist"]) -- warning!
|
||||
-----------------------------------------------------------------------------]]
|
||||
function prototype:GetLookupTable()
|
||||
local db = tablesToDB[self]
|
||||
|
||||
local lookup = db.lookup
|
||||
if lookup then
|
||||
return lookup
|
||||
end
|
||||
return initLookup(self, {})
|
||||
end
|
||||
--[[---------------------------------------------------------------------------
|
||||
Notes:
|
||||
* If you try to access a nonexistent key, it will return nil.
|
||||
Returns:
|
||||
A lookup table for english to localized words.
|
||||
Example:
|
||||
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
|
||||
local B_has = B:GetUnstrictLookupTable()
|
||||
assert(B_has["Some english word"] == "Some localized word")
|
||||
assert(B_has["Some english word that doesn't exist"] == nil)
|
||||
-----------------------------------------------------------------------------]]
|
||||
function prototype:GetUnstrictLookupTable()
|
||||
local db = tablesToDB[self]
|
||||
|
||||
return db.current
|
||||
end
|
||||
--[[---------------------------------------------------------------------------
|
||||
Notes:
|
||||
* If you try to access a nonexistent key, it will return nil.
|
||||
* This is useful for checking if the base (English) table has a key, even if the localized one does not have it registered.
|
||||
Returns:
|
||||
A lookup table for english to localized words.
|
||||
Example:
|
||||
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
|
||||
local B_hasBase = B:GetBaseLookupTable()
|
||||
assert(B_hasBase["Some english word"] == "Some english word")
|
||||
assert(B_hasBase["Some english word that doesn't exist"] == nil)
|
||||
-----------------------------------------------------------------------------]]
|
||||
function prototype:GetBaseLookupTable()
|
||||
local db = tablesToDB[self]
|
||||
|
||||
return db.base
|
||||
end
|
||||
--[[---------------------------------------------------------------------------
|
||||
Notes:
|
||||
* If you try to access a nonexistent key, it will return nil.
|
||||
* This will return only one English word that it maps to, if there are more than one to check, see :GetReverseIterator("word")
|
||||
Returns:
|
||||
A lookup table for localized to english words.
|
||||
Example:
|
||||
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
|
||||
local BR = B:GetReverseLookupTable()
|
||||
assert(BR["Some localized word"] == "Some english word")
|
||||
assert(BR["Some localized word that doesn't exist"] == nil)
|
||||
-----------------------------------------------------------------------------]]
|
||||
function prototype:GetReverseLookupTable()
|
||||
local db = tablesToDB[self]
|
||||
|
||||
local reverse = db.reverse
|
||||
if reverse then
|
||||
return reverse
|
||||
end
|
||||
return initReverse(self, {})
|
||||
end
|
||||
local blank = {}
|
||||
local weakVal = {__mode='v'}
|
||||
--[[---------------------------------------------------------------------------
|
||||
Arguments:
|
||||
string - the localized word to chek for.
|
||||
Returns:
|
||||
An iterator to traverse all English words that map to the given key
|
||||
Example:
|
||||
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
|
||||
for word in B:GetReverseIterator("Some localized word") do
|
||||
DoSomething(word)
|
||||
end
|
||||
-----------------------------------------------------------------------------]]
|
||||
function prototype:GetReverseIterator(key)
|
||||
local db = tablesToDB[self]
|
||||
local reverseIterators = db.reverseIterators
|
||||
if not reverseIterators then
|
||||
reverseIterators = setmetatable({}, weakVal)
|
||||
db.reverseIterators = reverseIterators
|
||||
elseif reverseIterators[key] then
|
||||
return pairs(reverseIterators[key])
|
||||
end
|
||||
local t
|
||||
for k,v in pairs(db.current) do
|
||||
if v == key then
|
||||
if not t then
|
||||
t = {}
|
||||
end
|
||||
t[k] = true
|
||||
end
|
||||
end
|
||||
reverseIterators[key] = t or blank
|
||||
return pairs(reverseIterators[key])
|
||||
end
|
||||
--[[---------------------------------------------------------------------------
|
||||
Returns:
|
||||
An iterator to traverse all translations English to localized.
|
||||
Example:
|
||||
local B = LibStub("LibBabble-Module-3.0") -- where Module is what you want.
|
||||
for english, localized in B:Iterate() do
|
||||
DoSomething(english, localized)
|
||||
end
|
||||
-----------------------------------------------------------------------------]]
|
||||
function prototype:Iterate()
|
||||
local db = tablesToDB[self]
|
||||
|
||||
return pairs(db.current)
|
||||
end
|
||||
|
||||
-- #NODOC
|
||||
-- modules need to call this to set the base table
|
||||
function prototype:SetBaseTranslations(base)
|
||||
local db = tablesToDB[self]
|
||||
local oldBase = db.base
|
||||
if oldBase then
|
||||
for k in pairs(oldBase) do
|
||||
oldBase[k] = nil
|
||||
end
|
||||
for k, v in pairs(base) do
|
||||
oldBase[k] = v
|
||||
end
|
||||
base = oldBase
|
||||
else
|
||||
db.base = base
|
||||
end
|
||||
for k,v in pairs(base) do
|
||||
if v == true then
|
||||
base[k] = k
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function init(module)
|
||||
local db = tablesToDB[module]
|
||||
if db.lookup then
|
||||
initLookup(module, db.lookup)
|
||||
end
|
||||
if db.reverse then
|
||||
initReverse(module, db.reverse)
|
||||
end
|
||||
db.reverseIterators = nil
|
||||
end
|
||||
|
||||
-- #NODOC
|
||||
-- modules need to call this to set the current table. if current is true, use the base table.
|
||||
function prototype:SetCurrentTranslations(current)
|
||||
local db = tablesToDB[self]
|
||||
if current == true then
|
||||
db.current = db.base
|
||||
else
|
||||
local oldCurrent = db.current
|
||||
if oldCurrent then
|
||||
for k in pairs(oldCurrent) do
|
||||
oldCurrent[k] = nil
|
||||
end
|
||||
for k, v in pairs(current) do
|
||||
oldCurrent[k] = v
|
||||
end
|
||||
current = oldCurrent
|
||||
else
|
||||
db.current = current
|
||||
end
|
||||
end
|
||||
init(self)
|
||||
end
|
||||
|
||||
for namespace, db in pairs(data) do
|
||||
setmetatable(db.module, prototype_mt)
|
||||
init(db.module)
|
||||
end
|
||||
|
||||
-- #NODOC
|
||||
-- modules need to call this to create a new namespace.
|
||||
function LibBabble:New(namespace, minor)
|
||||
local module, oldminor = LibStub:NewLibrary(namespace, minor)
|
||||
if not module then
|
||||
return
|
||||
end
|
||||
|
||||
if not oldminor then
|
||||
local db = {
|
||||
module = module,
|
||||
}
|
||||
data[namespace] = db
|
||||
tablesToDB[module] = db
|
||||
else
|
||||
for k,v in pairs(module) do
|
||||
module[k] = nil
|
||||
end
|
||||
end
|
||||
|
||||
setmetatable(module, prototype_mt)
|
||||
|
||||
return module
|
||||
end
|
||||