diff --git a/MogIt/Bindings.xml b/MogIt/Bindings.xml new file mode 100644 index 0000000..f3126d1 --- /dev/null +++ b/MogIt/Bindings.xml @@ -0,0 +1,14 @@ + + + MogIt:ToggleFrame() + + + MogIt:TogglePreview() + + + + \ No newline at end of file diff --git a/MogIt/Core/Core.lua b/MogIt/Core/Core.lua new file mode 100644 index 0000000..6c50ff9 --- /dev/null +++ b/MogIt/Core/Core.lua @@ -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 +--// diff --git a/MogIt/Core/Core.xml b/MogIt/Core/Core.xml new file mode 100644 index 0000000..63cf173 --- /dev/null +++ b/MogIt/Core/Core.xml @@ -0,0 +1,432 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + self:GetParent():SetVerticalScroll(value); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +