local _, addon = ... local CharacterProfile = addon.ProfileAPI; local TransmogDataProvider = addon.TransmogDataProvider; local L = Narci.L; local FadeFrame = NarciFadeUI.Fade; local GetEquipmentSlotByID = Narci.GetEquipmentSlotByID; local GetClassColorByClassID = NarciAPI.GetClassColorByClassID; local SmartSetActorName = NarciAPI.SmartSetActorName; local C_TransmogCollection = C_TransmogCollection; local After = C_Timer.After; local GetCursorPosition = GetCursorPosition; local UIParent = UIParent; local BUTTON_PER_PAGE = 8; local PIXEL = NarciAPI.GetPixelByScale(1); local IGNORE_NO_OUTFIT_CHARS = true; local MainFrame, ActivePreviewModel, CharacterList, FilterButton, SimpleTooltip; local PreviewModels = {}; local function Mixin(object, mixin) for k, v in pairs(mixin) do object[k] = v; end end local inOutSine = addon.EasingFunctions.inOutSine local outQuart = addon.EasingFunctions.outQuart; local outSine = addon.EasingFunctions.outSine; local ModelFileIDxUICameraID = { --Transmog-Set-Vendor [949470] = 1035, --Orc F [917116] = 1036, --Orc/Mag'har M Hunched [1968587] = 1036, --Mag'har Upright [1630218] = 1039, --Highmountain M [1630402] = 1040, --Highmountain F [940356] = 1029, --Gnome F [900914] = 1030, --Gnome M [2564806] = 1029, --Mechagnome F [2622502] = 1030, --Mechagnome M [1022598] = 1025, --Draenei F [1005887] = 1026, --Draenei M [1593999] = 1025, --Lightforged F [1620605] = 1026, --Lightforged M [589715] = 1037, --Pandaren F [535052] = 1038, --Pandaren M [986648] = 1039, --Tauren F [968705] = 1040, --Tauren M [997378] = 1043, --UD F [959310] = 1044, --UD M [1000764] = 1022, --Human F [1011653] = 996, --Human M [307453] = 1045, --Worgen-Wolf F [307454] = 1046, --Worgen-Wolf M [1890763] = 1027, --DarkIron F [1890765] = 1028, --DarkIron M [950080] = 1027, --Dwarf F [878772] = 1028, --Dwarf M [1733758] = 1023, --VE F [1734034] = 1024, --VE M [1100258] = 1023, --BE F [1100087] = 1024, --BE M [921844] = 1033, --NE F [974343] = 1034, --NE M [1018060] = 1041, --Troll F [1022938] = 1042, --Troll M [1886724] = 1387, --KulTiran F [1721003] = 1386, --KulTiran M [119369] = 1031, --Goblin F [119376] = 1032, --Goblin M [1662187] = 1391, --Zandalari F [1630447] = 1390, --Zandalari M [1890759] = 1031, --Vulpera F [1890761] = 1031, --Vulpera M [1810676] = 1112, --Nightborne F [1814471] = 1034, --Nightborne M }; local function GetUICameraIDByModelFileID(fileID) return ModelFileIDxUICameraID[fileID] or 996 end local function GetPlayerInfoFromNarcissusDB(uid, key) return CharacterProfile:GetPlayerInfo(uid, key); end local function GetPlayerInfoFromBetterWardrobeDB(profileKey, key) return TransmogDataProvider:GetBWCharacterData(profileKey, key); end local GetPlayerInfo = GetPlayerInfoFromNarcissusDB; local OutfitDataProvider = {}; OutfitDataProvider.isCurrentPlayer = true; OutfitDataProvider.outfitIDs = {}; OutfitDataProvider.originalOutfitData = { --the items they worn when an actors is created name = L["Models"], outfits = { --{name = string, outfit = table, id = number}, }, }; OutfitDataProvider.currentPlayerUID = CharacterProfile:GetCurrentPlayerUID(); --current player OutfitDataProvider.selectedPlayerUID = nil; --the alts OutfitDataProvider.selectedOrderID = nil; function OutfitDataProvider:OnTransmogOutfitsChanged() if self.selectedPlayerUID == self.currentPlayerUID then if MainFrame:IsShown() then self:SelectProfile(nil, true); else MainFrame.outfitChanged = true; end end MainFrame:RegisterEvent("PLAYER_LOGOUT"); --update saved outfits when logout end function OutfitDataProvider:SelectProfile(playerUID, forceUpdate) playerUID = playerUID or self.currentPlayerUID; if playerUID == self.selectedPlayerUID and not forceUpdate then return else self.selectedPlayerUID = playerUID; end self.selectedOrderID = nil; if playerUID == "actors" then self["GetNameByOrder"] = self["GetNameFromActors"]; self["GetOutfitByOrder"] = self["GetOutfitFromActors"]; self.numOutfits = #self.originalOutfitData.outfits; SmartSetActorName(MainFrame.ProfileLabel, L["Origin Outfits"]); else if playerUID == self.currentPlayerUID then self["GetNameByOrder"] = self["GetNameFromServer"]; self["GetOutfitByOrder"] = self["GetOutfitFromServer"]; self.outfitStrings = nil; self.outfitIDs = C_TransmogCollection.GetOutfits() or {}; self.numOutfits = #self.outfitIDs; else self["GetNameByOrder"] = self["GetNameFromProfile"]; self["GetOutfitByOrder"] = self["GetOutfitFromProfile"]; self.outfitStrings = GetPlayerInfo(playerUID, "outfits"); self.numOutfits = #self.outfitStrings; end SmartSetActorName(MainFrame.ProfileLabel, string.format(L["Outfit Owner Format"], GetPlayerInfo(playerUID, "name"))); end MainFrame:UpdateOutfits(); end function OutfitDataProvider:GetOutfitByOrder(i) if self.isCurrentPlayer then local outfitID = self.outfitIDs[i]; if outfitID then return C_TransmogCollection.GetOutfitItemTransmogInfoList(outfitID); end end end function OutfitDataProvider:GetNameByOrder(i) if self.isCurrentPlayer then local outfitID = self.outfitIDs[i]; if outfitID then return C_TransmogCollection.GetOutfitInfo(outfitID); end else end end function OutfitDataProvider:GetNumOutfits() return self.numOutfits or 0 end function OutfitDataProvider:GetNameFromServer(i) local outfitID = self.outfitIDs[i]; if outfitID then return C_TransmogCollection.GetOutfitInfo(outfitID); end end function OutfitDataProvider:GetOutfitFromServer(i) local outfitID = self.outfitIDs[i]; if outfitID then return C_TransmogCollection.GetOutfitItemTransmogInfoList(outfitID); end end function OutfitDataProvider:GetNameFromProfile(i) if self.outfitStrings[i] then return self.outfitStrings[i].n end end function OutfitDataProvider:GetOutfitFromProfile(i) if self.outfitStrings[i] and self.outfitStrings[i].s then return TransmogDataProvider:ConvertTransmogStringToList( self.outfitStrings[i].s ); end end function OutfitDataProvider:GetNameFromActors(i) return self.originalOutfitData.outfits[i].name end function OutfitDataProvider:GetOutfitFromActors(i) --return self.originalOutfitData.outfits[i].outfit return TransmogDataProvider:ConvertTransmogStringToList( self.originalOutfitData.outfits[i].outfitString ); end local DelayTryOn = { t = 0, orderID = nil, }; local function HasAnySource(transmogInfo) return transmogInfo and transmogInfo.appearanceID ~= 0 end local function DressModelByOrderID(model, orderID) local infoList = OutfitDataProvider:GetOutfitByOrder(orderID); local result; local valid = true; if infoList then model:Undress(); for slotID, transmogInfo in pairs(infoList) do result = model:SetItemTransmogInfo(transmogInfo, slotID, slotID ~= 16); --possibly broken: dressing gnome with BE heritage armor returns 0 (success) --print(slotID.." "..result) if not HasAnySource(transmogInfo) then result = 0; --consider empty slot as TryOn successful end valid = valid and (result == 0); end end MainFrame.RightArea.TryOnAlert:SetShown(not valid); end local function DelayTryOn_OnUpdate(self, elapsed) DelayTryOn.t = DelayTryOn.t + elapsed; if DelayTryOn.t >= 0.15 then if DelayTryOn.orderID then DressModelByOrderID(ActivePreviewModel, DelayTryOn.orderID); end self:SetScript("OnUpdate", nil); end end local function AnchorSelectionMarkToButton(self, button) --self: the parent frame of the texture if button then if not self.SelectionMark then self.SelectionMark = self:CreateTexture(nil, "OVERLAY"); self.SelectionMark:SetTexture("Interface\\AddOns\\Narcissus\\Art\\Modules\\PhotoMode\\OutfitSelect\\SelectionMark"); self.SelectionMark:SetSize(16*PIXEL, 16*PIXEL); end self.SelectionMark:ClearAllPoints(); self.SelectionMark:SetPoint("CENTER", button, "LEFT", 7, 0); self.SelectionMark:Show(); else if self.SelectionMark then self.SelectionMark:Hide(); end end end local function PreviewModel_OnModelLoaded(self) --print("ModelFileID: "..self:GetModelFileID()); local cameraID = GetUICameraIDByModelFileID( self:GetModelFileID() ) --local detailsCameraID, transmogCameraID = C_TransmogSets.GetCameraIDs(); Model_ApplyUICamera(self, cameraID); self:SetAnimation(0); self:FreezeAnimation(0, 0, 0); end local function HeaderButton_OnEnter(self) self.Label:SetTextColor(1, 1, 1); self.Icon:SetVertexColor(1, 1, 1); self.Label:Show(); end local function HeaderButton_OnLeave(self) self.Label:SetTextColor(0.65, 0.65, 0.65); self.Icon:SetVertexColor(0.65, 0.65, 0.65); if self.hiddenLabel then self.Label:Hide(); end end local function HeaderButton_OnMouseDown(self) self.Label:SetPoint("CENTER", 5, -1.6); end local function HeaderButton_OnMouseUp(self) self.Label:SetPoint("CENTER", 5, -1); end --SimpleTooltip: Show this if the outfit name is truncated-- local function SimpleTooltip_OnUpdate(self, elapsed) self.x, self.y = GetCursorPosition(); self.x = self.x + 0; self.y = self.y + 8; self:SetPoint("LEFT", UIParent, "BOTTOMLEFT", self.x, self.y); if self.t then self.t = self.t + elapsed; if self.t < 0 then self:SetAlpha(0); elseif self.t < 0.2 then self:SetAlpha(self.t * 5); else self:SetAlpha(1); self.t = nil; end end end local function SimpleTooltip_SetText(text) SimpleTooltip.Name:SetText(text); SimpleTooltip:SetScript("OnUpdate", SimpleTooltip_OnUpdate); SimpleTooltip.t = -0.5; SimpleTooltip:SetAlpha(0); SimpleTooltip:Show(); end local function SimpleTooltip_OnHide() SimpleTooltip:SetScript("OnUpdate", nil); SimpleTooltip:Hide(); SimpleTooltip.x = nil; SimpleTooltip.y = nil; end NarciPhotoModeOutfitButtonMixin = {}; function NarciPhotoModeOutfitButtonMixin:ShowHighlight() FadeFrame(self.Highlight, 0.12, 1); end function NarciPhotoModeOutfitButtonMixin:OnLeave() FadeFrame(self.Highlight, 0.2, 0); MainFrame.RightArea:SetScript("OnUpdate", nil); SimpleTooltip:Hide(); end function NarciPhotoModeOutfitButtonMixin:HideButton() self:Hide(); self.Highlight:Hide(); self.Highlight:SetAlpha(0); self.orderID = nil; end function NarciPhotoModeOutfitButtonMixin:OnEnter() self:ShowHighlight(); DelayTryOn.t = 0; DelayTryOn.orderID = self.orderID; MainFrame.RightArea:SetScript("OnUpdate", DelayTryOn_OnUpdate); if self.Name:IsTruncated() then SimpleTooltip_SetText(self.Name:GetText()); else SimpleTooltip:Hide(); end end function NarciPhotoModeOutfitButtonMixin:OnClick() local model = Narci.ActiveModel; if model and model:IsObjectType("DressUpModel") then local infoList = OutfitDataProvider:GetOutfitByOrder(self.orderID); if infoList then model:Undress(); if model:GetName() == "NarciPlayerModelFrame1" then local slotButton; for slotID, transmogInfo in pairs(infoList) do slotButton = GetEquipmentSlotByID(slotID); if slotButton then if transmogInfo then slotButton:SetTransmogSourceID(transmogInfo.appearanceID, transmogInfo.secondaryAppearanceID); else slotButton:SetTransmogSourceID(0); end end --model:SetItemTransmogInfo(transmogInfo, slotID); if slotID == 16 or slotID == 17 then model:TryOn(transmogInfo.appearanceID, (slotID == 16 and "MAINHANDSLOT") or "SECONDARYHANDSLOT", transmogInfo.illusionID); --ME FIXED? else model:SetItemTransmogInfo(transmogInfo); end end else for slotID, transmogInfo in pairs(infoList) do --model:SetItemTransmogInfo(transmogInfo, slotID); if slotID == 16 or slotID == 17 then model:TryOn(transmogInfo.appearanceID, (slotID == 16 and "MAINHANDSLOT") or "SECONDARYHANDSLOT", transmogInfo.illusionID); --ME FIXED? else model:SetItemTransmogInfo(transmogInfo); end end end Narci_PhotoModeWeaponFrame:SetItemFromActor(model); model.customTransmogList = infoList; end end AnchorSelectionMarkToButton(self:GetParent(), self); OutfitDataProvider.selectedOrderID = self.orderID; end NarciPhotoModeCharacterListButtonMixin = CreateFromMixins(NarciPhotoModeOutfitButtonMixin); function NarciPhotoModeCharacterListButtonMixin:OnEnter() self:ShowHighlight(); end function NarciPhotoModeCharacterListButtonMixin:SetData(name, classID, numOutfits) --self.Name:SetText(name); SmartSetActorName(self.Name, name); local classColor = classID and GetClassColorByClassID(classID); if classColor then self.Name:SetTextColor(classColor:GetRGB()); else self.Name:SetTextColor(0.65, 0.65, 0.65); end if numOutfits and numOutfits > 0 then self.Count:SetText(numOutfits); self.Count:Show(); else self.Count:Hide(); end end function NarciPhotoModeCharacterListButtonMixin:OnClick() AnchorSelectionMarkToButton(self:GetParent(), self); OutfitDataProvider:SelectProfile(self.uid); end local function ClearAnimationTemps() local f = MainFrame; f:SetScript("OnUpdate", nil); f.t = nil; f.toWidth = nil; f.fromWidth = nil; f.toHeight = nil; end local function AnimExpand_OnUpdate(self, elapsed) self.t = self.t + elapsed; local width = inOutSine(self.t, self.fromWidth, self.toWidth, 0.35); if self.t >= 0.35 then width = self.toWidth; ClearAnimationTemps(); end local listWidth = width - 216; if listWidth < 1 then listWidth = 1; end self:SetWidth(width); self.CharacterList:SetWidth(listWidth); end local function AnimOpen_OnUpdate(self, elapsed) self.t = self.t + elapsed; local height = outQuart(self.t, 51, 161, 0.25); local yaw = outSine(self.t, -0.85, 0, 0.25); local alpha = 4 * self.t; if self.t >= 0.25 then height = 161; alpha = 1; yaw = 0; ClearAnimationTemps(); end self:SetHeight(height); self:SetAlpha(alpha); ActivePreviewModel:SetFacing(yaw); end local function ToggleCharacterList() if MainFrame.t then return end; --still in transition local state = not CharacterList:IsShown(); --CharacterList:SetShown(state); --[[ if state then MainFrame:SetWidth(324); else MainFrame:SetWidth(216); end --]] MainFrame.fromWidth = MainFrame:GetWidth(); MainFrame.t = 0; if state then MainFrame.toWidth = 324; FadeFrame(CharacterList, 0.25, 1, 0); else MainFrame.toWidth = 216; FadeFrame(CharacterList, 0.25, 0); end MainFrame:SetScript("OnUpdate", AnimExpand_OnUpdate); end local function Shared_OnMouseWheel(self, delta) local valid; if delta > 0 then if self.page > 1 then self.page = self.page - 1; valid = true; end elseif delta < 0 then if self.page < self.numPages then self.page = self.page + 1; valid = true; end end if valid then self:UpdatePage(); end end local ValidSortMethods = { name = 1, recent = 2, }; local function FilterButton_UpdateName(methodID) if not methodID then local currentMethod = NarcissusDB.OutfitSortMethod; methodID = ValidSortMethods[currentMethod]; end if methodID == 1 then FilterButton.Label:SetText(L["SortMethod Name"]); else FilterButton.Label:SetText(L["SortMethod Recent"]); end end local function FilterButton_OnClick() local currentMethod = NarcissusDB.OutfitSortMethod; local methodID = ValidSortMethods[currentMethod]; local newMethod; if methodID == 1 then newMethod = "recent"; methodID = 2; else newMethod= "name"; methodID = 1; end CharacterList:Init(newMethod); NarcissusDB.OutfitSortMethod = newMethod; FilterButton_UpdateName(methodID); end local UIDRoster; local CharacterListMixin = {}; function CharacterListMixin:Init(sortMethod) --Get Profiles local methodID = ValidSortMethods[sortMethod] or 1; if not methodID then sortMethod = "name"; end local numCharacters, numIgnored; if sortMethod == "BetterWardrobe" then UIDRoster, numCharacters, numIgnored = TransmogDataProvider:GetBWCharacters(); else UIDRoster, numCharacters, numIgnored = CharacterProfile:GetRoster(sortMethod, IGNORE_NO_OUTFIT_CHARS and "outfit"); end table.insert(UIDRoster, 1, "actors"); --the first entry is reserved for actors' original outfits numCharacters = numCharacters + 1; self.page = 1; if not self.PageNodes then self.PageNodes = {}; end if not self.Buttons then self.Buttons = {}; end local numPages; if numCharacters > 0 then numPages = math.ceil(numCharacters / BUTTON_PER_PAGE); else numPages = 0; end self.numPages = numPages; if numPages > 1 then for i = 1, numPages do if not self.PageNodes[i] then self.PageNodes[i] = self:CreateTexture(nil, "OVERLAY"); local a = 8 * PIXEL; self.PageNodes[i]:SetSize(a, a); self.PageNodes[i]:SetTexture("Interface\\AddOns\\Narcissus\\Art\\Modules\\PhotoMode\\OutfitSelect\\PageNode"); end self.PageNodes[i]:ClearAllPoints(); self.PageNodes[i]:SetPoint("TOP", self, "RIGHT", -6, 4 * (numPages - 0.5) + (1 - i) * 8); self.PageNodes[i]:Show(); end for i = numPages + 1, #self.PageNodes do self.PageNodes[i]:Hide(); end else for _, tex in pairs(self.PageNodes) do tex:Hide(); end end self:UpdatePage(); end function CharacterListMixin:UpdatePage() AnchorSelectionMarkToButton(self.ClipContainer, nil); local button; local characterData; local name, uid, classID, numOutfits; local indexOffset = (self.page - 1) * BUTTON_PER_PAGE; local anySelection; for i = 1, BUTTON_PER_PAGE do uid = UIDRoster[i + indexOffset]; if uid then if uid == "actors" then characterData = OutfitDataProvider.originalOutfitData; else characterData = GetPlayerInfo(uid); end if not self.Buttons[i] then self.Buttons[i] = CreateFrame("Button", nil, self.ClipContainer, "NarciPhotoModeCharacterListButtonTemplate"); --self.Buttons[i]:SetPoint("TOP", self, "TOP", 1, (1 - i) * 16 - 8); self.Buttons[i]:SetPoint("BOTTOM", self, "BOTTOM", 1, (1 - i) * 16 + 120); self.Buttons[i].Name:SetWidth(64); end button = self.Buttons[i]; name = characterData.name; classID = characterData.class; numOutfits = characterData.numOutfits or (characterData.outfits and #characterData.outfits); button:SetData(name, classID, numOutfits); button.uid = uid; button:Show(); if not anySelection then if uid == OutfitDataProvider.selectedPlayerUID then anySelection = true; AnchorSelectionMarkToButton(self.ClipContainer, button); end end else if self.Buttons[i] then self.Buttons[i]:HideButton(); else break end end end for i = 1, self.numPages do if self.PageNodes[i] then if i == self.page then self.PageNodes[i]:SetVertexColor(1, 1, 1); else self.PageNodes[i]:SetVertexColor(0.5, 0.5, 0.5); end end end --[[ if self:IsMouseOver(0, 0, 0, -106) then for i = 1, BUTTON_PER_PAGE do if self.Buttons[i] and self.Buttons[i]:IsShown() then if self.Buttons[i]:IsMouseOver() then self.Buttons[i]:OnEnter(); break end else break end end end --]] end local function SetDataSource(source) if source == "BetterWardrobe" then GetPlayerInfo = GetPlayerInfoFromBetterWardrobeDB; CharacterList:Init("BetterWardrobe"); FilterButton:Hide(); FilterButton.Label:SetText("BetterWardrobe"); else GetPlayerInfo = GetPlayerInfoFromNarcissusDB; CharacterList:Init(NarcissusDB.OutfitSortMethod); FilterButton:Show(); FilterButton_UpdateName(); end end local function DataSourceButton_SetLabelText(self, text) self.Label:SetText(text); self:SetWidth(math.ceil(self.Label:GetWidth() or 16) + 20); end local function DataSourceButton_OnClick(self) self.isBW = not self.isBW; local name; if self.isBW then name = "BetterWardrobe"; else name = "Narcissus"; end SetDataSource(name); DataSourceButton_SetLabelText(self, name); end NarciPhotoModeOutfitSelectMixin = {}; function NarciPhotoModeOutfitSelectMixin:OnLoad() MainFrame = self; self.parent = self:GetParent(); self.activeModelIndex = 1; self:RegisterEvent("PLAYER_ENTERING_WORLD"); self:RegisterEvent("TRANSMOG_OUTFITS_CHANGED"); end function NarciPhotoModeOutfitSelectMixin:Init() self.Buttons = {}; self.PageNodes = {}; self:SetScript("OnMouseWheel", Shared_OnMouseWheel); NarciAPI.NineSliceUtil.SetUpBackdrop(self, "shadowR12", 1, 0, 0, 0); --[[ ActivePreviewModel = CreateFrame("DressUpModel", nil, self); --ActivePreviewModel:SetKeepModelOnHide(true); local m = ActivePreviewModel; m:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", -1, 1); m:SetSize(106, 142); --108, 144 m:SetAutoDress(true); m:SetUnit("player"); m:SetAnimation(0); m:SetViewTranslation(0, 0); m:SetModelDrawLayer("ARTWORK"); m:SetFrameLevel(self:GetFrameLevel()) local x, y, z = m:TransformCameraSpaceToModelSpace(0, 0, -0.25); m:SetPosition(x, y, z); m:SetLight(true, false, -1, 1, -1, 0.8, 1, 1, 1, 0.5, 1, 1, 1); m:SetScript("OnShow", function(f) f:RefreshUnit(); end); --]] SimpleTooltip = self.SimpleTooltip; SimpleTooltip:SetScript("OnHide", SimpleTooltip_OnHide); local switch = Narci_ModelSettings.BasicPanel.OutfitToggle; self:ClearAllPoints(); self:SetPoint("BOTTOMRIGHT", switch, "TOPLEFT", 214, 4); self.parentSwitch = switch; --Create Background Textures local function TileBackground(frame, fromCoordX, sublevel) local tiles = {}; local t; for i = 1, 9 do t = frame:CreateTexture(nil, "BACKGROUND", nil, sublevel); t:SetTexture("Interface\\AddOns\\Narcissus\\Art\\Modules\\PhotoMode\\OutfitSelect\\Panel"); tiles[i] = t; if i <= 4 then t:SetSize(34, 34); if i == 1 then t:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, 0); t:SetTexCoord(fromCoordX, fromCoordX + 0.125, 0, 0.125); elseif i == 2 then t:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, 0); t:SetTexCoord(fromCoordX + 0.25, fromCoordX + 0.375, 0, 0.125); elseif i == 3 then t:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", 0, 0); t:SetTexCoord(fromCoordX, fromCoordX + 0.125, 0.25, 0.375); elseif i == 4 then t:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 0, 0); t:SetTexCoord(fromCoordX + 0.25, fromCoordX + 0.375, 0.25, 0.375); end elseif i == 9 then t:SetPoint("TOPLEFT", tiles[1], "BOTTOMRIGHT", 0, 0); t:SetPoint("BOTTOMRIGHT", tiles[4], "TOPLEFT", 0, 0); t:SetTexCoord(fromCoordX + 0.125, fromCoordX + 0.25, 0.125, 0.25); else if i == 5 then t:SetPoint("TOPLEFT", tiles[1], "TOPRIGHT", 0, 0); t:SetPoint("BOTTOMRIGHT", tiles[2], "BOTTOMLEFT", 0, 0); t:SetTexCoord(fromCoordX + 0.125, fromCoordX + 0.25, 0, 0.125); elseif i == 6 then t:SetPoint("TOPLEFT", tiles[1], "BOTTOMLEFT", 0, 0); t:SetPoint("BOTTOMRIGHT", tiles[3], "TOPRIGHT", 0, 0); t:SetTexCoord(fromCoordX, fromCoordX + 0.125, 0.125, 0.25); elseif i == 7 then t:SetPoint("TOPLEFT", tiles[2], "BOTTOMLEFT", 0, 0); t:SetPoint("BOTTOMRIGHT", tiles[4], "TOPRIGHT", 0, 0); t:SetTexCoord(fromCoordX + 0.25, fromCoordX + 0.375, 0.125, 0.25); elseif i == 8 then t:SetPoint("TOPLEFT", tiles[3], "TOPRIGHT", 0, 0); t:SetPoint("BOTTOMRIGHT", tiles[4], "BOTTOMLEFT", 0, 0); t:SetTexCoord(fromCoordX + 0.125, fromCoordX + 0.25, 0.25, 0.375); end end end end TileBackground(self.LeftArea, 0, 1); TileBackground(self.RightArea, 0.5, 2); local h = self.Header; self.ProfileLabel = h.CharacterListToggle.Label; h.CharacterListToggle:SetScript("OnClick", ToggleCharacterList); h.CharacterListToggle:SetScript("OnEnter", HeaderButton_OnEnter); h.CharacterListToggle:SetScript("OnLeave", HeaderButton_OnLeave); h.CharacterListToggle:SetScript("OnMouseDown", HeaderButton_OnMouseDown); h.CharacterListToggle:SetScript("OnMouseUp", HeaderButton_OnMouseUp); HeaderButton_OnLeave(h.CharacterListToggle); --header background local tiles = {}; for i = 1, 3 do local t = h:CreateTexture(nil, "BACKGROUND", nil, 0); t:SetTexture("Interface\\AddOns\\Narcissus\\Art\\Modules\\PhotoMode\\OutfitSelect\\Panel"); tiles[i] = t; if i == 3 then t:SetPoint("TOPLEFT", tiles[1], "TOPRIGHT", 0, 0); t:SetPoint("BOTTOMRIGHT", tiles[2], "BOTTOMLEFT", 0, 0); t:SetTexCoord(0.125, 0.25, 0.5, 0.5625); else t:SetSize(34, 17); if i == 1 then t:SetPoint("TOPLEFT", h, "TOPLEFT", 0, 0); t:SetTexCoord(0, 0.125, 0.5, 0.5625); else t:SetPoint("TOPRIGHT", h, "TOPRIGHT", 0, 0); t:SetTexCoord(0.25, 0.375, 0.5, 0.5625); end end end OutfitDataProvider:SelectProfile(); CharacterList = self.CharacterList; CharacterList:SetScript("OnMouseWheel", Shared_OnMouseWheel); Mixin(CharacterList, CharacterListMixin); CharacterList:Init(NarcissusDB.OutfitSortMethod); FilterButton = self.CharacterList.ClipContainer.FilterButton; local fb = FilterButton; fb.methodID = 1; fb:SetScript("OnClick", FilterButton_OnClick); fb:SetScript("OnEnter", HeaderButton_OnEnter); fb:SetScript("OnLeave", HeaderButton_OnLeave); fb:SetScript("OnMouseDown", HeaderButton_OnMouseDown); fb:SetScript("OnMouseUp", HeaderButton_OnMouseUp); FilterButton_UpdateName(); HeaderButton_OnLeave(fb); if TransmogDataProvider:IsBWDatabaseValid() then --Create a button to select outfit data source (Narcissus, BetterWardrobe) local dsb = self.CharacterList.ClipContainer.DataSourceButton; dsb:Show(); dsb:SetScript("OnEnter", HeaderButton_OnEnter); dsb:SetScript("OnLeave", HeaderButton_OnLeave); dsb:SetScript("OnMouseDown", function(f) f.Label:SetPoint("LEFT", 19, -1.6); end); dsb:SetScript("OnMouseUp", function(f) f.Label:SetPoint("LEFT", 19, -1); end); dsb:SetScript("OnClick", DataSourceButton_OnClick); DataSourceButton_SetLabelText(dsb, "Narcissus"); fb:ClearAllPoints(); fb:SetPoint("CENTER", CharacterList, "TOP", 46, 8); fb:SetSize(16, 16); fb.hiddenLabel = true; fb.Icon:ClearAllPoints(); fb.Icon:SetPoint("CENTER", fb, "CENTER", 0, -1); fb.Label:Hide(); fb.Label:ClearAllPoints(); fb.Label:SetPoint("RIGHT", fb.Icon, "LEFT", 4, 0); fb.Label:SetJustifyH("RIGHT"); fb:SetScript("OnMouseDown", function(f) f.Icon:SetPoint("CENTER", 0, -1.6); end); fb:SetScript("OnMouseUp", function(f) f.Icon:SetPoint("CENTER", 0, -1); end); end self:AddPlayerActor("player", _G["NarciPlayerModelFrame1"]); if self.activeModelIndex == 1 then self:SelectPreviewModel(1); end self.Init = nil; end local function CopyTable(settings) --Blizzard TableUtil.lua local copy = {}; for k, v in pairs(settings) do if type(v) == "table" then copy[k] = CopyTable(v); else copy[k] = v; end end return copy; end function NarciPhotoModeOutfitSelectMixin:AddPlayerActor(unit, model) if not model.GetItemTransmogInfoList then return end; local index = model:GetID(); if not PreviewModels[index] then local m = CreateFrame("DressUpModel", nil, self); PreviewModels[index] = m; m:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", -1, 1); m:SetSize(106, 142); --108, 144 m:SetAutoDress(true); m:SetKeepModelOnHide(true); m:SetAnimation(0); m:SetViewTranslation(0, 0); m:SetModelDrawLayer("ARTWORK"); m:SetFrameLevel(self:GetFrameLevel()); m:SetScript("OnModelLoaded", PreviewModel_OnModelLoaded); local x, y, z = m:TransformCameraSpaceToModelSpace(0, 0, -0.25); m:SetPosition(x, y, z); m:SetLight(true, false, -1, 1, -1, 0.8, 1, 1, 1, 0.5, 1, 1, 1); m:Hide(); end PreviewModels[index]:SetUnit(unit, index); --Add outfit After(0.2, function() local name = UnitName(unit); name = name.." #"..index; local infoList = model:GetItemTransmogInfoList(); --we have to deep copy this table local transmogString = TransmogDataProvider:ConvertTransmogListToString(infoList); local db = OutfitDataProvider.originalOutfitData.outfits; for i = 1, #db do if db[i].id == index then table.remove(db, i); break end end table.insert(db, 1, { name = name, outfit = infoList, outfitString = transmogString, id = index, } ); if CharacterList then --Frame hasn't been initialized CharacterList:UpdatePage(); if OutfitDataProvider.selectedPlayerUID == "actors" then OutfitDataProvider.numOutfits = #db; self:UpdatePage(); end end end) end function NarciPhotoModeOutfitSelectMixin:ModifyPlayerTransmogInfo(index, mainHandInfo, offHandInfo) local db = OutfitDataProvider.originalOutfitData.outfits; local outfitData; for i = 1, #db do if db[i].id == index then outfitData = db[i]; if outfitData.outfit then outfitData.outfit[16] = mainHandInfo; outfitData.outfit[17] = offHandInfo; end break end end if outfitData then outfitData.outfitString = TransmogDataProvider:ConvertTransmogListToString(outfitData.outfit); end end function NarciPhotoModeOutfitSelectMixin:SelectPreviewModel(index) for i, model in pairs(PreviewModels) do if i == index then model:Show(); ActivePreviewModel = model; else model:Hide(); end end self.activeModelIndex = index; end function NarciPhotoModeOutfitSelectMixin:UpdateOutfits() local numOutfits = OutfitDataProvider:GetNumOutfits(); local numPages; if numOutfits > 0 then numPages = math.ceil(numOutfits / BUTTON_PER_PAGE); self.NoOutfitText:Hide(); else numPages = 0; self.NoOutfitText:Show(); end for _, tex in pairs(self.PageNodes) do tex:Hide(); end if numPages > 1 then for i = 1, numPages do if not self.PageNodes[i] then self.PageNodes[i] = self:CreateTexture(nil, "OVERLAY"); local a = 8 * PIXEL; self.PageNodes[i]:SetSize(a, a); self.PageNodes[i]:SetTexture("Interface\\AddOns\\Narcissus\\Art\\Modules\\PhotoMode\\OutfitSelect\\PageNode"); end self.PageNodes[i]:ClearAllPoints(); self.PageNodes[i]:SetPoint("TOP", self.RightArea, "LEFT", -6, 4 * (numPages - 0.5) + (1 - i) * 8); self.PageNodes[i]:Show(); end end self.outfitChanged = nil; self.numPages = numPages; self:ResetPage(); end function NarciPhotoModeOutfitSelectMixin:ResetPage() self.page = 1; self:UpdatePage(); end function NarciPhotoModeOutfitSelectMixin:OnShow() if self.Init then self:Init(); end if self.outfitChanged then OutfitDataProvider:OnTransmogOutfitsChanged(); end self:RegisterEvent("GLOBAL_MOUSE_DOWN"); self.parentSwitch.Arrow:SetTexCoord(0, 1, 0, 1); end function NarciPhotoModeOutfitSelectMixin:OnHide() self:UnregisterEvent("GLOBAL_MOUSE_DOWN"); self:Hide(); self.parentSwitch.Arrow:SetTexCoord(0, 1, 1, 0); if self.t then if self.toWidth then local listWidth = self.toWidth - 216; if listWidth < 1 then listWidth = 1; end self:SetWidth(self.toWidth); self.CharacterList:SetWidth(listWidth); ClearAnimationTemps(); end end end function NarciPhotoModeOutfitSelectMixin:OnEnter() self.parent:OnEnter(); end function NarciPhotoModeOutfitSelectMixin:UpdatePage() AnchorSelectionMarkToButton(self, nil); local button; local name; local indexOffset = (self.page - 1) * BUTTON_PER_PAGE; local numOutfits = OutfitDataProvider:GetNumOutfits(); local orderID; local anySelection; for i = 1, BUTTON_PER_PAGE do orderID = i + indexOffset; if orderID <= numOutfits then if not self.Buttons[i] then self.Buttons[i] = CreateFrame("Button", nil, self, "NarciPhotoModeOutfitButtonTemplate"); --self.Buttons[i]:SetPoint("TOPRIGHT", self.LeftArea, "TOPRIGHT", -1, (1 - i) * 16 - 8); self.Buttons[i]:SetPoint("BOTTOMRIGHT", self.LeftArea, "BOTTOMRIGHT", -1, (1 - i) * 16 + 120); end button = self.Buttons[i]; button.orderID = orderID; name = OutfitDataProvider:GetNameByOrder(orderID); SmartSetActorName(button.Name, name); --button.Name:SetText(name); button:Show(); if not anySelection then if orderID == OutfitDataProvider.selectedOrderID then anySelection = true; AnchorSelectionMarkToButton(self, button); end end else if self.Buttons[i] then self.Buttons[i]:HideButton(); else break end end end for i = 1, self.numPages do if self.PageNodes[i] then if i == self.page then self.PageNodes[i]:SetVertexColor(1, 1, 1); else self.PageNodes[i]:SetVertexColor(0.5, 0.5, 0.5); end end end if self:IsMouseOver(0, 0, 0, -106) then for i = 1, BUTTON_PER_PAGE do if self.Buttons[i] and self.Buttons[i]:IsShown() then if self.Buttons[i]:IsMouseOver() then self.Buttons[i]:OnEnter(); break end else break end end end end function NarciPhotoModeOutfitSelectMixin:OnMouseWheel(delta) local valid; if delta > 0 then if self.page > 1 then self.page = self.page - 1; valid = true; end elseif delta < 0 then if self.page < self.numPages then self.page = self.page + 1; valid = true; end end if valid then self:UpdatePage(); end end function NarciPhotoModeOutfitSelectMixin:OnEvent(event) if event == "GLOBAL_MOUSE_DOWN" then if not (self:IsMouseOver(8, 0, -4, 4) or self.parentSwitch:IsMouseOver()) then self:HideUI(); end elseif event == "TRANSMOG_OUTFITS_CHANGED" then OutfitDataProvider:OnTransmogOutfitsChanged(); elseif event == "PLAYER_ENTERING_WORLD" then self:UnregisterEvent(event); CharacterProfile:SaveOutfits(); elseif event == "PLAYER_LOGOUT" then self:UnregisterEvent(event); CharacterProfile:SaveOutfits(); end end function NarciPhotoModeOutfitSelectMixin:ToggleUI() if self:IsShown() then self:HideUI(); else self:ShowUI(); end end function NarciPhotoModeOutfitSelectMixin:ShowUI() self:Show(); self:SetAlpha(0); self.t = 0; self:SetScript("OnUpdate", AnimOpen_OnUpdate); end function NarciPhotoModeOutfitSelectMixin:HideUI() self:Hide(); end --/script local a={0,84,1};local i=1;local m=Narci.ActiveModel;m:SetScript("OnAnimFinished",function(m)i=i+1;if a[i] then m:SetAnimation(a[i]) else m:SetScript("OnAnimFinished",nil)end end);m:SetAnimation(a[1]); --/script for k, v in pairs(BW) do if type(v) == "function" then print(k) end end --[[ BetterWardrobe_SavedSetData.global.sets.[name - server].sources --Blizzard Outfit BetterWardrobe_ListData.OutfitDB.char.[name - server].outfits --SavedExtra (mainHandEnchant, offHandEnchant, offShoulder) --]]