local _, addon = ... local TransitionAPI = addon.TransitionAPI; ------------------------------------------------------------------------ local VISUAL_ID_MAX = 220000; local TAB_WIDTH = 116; local NUM_MAX_HISTORY = 5; local MODEL_SETTINGS_FRAME_WIDTH = 440; local BROWSER_ANCHOR_OFFSET_COLLAPSED_X = 146; local BROWSER_ANCHOR_OFFSET_EXPANED_X = -28; local BROWSER_ANCHOR_OFFSET_Y = -6; ------------------------------------------------------------------------ local Narci = Narci; local L = Narci.L; local FadeFrame = NarciFadeUI.Fade; local After = C_Timer.After; local tinsert = table.insert; local BrowserFrame, ListFrame, PreviewFrame, HistoryFrame, Tab1, ListScrollBar, HistoryButtonFrame, QuickFavoriteButton, SuggestionFrame, HomeButton, MyFavoriteEditFrame; local NUM_VISIBLE_BUTTONS = 0; local NarciSpellVisualBrowser = NarciSpellVisualBrowser; local SpellVisualList = NarciSpellVisualBrowser.Catalogue; local GetSpellVisualKitInfo = NarciSpellVisualBrowser.GetSpellVisualKitInfo; local IsSpellVisualLogged = NarciSpellVisualBrowser.IsSpellVisualLogged; local NarciTooltip = NarciTooltip; local SelectedVisualIndex; local function CountLength(table) local count = 0; for i = 1, #table do count = count + #table[i]; end return count; end local function PrintTable(table) for k, v in pairs(table) do if v ~= nil then print(k.." - "..v); end end end ------------------------------------------- --Public method : Used in PlayerModel.lua function NarciSpellVisualBrowser:LoadHistory() local model = Narci.ActiveModel; if not model then return; end; SelectedVisualIndex = nil; local AppliedVisuals = model.AppliedVisuals; NUM_VISIBLE_BUTTONS = #AppliedVisuals; local buttons = HistoryFrame.HistoryButtonFrame.buttons; local button; local name, icon, animID; for i = 1, #buttons do button = buttons[i]; if AppliedVisuals[i] then button:Show(); button:SetAlpha(1); name, icon, animID = GetSpellVisualKitInfo( AppliedVisuals[i] ); button.Icon:SetTexture(icon); button.Icon:SetAlpha(0.6); button.name = name; else button:Hide(); end button.Border:SetTexCoord(0, 0.25, 0, 1); button.selected = false; end button = buttons[1]; button:SetPoint("BOTTOMRIGHT", HistoryButtonFrame, "BOTTOMRIGHT", 24 * (1 - NUM_VISIBLE_BUTTONS), 0); end ------------------------------------------- ------------Animation Container------------ ------------------------------------------- local AnimationContariner = CreateFrame("Frame"); --Root local pi = math.pi; local max = math.max; local sin = math.sin; local cos = math.cos; local function linear(t, b, e, d) return (e - b) * t / d + b end local function outSine(t, b, e, d) --elapsed, begin, end, duration return (e - b) * sin(t / d * (pi / 2)) + b end local function inOutSine(t, b, e, d) return -(e - b) / 2 * (cos(pi * t / d) - 1) + b end ------------------------------------------- --Toggle Spell Visual Brower frame local ExpandAnim = CreateFrame("Frame"); ExpandAnim:Hide(); ExpandAnim.total = 0; ExpandAnim.duration = 0.25; ExpandAnim:SetScript("OnHide", function(self) self.total = 0; end); ExpandAnim.duration2 = 0.5; local ModelSettings = Narci_ModelSettings; ExpandAnim:SetScript("OnShow", function(self) self.StartHeight = BrowserFrame:GetHeight(); _, self.xRelativeTo, _, self.StartX = BrowserFrame:GetPoint(); _, self.yRelativeTo, _, _, self.StartY = BrowserFrame.ExpandableFrames:GetPoint(); self.StartWidth = ModelSettings:GetWidth(); end); local function Expand_OnUpdate(self, elapsed) self.total = self.total + elapsed; local newTotal = self.total; local offsetX = outSine(newTotal, self.StartX, self.EndX, self.duration); local width = outSine(newTotal, self.StartWidth, self.EndWidth, self.duration); if newTotal >= self.duration then offsetX = self.EndX; width = self.EndWidth; local offsetY = outSine(newTotal - self.duration, self.StartY, self.EndY, 0.25); if newTotal >= self.duration2 then offsetY = self.EndY; self:Hide(); end BrowserFrame.ExpandableFrames:SetPoint("BOTTOM", self.yRelativeTo, "TOP", 0, offsetY); end BrowserFrame:SetPoint("BOTTOMRIGHT", self.xRelativeTo, "BOTTOMLEFT", offsetX, BROWSER_ANCHOR_OFFSET_Y); ModelSettings:SetWidth(width); --To keep the other panels still while widen this frame, their anchors must be updated --10 is ActorPanel's offset to its parent frame ModelSettings.ActorPanel:SetPoint("TOPLEFT", ModelSettings, "TOPLEFT", width - MODEL_SETTINGS_FRAME_WIDTH + 10, 0); end ExpandAnim:SetScript("OnUpdate", Expand_OnUpdate); local MODEL_SETTINGS_FRAME_WIDTH = ModelSettings:GetWidth(); local function ReAnchorBrowser() --local oldRight = ModelSettings:GetRight(); local oldCenterX = ModelSettings:GetCenter(); local oldBottom = ModelSettings:GetBottom(); local screenWidth = WorldFrame:GetWidth(); local scale = ModelSettings:GetEffectiveScale(); if not scale or scale == 0 then scale = 1; --return; end local width = ModelSettings:GetWidth()/2; ModelSettings:ClearAllPoints(); ModelSettings:SetPoint("BOTTOMRIGHT", nil, "BOTTOMRIGHT", oldCenterX + width - screenWidth / scale , oldBottom); end function Narci_ToggleSpellVisualBrowser(self) if ExpandAnim:IsShown() then return; end; self.isActive = not self.isActive; ReAnchorBrowser(); local state = self.isActive; BrowserFrame.isActive = state; local newWidth; local newOffsetX, newOffsetY; --for 2 different widgets if state then newWidth = MODEL_SETTINGS_FRAME_WIDTH + 218; newOffsetY = 0; newOffsetX = BROWSER_ANCHOR_OFFSET_EXPANED_X; FadeFrame(BrowserFrame, 0.15, 1); FadeFrame(self.Background, 0.15, 0); FadeFrame(self.Label, 0.15, 0); After(0.25, function() FadeFrame(BrowserFrame.ExpandableFrames, 0.25, 1); end); self:SetWidth(24); else newWidth = MODEL_SETTINGS_FRAME_WIDTH; newOffsetX = BROWSER_ANCHOR_OFFSET_COLLAPSED_X; newOffsetY = -40; FadeFrame(BrowserFrame.ExpandableFrames, 0.15, 0); After(0.15, function() FadeFrame(BrowserFrame, 0.25, 0); end); self:SetWidth(58); end ExpandAnim.EndY = newOffsetY; --ExpandableFrames ExpandAnim.EndX = newOffsetX; --BrowserFrame ExpandAnim.EndWidth = newWidth; --ModelSettings if state then --Expand ExpandAnim.duration2 = 0.5; ExpandAnim:Show(); else ExpandAnim.duration2 = 0.25; After(0.2, function() ExpandAnim:Show(); FadeFrame(self.Background, 0.15, 1); FadeFrame(self.Label, 0.15, 1); end); end end --Tab Changing Animation (Choose a category and go) local SwipeAnim = NarciAPI_CreateAnimationFrame(0.25); SwipeAnim:SetScript("OnShow", function(self) self.point, self.relativeTo, self.relativePoint, self.startOffset = Tab1:GetPoint(); end); local function Swipe_OnUpdate(self, elapsed) self.total = self.total + elapsed; local offset = outSine(self.total, self.startOffset, self.endOffset, self.duration); if self.total >= self.duration then offset = self.endOffset; self:Hide(); end Tab1:SetPoint(self.point, self.relativeTo, self.relativePoint, offset, 0); end SwipeAnim:SetScript("OnUpdate", Swipe_OnUpdate); local function GoToTab(index) SwipeAnim:Hide(); SwipeAnim.endOffset = (1 - index) * TAB_WIDTH; SwipeAnim:Show(); if index ~= 1 then FadeFrame(HomeButton, 0.2, 1); HomeButton.CurrentTabIndex = index; PreviewFrame:Disable(); else PreviewFrame:Enable(); end --Guide if BrowserFrame.ShowGuide then BrowserFrame.Guide.TabListener:SetValue(3); BrowserFrame.ShowGuide = false; end end --Tab collapsing Animation local CollapseAnim = NarciAPI_CreateAnimationFrame(0.2); CollapseAnim:SetScript("OnShow", function(self) self.StartHeight = self.tab:GetHeight(); end); local function Collapse_OnUpdate(self, elapsed) self.total = self.total + elapsed; local height = outSine(self.total, self.StartHeight, self.EndHeight, self.duration); if self.total >= self.duration then height = self.EndHeight; self:Hide(); end self.tab:SetHeight(height); end CollapseAnim:SetScript("OnUpdate", Collapse_OnUpdate); local function CollapseTab(tab, endHeight) CollapseAnim:Hide(); CollapseAnim.tab = tab; CollapseAnim.EndHeight = endHeight; CollapseAnim:Show(); end --Gradually Update Scroll Range local RangeAnim = NarciAPI_CreateAnimationFrame(0.5); RangeAnim:SetScript("OnShow", function(self) _, self.StartValue = ListScrollBar:GetMinMaxValues(); if self.EndValue < 0.1 then ListScrollBar.Thumb:Hide(); else ListScrollBar.Thumb:Show(); end end); local function UpdateInnerShadowStates(scrollBar, newMax, smoothing) local currValue = scrollBar:GetValue(); local minVal, maxVal = scrollBar:GetMinMaxValues(); local maxVal = newMax or maxVal; if maxVal == 0 then scrollBar.Thumb:Hide(); else scrollBar.Thumb:Show(); end if not smoothing then if ( currValue >= maxVal - 12) then scrollBar.BottomShadow:Hide(); else scrollBar.BottomShadow:Show(); end if ( currValue <= minVal + 12) then scrollBar.TopShadow:Hide(); else scrollBar.TopShadow:Show(); end scrollBar.BottomShadow:SetAlpha(1); scrollBar.TopShadow:SetAlpha(1); else if ( currValue >= maxVal - 12) then FadeFrame(scrollBar.BottomShadow, 0.2, 0); else if not scrollBar.BottomShadow:IsShown() then FadeFrame(scrollBar.BottomShadow, 0.2, 1); end end if ( currValue <= minVal + 12) then FadeFrame(scrollBar.TopShadow, 0.2, 0); else if not scrollBar.TopShadow:IsShown() then FadeFrame(scrollBar.TopShadow, 0.2, 1); end end end end local function Range_OnUpdate(self, elapsed) self.total = self.total + elapsed; local range = inOutSine(self.total, self.StartValue, self.EndValue, self.duration); if self.total >= self.duration then range = self.EndValue; self:Hide(); end ListScrollBar:SetMinMaxValues(0, range); end RangeAnim:SetScript("OnUpdate", Range_OnUpdate); local function SmoothRange(newRange) RangeAnim:Hide(); RangeAnim.EndValue = newRange; RangeAnim:Show(); end --Add button onto History tab local InsertAnim = NarciAPI_CreateAnimationFrame(0.5); --Remove a button from History tab local RemoveAnim = NarciAPI_CreateAnimationFrame(0.5); local function RemapButton() --print(NUM_VISIBLE_BUTTONS) if NUM_VISIBLE_BUTTONS <= NUM_MAX_HISTORY then return; end local buttons = HistoryButtonFrame.buttons; local button, icon, name; local numButton = #buttons; local icons = {}; local names = {}; for i = 1, numButton do button = buttons[i]; icon = button.textureID or 134400; tinsert(icons, icon); tinsert(names, button.name); end for i = 1, (numButton - 1) do button = buttons[i]; icon = icons[i + 1]; name = names[i + 1]; button.Icon:SetTexture(icon); button.name = name; button.textureID = icon; end icon = icons[1]; name = names[1]; button = buttons[1]; button:SetPoint("BOTTOMRIGHT", HistoryButtonFrame, "BOTTOMRIGHT", -(24 * (NUM_MAX_HISTORY - 1)) , 0); button = buttons[numButton]; button.Icon:SetTexture(icon); --icon[1], icon[2], icon[3] button.name = name; button.textureID = icon; buttons[NUM_MAX_HISTORY + 1]:Hide(); --print("Remapped"); end InsertAnim:SetScript("OnShow", function(self) local buttons = HistoryButtonFrame.buttons; local num = NUM_VISIBLE_BUTTONS; local NewButton = buttons[num]; self.StartX = (num - 2) * 24; self.EndX = (num - 1) * 24; self.StartY = HistoryButtonFrame.offsetY; if num == 1 then self.button1 = nil; self.button2 = buttons[1]; --Drop down self.button3 = nil; else self.button1 = buttons[1]; --Move left self.button2 = NewButton; --Drop down if num <= NUM_MAX_HISTORY then self.button3 = buttons[num - 1]; --Anchor button else self.button3 = nil; end end FadeFrame(NewButton, 0.12, 1); NewButton.animIn:Play(); end); local function Insert_OnUpdate(self, elapsed) self.total = self.total + elapsed; local offsetX = inOutSine(self.total, self.StartX, self.EndX, self.duration); local offsetY = outSine(self.total, self.StartY, 0, self.duration); if self.total >= self.duration then offsetX = self.EndX; offsetY = 0; self:Hide(); After(0, function() if self.button3 then self.button2:ClearAllPoints(); self.button2:SetPoint("LEFT", self.button3, "RIGHT", 0, 0); end RemapButton(); end); end if self.button1 then self.button1:SetPoint("BOTTOMRIGHT", HistoryButtonFrame, "BOTTOMRIGHT", -offsetX, 0); end self.button2:SetPoint("BOTTOMRIGHT", HistoryButtonFrame, "BOTTOMRIGHT", 0, offsetY); end InsertAnim:SetScript("OnUpdate", Insert_OnUpdate); local function AddToHistory(visualID) local model = Narci.ActiveModel; if not model then return; end; local AppliedVisuals = model.AppliedVisuals or {}; local NewHistory = {}; for i = 1, #AppliedVisuals do NewHistory[i] = AppliedVisuals[i]; end if #NewHistory < NUM_MAX_HISTORY then tinsert(NewHistory, visualID); else for i = 1, (#NewHistory - 1) do NewHistory[i] = NewHistory[i + 1]; end NewHistory[NUM_MAX_HISTORY] = visualID; end wipe(model.AppliedVisuals); model.AppliedVisuals = NewHistory; end local function HistoryButton_ResetSelection() local buttons = HistoryButtonFrame.buttons; SelectedVisualIndex = nil; local button; for i = 1, #buttons do button = buttons[i]; button.Border:SetTexCoord(0, 0.25, 0, 1); button.selected = false; button.Icon:SetAlpha(0.6); end end local function SmoothInsert(visualID, textureID, visualName) if RemoveAnim:IsShown() or InsertAnim:IsShown() then return; end; local model = Narci.ActiveModel; if model then model:ApplySpellVisualKit(visualID, false); else return; end local button; if NUM_VISIBLE_BUTTONS <= NUM_MAX_HISTORY then NUM_VISIBLE_BUTTONS = NUM_VISIBLE_BUTTONS + 1; button = HistoryButtonFrame.buttons[NUM_VISIBLE_BUTTONS]; else button = HistoryButtonFrame.buttons[NUM_MAX_HISTORY + 1]; end HistoryButton_ResetSelection(); textureID = textureID or 134400; button.Icon:SetTexture(textureID); button.Icon:SetTexCoord(0, 1, 0, 1); button.textureID = textureID; button.visualID = visualID; button.name = visualName; InsertAnim:Show(); AddToHistory(visualID); FadeFrame(HistoryFrame.Note, 0.25, 0); FadeFrame(HistoryFrame.Label, 0.15, 1); if model.isVirtual then --Rewrite model index button's tooltip local button = Narci_ActorPanel.ExtraPanel.buttons[model.buttonIndex]; if button then button.Label:SetText(visualName); end end end ---------------------------------------------------------------- RemoveAnim:SetScript("OnShow", function(self) self.ReAnchoredButton:ClearAllPoints(); self.EndX = self.StartX + 24; end) local function RemapIcons(buttonID) local buttons = HistoryButtonFrame.buttons; local button, icon, name; local numButton = #buttons; local icons = {}; local names = {}; for i = 1, numButton do button = buttons[i]; icon = button.textureID or 134400; tinsert(icons, icon); tinsert(names, button.name); end if buttonID == 1 then for i = 1, numButton - 1 do button = buttons[i]; icon = icons[i + 1]; name = names[i + 1]; button.Icon:SetTexture(icon); button.name = name; button.textureID = icon; end else for i = buttonID, numButton - 1 do button = buttons[i]; icon = icons[i + 1]; name = names[i + 1]; button.Icon:SetTexture(icon); button.name = name; button.textureID = icon; end end end local function Remove_OnUpdate(self, elapsed) self.total = self.total + elapsed; local alpha = linear(self.total, 1, 0, self.duration - 0.25) ; local offsetX = inOutSine(self.total, self.StartX, self.EndX, self.duration); if self.total >= self.duration then alpha = 0; offsetX = self.EndX; self:Hide(); After(0, function() HistoryButton_ResetSelection(); self.RemovedButton:SetAlpha(1); if self.LeftButton then self.RemovedButton:SetPoint("LEFT", self.LeftButton, "RIGHT", 0, 0); end if self.ReAnchoredButton then self.ReAnchoredButton:SetPoint("LEFT", self.RemovedButton, "RIGHT", 0, 0); end if not self.Reposition then self.LeadButton:SetPoint("BOTTOMRIGHT", HistoryButtonFrame, "BOTTOMRIGHT", offsetX, 0); end RemapIcons(self.buttonID) end); end if alpha < 0 then alpha = 0; end self.RemovedButton:SetAlpha(alpha); if self.Reposition then self.LeadButton:SetPoint("BOTTOMRIGHT", HistoryButtonFrame, "BOTTOMRIGHT", offsetX, 0); end end RemoveAnim:SetScript("OnUpdate", Remove_OnUpdate); local function SmoothRemove(buttonID) if not buttonID or RemoveAnim:IsShown() or InsertAnim:IsShown() then return; end; local buttons = HistoryButtonFrame.buttons; local RemovedButton = buttons[buttonID]; RemoveAnim.RemovedButton = RemovedButton; RemoveAnim.LeadButton = buttons[1]; RemoveAnim.LeftButton = buttons[buttonID - 1]; RemoveAnim.ReAnchoredButton = buttons[buttonID + 1]; _, _, _, RemoveAnim.StartX = buttons[1]:GetPoint(); RemoveAnim.buttonID = buttonID; if buttonID == 1 then RemoveAnim.Reposition = false; else RemoveAnim.Reposition = true; end if buttonID ~= 1 then RemovedButton:ClearAllPoints(); end if NUM_VISIBLE_BUTTONS > NUM_MAX_HISTORY then NUM_VISIBLE_BUTTONS = NUM_MAX_HISTORY - 1; else NUM_VISIBLE_BUTTONS = NUM_VISIBLE_BUTTONS - 1; end RemoveAnim:Show(); end ----------------------------------------------------------------------- local function UpdateScrollRange(smoothing) local ScrollFrame = ListFrame.ScrollFrame; local ScrollChild = ScrollFrame.ScrollChild; local TotalButton = ScrollChild.numEffectiveButtons; local parentButtons = ScrollChild.parentButtons; local collapsedButton = 0; local parentButton; for i = 1, #parentButtons do parentButton = parentButtons[i]; if parentButton.collapsed then collapsedButton = collapsedButton + parentButton.childNum; end end local buttonHeight = 16; local ButtonPerPage = 8; local TotalHeight = (TotalButton - collapsedButton) * buttonHeight; local MaxScroll = max(0, TotalHeight - ButtonPerPage * buttonHeight); ScrollFrame.range = MaxScroll; if smoothing then SmoothRange(MaxScroll); UpdateInnerShadowStates(ListScrollBar, MaxScroll, true); else ScrollFrame.scrollBar:SetMinMaxValues(0, MaxScroll); UpdateInnerShadowStates(ListScrollBar, MaxScroll, false); end end local function SubcategoryButton_OnClick(self) self.collapsed = not self.collapsed; local tabHeight; if self.collapsed then FadeFrame(self.Drawer, 0.15, 0); self.Icon:SetTexCoord(0, 1, 0, 1); tabHeight = 16; else FadeFrame(self.Drawer, 0.2, 1); self.Icon:SetTexCoord(0, 1, 1, 0); tabHeight = 16 * (self.childNum + 1); end CollapseTab(self.Drawer, tabHeight - 1); UpdateScrollRange(true); end local clickCounter = {}; clickCounter.leftButton = 0; local function EntryButton_OnClick(self, button) local model = Narci.ActiveModel; if not model then return; end; if button == "LeftButton" then model:ApplySpellVisualKit(self.visualID, true); --Show Mouse Button Tooltip: Right-click to apply visuals if not clickCounter.tooltipShown then clickCounter.leftButton = clickCounter.leftButton + 1; if clickCounter.leftButton >= 3 then clickCounter.tooltipShown = true; BrowserFrame.MouseButton:FadeIn(); end end elseif button == "RightButton" then SmoothInsert(self.visualID, self.texID, self:GetText()); end --Set Suggested AnimationID local animID = self.animID; SuggestionFrame.IDButton.animID = animID; if animID then if SuggestionFrame.AutoPlay.IsOn then model:PlayAnimation(animID); animID = "|cffd9cdb4"..animID; end else animID = "|cffa7a7a7".."N/A"; end SuggestionFrame.IDButton:SetText(animID); end local function SuggestedID_OnClick(self) if self.animID then local model = Narci.ActiveModel; if not model then return; end; model:PlayAnimation(self.animID); NarciModelControl_AnimationIDEditBox:SetText(self.animID); end end ------------------------------------------------- ----------------Set preview image---------------- ------------------------------------------------- local PreviewTimer = NarciAPI_CreateAnimationFrame(0.25); PreviewTimer:SetScript("OnHide", function(self) self:Hide(); self.total = 0; end); PreviewTimer:SetScript("OnUpdate", function(self, elapsed) self.total = self.total + elapsed; if self.total >= self.duration then if self.visualID == self.pendingID then --Some times when you collpase/expand a tab, OnEnter gets triggerred. In this case don't update prewview image --print(self.visualID) if IsSpellVisualLogged(self.visualID) then PreviewFrame.TopImage.FadeOut:Play(); --print("Has preview") else --print("no preview") PreviewFrame.BottomImage:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SpellVisualPreviews\\Blank"); end end self:Hide(); end end); local function UpdatePreview(visualID) if not visualID then return; end; PreviewFrame.BottomImage:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SpellVisualPreviews\\"..tostring(visualID)); PreviewTimer.total = 0; PreviewTimer.visualID = visualID; PreviewTimer:Show(); end ------------------------------------------------- local function ShowHighlight(self) PreviewTimer.pendingID = self.visualID; FadeFrame(self.Highlight, 0.12, 1); end local function HideHighlightAndClearID(self) PreviewTimer.pendingID = nil; FadeFrame(self.Highlight, 0.2, 0); end local function SubcategoryButton_OnEnter(self) ShowHighlight(self); --self:SetIgnoreParentAlpha(true); QuickFavoriteButton:Hide(); end local function SubcategoryButton_OnLeave(self) HideHighlightAndClearID(self); self:GetParent():SetAlpha(1); --self:SetIgnoreParentAlpha(false); end local FavoriteSpellVisualKitIDs = {}; local IsFavorite = {}; local function EnrtyButton_OnEnter(self) ShowHighlight(self); if not self.visualID then return; end; UpdatePreview(self.visualID); local Star = QuickFavoriteButton; Star:SetPoint("CENTER", self.Star, "CENTER", 0, 0); Star.parent = self; Star:Show(); Star.visualID = self.visualID; Star:SetFavorite(IsFavorite[self.visualID]); end local function CreateEntryButtonFrames(Category) local ScrollFrame = ListFrame.ScrollFrame local ScrollChild = ScrollFrame.ScrollChild; local scrollBar = ScrollFrame.scrollBar; scrollBar:SetValue(0); scrollBar.BottomShadow:SetAlpha(0); scrollBar.TopShadow:SetAlpha(0); local button, drawerFrame; local entryFrames = {}; local totalFrames = ScrollChild.buttons or {}; local parentButtons = {}; local list, listLength; local totalButton, totalEntry = 1, 0; local info, tex; if totalFrames then for i = 1, #totalFrames do totalFrames[i]:Hide(); totalFrames[i].childNum = 0; end end for i = 1, #SpellVisualList[Category] do --Tab Button-- list = SpellVisualList[Category][i]; listLength = #list; button = totalFrames[totalButton]; if not button then button = CreateFrame("Button", nil, ScrollChild, "Narci_OptionalSpellVisualButtonTemplate"); tinsert(totalFrames, button); else button:ClearAllPoints(); button:SetParent(ScrollChild); end tinsert(parentButtons, button); if totalButton == 1 then button:SetPoint("TOP", ScrollChild, "TOP", 0, -16); else button:SetPoint("TOP", parentButtons[i - 1].Drawer, "BOTTOM", 0, 0); end button:Show(); button:SetText(list["name"]); button.Drawer:Hide(); button.Drawer:SetAlpha(0); button.Drawer:SetHeight(15); button.Divider:Show() button.collapsed = true; button.text = list["name"]; button.ButtonText:SetJustifyH("CENTER"); button.ButtonText:SetPoint("CENTER", 0, 0); button.Icon:SetTexture("Interface\\AddOns\\Narcissus\\Art\\Widgets\\SpellVisualBrowser\\ExpandMark"); button.Icon:SetTexCoord(0, 1, 0, 1); button.Star:Hide(); button.visualID = nil; button.Count:SetText(listLength); button.Count:Show(); button.Background:Show(); button.childNum = listLength; button:SetPushedTextOffset(0, 0); button:SetScript("OnClick", SubcategoryButton_OnClick); button:SetScript("OnEnter", SubcategoryButton_OnEnter); button:SetScript("OnLeave", SubcategoryButton_OnLeave); totalButton = totalButton + 1; drawerFrame = button.Drawer; for j = listLength, 1, -1 do --1, listLength, 1 --Entry button-- button = totalFrames[totalButton]; if not button then button = CreateFrame("Button", nil, drawerFrame, "Narci_OptionalSpellVisualButtonTemplate"); tinsert(totalFrames, button); else button:ClearAllPoints(); button:SetParent(drawerFrame); end tinsert(entryFrames, button); button:Show(); drawerFrame:SetAlpha(0); drawerFrame:Hide(); drawerFrame:SetHeight(15); if j == listLength then --button:SetPoint("BOTTOM", drawerFrame, "BOTTOM", 0, 0); -- 0,-16 When anchor to the top button.Divider:Show() else --button:SetPoint("BOTTOM", entryFrames[totalEntry], "TOP", 0, 0); button.Divider:Hide(); end button:SetPoint("BOTTOM", drawerFrame, "BOTTOM", 0, 16*(listLength - j)); button.Background:Hide(); info = list[j]; button.visualID = info[1]; button.animID = info[4]; if IsFavorite[info[1]] then button.Star:Show(); else button.Star:Hide(); end button:SetText(info[2]); button.ButtonText:SetJustifyH("LEFT"); button.ButtonText:SetPoint("CENTER", 13, 0); button.Count:Hide(); tex = info[3]; if tex == 1 then tex = 134400; end button.texID = tex; button.Icon:SetTexture(tex); button.Icon:SetTexCoord(0.065, 0.945, 0.065, 0.935); button:SetScript("OnClick", EntryButton_OnClick); button:SetScript("OnEnter", EnrtyButton_OnEnter); button:SetScript("OnLeave", HideHighlightAndClearID); totalEntry = totalEntry + 1; totalButton = totalButton + 1; end end ScrollChild.numEffectiveButtons = totalButton - 1; ScrollChild.buttons = totalFrames; ScrollChild.parentButtons = parentButtons; end local function CategoryButton_OnClick(self) CreateEntryButtonFrames(self.index); ListFrame.Header.Tab2Label:SetText(self:GetText()); After(0, function() UpdateScrollRange(); GoToTab(2); end); end local function SavedEntryButton_OnEnter(self) ShowHighlight(self); if not self.visualID then return; end; UpdatePreview(self.visualID); --Relocate edit buttons (rename, delete) if MyFavoriteEditFrame.EditBox:HasFocus() then return; end MyFavoriteEditFrame.parent = self; MyFavoriteEditFrame:SetParent(self); MyFavoriteEditFrame:SetFrameLevel(self:GetFrameLevel()); MyFavoriteEditFrame:SetPoint("RIGHT", self, "RIGHT", -4, 0); MyFavoriteEditFrame:Show(); end local function SavedEntryButton_OnLeave(self) HideHighlightAndClearID(self); if not self:IsMouseOver() and not MyFavoriteEditFrame.EditBox:HasFocus() then MyFavoriteEditFrame:Hide(); end end local function SavedEntryButton_OnClick(self, button) local model = Narci.ActiveModel; if not model then return; end; if button == "LeftButton" then model:ApplySpellVisualKit(self.visualID, true); elseif button == "RightButton" then SmoothInsert(self.visualID, self.texID, self:GetText()); end end ---------------------------------------------------------------- local function UpdateScrollRange_Generic(scrollFrame) local ScrollFrame = scrollFrame; local ScrollChild = ScrollFrame.ScrollChild; local TotalButton = ScrollChild.numEffectiveButtons; local buttonHeight = 16; local ButtonPerPage = 8; local TotalHeight = TotalButton * buttonHeight; local MaxScroll = max(0, TotalHeight - ButtonPerPage * buttonHeight); ScrollFrame.range = MaxScroll; ScrollFrame.scrollBar:SetMinMaxValues(0, MaxScroll); UpdateInnerShadowStates(ScrollFrame.scrollBar, MaxScroll, false); end local function CreateMyFavorites() ListFrame.Header.Tab3Label:SetText("My Favorites"); local ScrollFrame = ListFrame.MyFavorites; local ScrollChild = ScrollFrame.ScrollChild; local scrollBar = ScrollFrame.scrollBar; scrollBar:SetValue(0); scrollBar.BottomShadow:SetAlpha(0); scrollBar.TopShadow:SetAlpha(0); local button; local buttons = ScrollChild.buttons or {}; local List = FavoriteSpellVisualKitIDs; local totalButton = 1; local tex; if buttons then for i = 1, #buttons do buttons[i]:Hide(); end end for k, v in pairs(List) do local i = totalButton; button = buttons[i]; if not button then button = CreateFrame("Button", nil, ScrollChild, "Narci_SavedSpellVisualButtonTemplate"); tinsert(buttons, button); else button:ClearAllPoints(); button:SetParent(ScrollChild); end if i == 1 then button:SetPoint("TOP", ScrollChild, "TOP", 0, -16); else button:SetPoint("TOP", buttons[i - 1], "BOTTOM", 0, 0); end button:Show(); button:Enable(); button:SetText(v[1]); button.text = v[1]; button.ButtonText:SetJustifyH("LEFT"); button.ButtonText:SetPoint("CENTER", 13, 0); tex = v[2] or 134400; button.Icon:SetTexture(tex); button.Icon:SetTexCoord(0.065, 0.945, 0.065, 0.935); button.texID = tex; button.visualID = k; button.ToBeDeleted = false; button:SetPushedTextOffset(1, -0.6); button:SetScript("OnClick", SavedEntryButton_OnClick); button:SetScript("OnEnter", SavedEntryButton_OnEnter); button:SetScript("OnLeave", SavedEntryButton_OnLeave); totalButton = totalButton + 1; end ScrollChild.numEffectiveButtons = totalButton - 1; ScrollChild.buttons = buttons; UpdateScrollRange_Generic(ScrollFrame); ScrollFrame.EditFrame:Hide(); end local function GoToMyFavorites() CreateMyFavorites(); After(0, function() GoToTab(3); end); end local function CountFavorites() local sum = 0; if not NarcissusDB or not NarcissusDB.Favorites or not NarcissusDB.Favorites.FavoriteSpellVisualKitIDs then return 0 end local list = NarcissusDB.Favorites.FavoriteSpellVisualKitIDs; for k, v in pairs(list) do sum = sum + 1; end return sum; end local MyCategoryButton; local function UpdateCategoryButtons() local frame = ListFrame.Category; if not frame.CategoryButtons then frame.CategoryButtons = {}; end local button; local buttons = frame.CategoryButtons; local totalPresets = #SpellVisualList + 1; --The last one is reserved for My Favorites for i = 1, totalPresets do button = buttons[i]; if not button then button = CreateFrame("Button", nil, frame, "Narci_SpellVisualCategoryButtonTemplate"); buttons[i] = button; end if i == 1 then button:SetPoint("TOP", frame, "TOP", 0, -16); else button:SetPoint("TOP", buttons[i - 1], "BOTTOM", 0, 0); end button.index = i; if i == totalPresets then button:SetText("My Favorites"); local numFavorites = CountFavorites(); button.Count:SetText(numFavorites); button:SetScript("OnClick", GoToMyFavorites); MyCategoryButton = button; else button:SetText(SpellVisualList[i]["name"]); button.Count:SetText( CountLength( SpellVisualList[i] ) ); button:SetScript("OnClick", CategoryButton_OnClick); end button:Show(); end for i = totalPresets + 1, #buttons do buttons[i]:Hide(); end end function NarciSpellVisualBrowser:SelectPack(index) local packName; SpellVisualList, packName = self:GetPack(index); UpdateCategoryButtons(); After(0, function() HomeButton:Click(); end) return packName end function NarciSpellVisualBrowser:SelectFirstEntry() --for tutorial ListFrame.Category.CategoryButtons[1]:Click(); After(0.65, function() if ListFrame.ScrollFrame.ScrollChild.buttons[1] then ListFrame.ScrollFrame.ScrollChild.buttons[1]:Click(); end end); end ----------------------------------------------------------------------- --History Tab local function HistoryButton_OnClick(self) local id = self:GetID(); local buttons = self:GetParent().buttons; local button; for i = 1, #buttons do button = buttons[i]; button.Border:SetTexCoord(0, 0.25, 0, 1); if i ~= id then button.selected = false; button.Icon:SetAlpha(0.6); end end local DeleteIcon = self:GetParent():GetParent().DeleteButton.Icon; self.selected = not self.selected; if self.selected then self.Border:SetTexCoord(0.25, 0.5, 0, 1); SelectedVisualIndex = id; DeleteIcon:SetDesaturated(false); else self.Border:SetTexCoord(0, 0.25, 0, 1); SelectedVisualIndex = nil; DeleteIcon:SetDesaturated(true); end end local function HistoryButton_OnEnter(self) self.Icon:Show(); self.Icon:SetAlpha(1); local tooltip = BrowserFrame.HistoryTooltip; local formatedID = "|cff999999"..self.visualID.."|r "; tooltip:SetPoint("BOTTOM", self, "TOP", 0, 0); if self.name and self.name ~= "" then tooltip.Label:SetText(formatedID.. self.name); PreviewTimer.pendingID = self.visualID; UpdatePreview(self.visualID); else tooltip.Label:SetText(formatedID.. "Custom"); end tooltip:Show(); end local function HistoryButton_OnLeave(self) BrowserFrame.HistoryTooltip:Hide(); if self.selected then return; end; FadeFrame(self.Icon, 0.2, 0.6); end local function CreateHistoryButtonFrame(self) local NumVisibleButtons = NUM_MAX_HISTORY; local offsetX = 24; local offsetY = 18; local button; local buttons = {}; for i = 1, NumVisibleButtons + 1 do button = CreateFrame("Button", nil, self, "Narci_HistoryButtonTemplate"); if i == 1 then button:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", 0, 24); else button:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", offsetX * (i - 1) , 24); end button.Icon:SetSize(14, 14); button.Icon:SetAlpha(0.6); button.ID:SetText(i); button:SetID(i); button:SetScript("OnClick", HistoryButton_OnClick); button:SetScript("OnEnter", HistoryButton_OnEnter); button:SetScript("OnLeave", HistoryButton_OnLeave); tinsert(buttons, button); end self.buttons = buttons; self.numEffectiveButtons = 0; self.offsetY = offsetY; end ----------------------------------------------------------------------- --Edit box frame local function EditBox_OnEnterPressed(self) self:ClearFocus(); self.Highlight:Hide(); local id = math.min(self:GetNumber(), VISUAL_ID_MAX); local model = Narci.ActiveModel; if not model then return; end; model:ApplySpellVisualKit(id, true); end local function EditBox_OnMouseWheel(self, delta) local id = self:GetNumber(); if delta < 0 and id < VISUAL_ID_MAX then id = id + 1; elseif delta > 0 and id > 0 then id = id - 1; else return; end local model = Narci.ActiveModel; if not model then return; end; self:SetNumber(id) model:ApplySpellVisualKit(id, true); end local function EditBox_OnTextChanged(self) --Update Favorite button local Star = self:GetParent().FavoriteButton; Star.IsFirstClick = true; local id = self:GetNumber(); if IsFavorite[id] then Star.Icon:SetAlpha(1); Star.Icon:SetTexCoord(0.25, 0.5, 0, 1); Star.IsFav = true; else Star.Icon:SetAlpha(0.6); Star.Icon:SetTexCoord(0, 0.25, 0, 1); Star.IsFav = false; end ---- self.Timer:Stop(); Narci_SpellVisualBrowser_PopUpFrame:Hide(); end local function ReApplySpellVisual(model) model = model or Narci.ActiveModel; if not model then return; end; local visualID; local AppliedVisuals = model.AppliedVisuals; for i = 1, #AppliedVisuals do visualID = AppliedVisuals[i]; if visualID then model:ApplySpellVisualKit(visualID, false); end end end local function ResetModel() local model = Narci.ActiveModel; if not model then return; end; local posX, posY, posZ = model:GetPosition(); local camX, camY, camZ = model:GetCameraPosition(); local _, _, dirX, dirY, dirZ, _, ambR, ambG, ambB, _, dirR, dirG, dirB = TransitionAPI.GetModelLight(model); local distance = model.cameraDistance; local animationID = model.animationID; local isPaused = model.isPaused; --[[ if model.isPlayer then if model.hasRaceChanged then model:SetCustomRace(); end end --]] model.isCameraDirty = false; if model.creatureID then model:SetCreature(model.creatureID); elseif model.displayID then model:SetDisplayInfo(model.displayID); else if model.unit and model.unit == "player" then TransitionAPI.SetModelByUnit(model, "player"); else model:RefreshUnit(); end end After(0, function() model:MakeCurrentCameraCustom(); model:SetPosition(posX, posY, posZ); TransitionAPI.SetCameraTarget(model, 0, 0, 0.8); TransitionAPI.SetCameraPosition(model, camX, camY, camZ); model.cameraDistance = distance; TransitionAPI.SetModelLight(model, true, false, dirX, dirY, dirZ, 1, ambR, ambG, ambB, 1, dirR, dirG, dirB); if isPaused then --model:Freeze(animationID); NarciModelControl_AnimationSlider:SetValue(model.freezedFrame or 0, true) else model:PlayAnimation(animationID); end After(0, function() ReApplySpellVisual(model); model:ReEquipWeapons(); if model.isVirtual then model:SetModelAlpha(0); end end) end); end NarciPhotoModeAPI.ResetModel = ResetModel; local function ResetButton_OnClick(self) ResetModel(); end local function DeleteButton_OnClick(self) self.Icon:SetDesaturated(true); NarciTooltip:HideTooltip(); if not SelectedVisualIndex then return; end; local model = Narci.ActiveModel; if not model then return; end local AppliedVisuals = model.AppliedVisuals; SmoothRemove(SelectedVisualIndex); if AppliedVisuals[SelectedVisualIndex] then local NewHistory = {}; local index = 1; for i = 1, NUM_VISIBLE_BUTTONS do if index == SelectedVisualIndex then index = index + 1; end NewHistory[i] = AppliedVisuals[index]; index = index + 1; end wipe(model.AppliedVisuals); model.AppliedVisuals = NewHistory; else return; end HistoryButton_ResetSelection(); --PrintTable(Narci.ActiveModel.AppliedVisuals); ResetModel(); end local function DeleteButton_OnEnter(self) self.Highlight:Show(); NarciTooltip:NewText(self, L["Remove Visual Tooltip"], nil, nil, true); end local function ButtonWithTooltip_OnLeave(self) self.Highlight:Hide(); NarciTooltip:HideTooltip(); end local function HistoryButton_RemoveAll() SelectedVisualIndex = nil; NUM_VISIBLE_BUTTONS = 0; local buttons = HistoryButtonFrame.buttons; local button; for i = 1, #buttons do button = buttons[i]; button.Border:SetTexCoord(0, 0.25, 0, 1); After( (i - 1)/10, function() FadeFrame(buttons[i], 0.25, 0); end); end end local function DeleteButton_OnLongClick(self) local model = Narci.ActiveModel; if model then HistoryButton_RemoveAll(); wipe(model.AppliedVisuals); --PrintTable(model.AppliedVisuals); ResetModel(); self:GetParent().FadeOut:Play(); self:GetParent():GetParent().Icon:SetSize(18, 18); else local AlertFrame = Narci_AlertFrame_Autohide; AlertFrame:SetAnchor(self, -24, true); AlertFrame:AddMessage("No active model", true); end end local function PlusButton_OnClick(self, button) local EditBox = self:GetParent().EditBox; EditBox:ClearFocus(); local id = EditBox:GetNumber(); if button == "LeftButton" and id < VISUAL_ID_MAX then id = id + 1; elseif button == "RightButton" and id > 0 then id = id - 1; end EditBox:SetNumber(id); local model = Narci.ActiveModel; if model then model:ApplySpellVisualKit(id, true) end end local function ApplyButton_OnClick(self, button) local EditBox = self:GetParent().EditBox; EditBox:ClearFocus(); EditBox.Highlight:Hide(); local id = EditBox:GetNumber(); id = tonumber(id); local name, icon, animationID = GetSpellVisualKitInfo(id); SmoothInsert(id, icon, name); end local function FavoriteButton_OnEnter(self) self.Icon:SetAlpha(1); self.Highlight:Show(); if not self:GetParent().PopUpFrame:IsShown() then if self.IsFav then NarciTooltip:NewText(self, L["Favorites Remove"], nil, nil, true); else NarciTooltip:NewText(self, L["Favorites Add"], nil, nil, true); end end end local function FavoriteButton_OnLeave(self) NarciTooltip:HideTooltip(); self.Highlight:Hide(); if not self.IsFav then self.Icon:SetAlpha(0.6); end end local function AddToFavorites(SpellVisualKitID, CustomName, CustomAnimationID) if not SpellVisualKitID then return; end; local name, icon, animationID = GetSpellVisualKitInfo(SpellVisualKitID); local ShowPreview; if name ~= "" then ShowPreview = true; else ShowPreview = false; icon = nil; end name = CustomName or name; animationID = CustomAnimationID or animationID; FavoriteSpellVisualKitIDs[SpellVisualKitID] = {name, icon, animationID, ShowPreview}; IsFavorite[SpellVisualKitID] = true; MyCategoryButton.Count:SetText( tonumber( MyCategoryButton.Count:GetText() ) + 1); MyCategoryButton.Differential:SetText("|cff7cc576+1"); --Green 7cc576 MyCategoryButton.Differential.FadeText:Play(); After(0, CreateMyFavorites); PlaySound(39672, "SFX"); end local function RenameFavorite(SpellVisualKitID, newName) if SpellVisualKitID then local entry = NarcissusDB.Favorites.FavoriteSpellVisualKitIDs[SpellVisualKitID]; if entry then entry[1] = newName; return true; else return false; end else return false; end end local function RemoveFromFavortes(IDsToBeDeleted) if not IDsToBeDeleted then return; end; local ShouldBeDeleted = {}; local IDType = type(IDsToBeDeleted); if IDType == "number" then ShouldBeDeleted[ IDsToBeDeleted ] = true; elseif IDType == "table" then for i = 1, #IDsToBeDeleted do ShouldBeDeleted[ IDsToBeDeleted[i] ] = true; end end local currentID = BrowserFrame.ExpandableFrames.EditBox:GetNumber(); local newList = {}; local oldList = FavoriteSpellVisualKitIDs; local sum = 0; for id, v in pairs(oldList) do if not ShouldBeDeleted[id] then newList[id] = v; sum = sum + 1; else IsFavorite[id] = false; if id == currentID then --Update favorite button local Star = BrowserFrame.ExpandableFrames.FavoriteButton; Star.Icon:SetTexCoord(0, 0.25, 0, 1); Star.Icon:SetAlpha(0.6); Star.IsFav= false; Star.IsFirstClick = true; end end end wipe(NarcissusDB.Favorites.FavoriteSpellVisualKitIDs); NarcissusDB.Favorites.FavoriteSpellVisualKitIDs = newList; FavoriteSpellVisualKitIDs = NarcissusDB.Favorites.FavoriteSpellVisualKitIDs; return sum; end local function StartRemovingFavorites() local MyFavorites = ListFrame.MyFavorites; local EditFrame = MyFavorites.EditFrame; EditFrame:Hide(); EditFrame.DeleteButton.numToBeDeleted = 0; local numButtons = MyFavorites.ScrollChild.numEffectiveButtons; local buttons = MyFavorites.ScrollChild.buttons; if not buttons or numButtons == 0 then return false; end local IDsToBeDeleted = {}; local NumDeleted local button; for i = 1, numButtons do button = buttons[i]; if button.ToBeDeleted then tinsert(IDsToBeDeleted, button.visualID); end end local numAfterDeleted = RemoveFromFavortes(IDsToBeDeleted); --print(#IDsToBeDeleted.." entries have been removed") return #IDsToBeDeleted, numAfterDeleted; end local function FavoritePopUp_Confirm() local PopUp = Narci_SpellVisualBrowser_PopUpFrame; local EditBox = PopUp.HiddenFrame.EditBox; local ID = tonumber(BrowserFrame.ExpandableFrames.EditBox:GetText()); AddToFavorites(ID, EditBox:GetText()); EditBox:ClearFocus(); FadeFrame(PopUp, 0.25, 0); local Star = PopUp:GetParent().FavoriteButton; Star.Icon:SetTexCoord(0.25, 0.5, 0, 1); Star.Icon:SetAlpha(1); Star.IsFav= true; Star.IsFirstClick = true; After(0, function() local sum = CountFavorites(); MyCategoryButton.Count:SetText(sum); end) end local function FavoritePopUp_Cancel() local PopUp = Narci_SpellVisualBrowser_PopUpFrame; FadeFrame(PopUp, 0.25, 0); local Star = PopUp:GetParent().FavoriteButton; Star.Icon:SetTexCoord(0, 0.25, 0, 1); Star.Icon:SetAlpha(0.6); Star.IsFav= false; Star.IsFirstClick = true; end local function FavoriteButton_OnClick(self) NarciTooltip:HideTooltip(); local PopUp = self:GetParent().PopUpFrame; if not self.IsFav then self.Icon:SetTexCoord(0.25, 0.5, 0, 1); if self.IsFirstClick then self.IsFirstClick = false; BrowserFrame.ArtFrame.Bling.animIn:Play(); local index = MyCategoryButton.Count:GetText() + 1; PopUp.HiddenFrame.EditBox:SetText("Custom Visual " .. index); FadeFrame(PopUp, 0.15, 1); else FavoritePopUp_Confirm(); end else local ID = self:GetParent().EditBox:GetNumber(); local numLeft = RemoveFromFavortes(ID); if numLeft then self.IsFav = false; self.Icon:SetTexCoord(0, 0.25, 0, 1); self.IsFirstClick = true; MyCategoryButton.Count:SetText(numLeft); MyCategoryButton.Differential:SetText("|cffff5050-1"); --minus 1 MyCategoryButton.Differential.FadeText:Play(); After(0, CreateMyFavorites); end end end local function UpdateDeleteInfo(numToBeDeleted) local TextFormat; if numToBeDeleted > 1 then TextFormat = L["Delete Entry Plural"]; --plural else TextFormat = L["Delete Entry Singular"]; --singular end ListFrame.Header.Tab3Label:SetText( string.format(TextFormat, numToBeDeleted) ); end local function EditFrame_EditBox_Confirm() local EntryButton = MyFavoriteEditFrame.parent; local NewText = MyFavoriteEditFrame.EditBox:GetText(); MyFavoriteEditFrame.EditBox.anyChange = nil; MyFavoriteEditFrame.EditBox:SetText(""); MyFavoriteEditFrame.EditBox:Hide(); EntryButton:SetText(NewText); if RenameFavorite(EntryButton.visualID, NewText) then --Rename succeeded EntryButton.Green.animIn:Stop(); EntryButton.Green.animIn:Play(); end NarciTooltip:HideTooltip(); end local function EditFrame_EditBox_Cancel(self) self.anyChange = nil; self:SetText(""); self:Hide(); NarciTooltip:HideTooltip(); end local function EditFrame_EditBox_OnTextChanged(self, isUserInput) if isUserInput then self.anyChange = true; end end local function EditFrame_EditBox_OnEditFocusLost(self) self:Hide(); Narci.UserIsInputing = false; self:HighlightText(0,0); if self.anyChange then self.anyChange = nil; EditFrame_EditBox_Confirm(); end MyFavoriteEditFrame.EditBoxBackground:Hide(); end local function EditFrame_DeleteButton_OnClick(self) local EntryButton = self:GetParent().parent; if not EntryButton then return; end; EntryButton.ToBeDeleted = not EntryButton.ToBeDeleted; local EditBox = self:GetParent().EditBox; EditFrame_EditBox_Cancel(EditBox); if EntryButton.ToBeDeleted then self.numToBeDeleted = self.numToBeDeleted or 0; self.numToBeDeleted = self.numToBeDeleted + 1; EntryButton:Disable(); else self.numToBeDeleted = self.numToBeDeleted - 1; EntryButton:Enable(); end UpdateDeleteInfo(self.numToBeDeleted); end local function EditFrame_RenameButton_OnClick(self) local EditBox = MyFavoriteEditFrame.EditBox; local EntryButton = MyFavoriteEditFrame.parent; self.IsOn = not self.IsOn; if self.IsOn then MyFavoriteEditFrame.EditBoxBackground:Show(); local OldText = EntryButton:GetText(); EditBox:Show(); EditBox:SetText(OldText or ""); EditBox:SetFocus(); EditBox:HighlightText(); if EntryButton.ToBeDeleted then --Rename a entry that is about to be deleted will cancel deletion EntryButton.ToBeDeleted = false; EntryButton:Enable(); --Update delete info local DeleteButton = MyFavoriteEditFrame.DeleteButton; DeleteButton.numToBeDeleted = DeleteButton.numToBeDeleted or 1; DeleteButton.numToBeDeleted = DeleteButton.numToBeDeleted - 1; UpdateDeleteInfo(DeleteButton.numToBeDeleted); end else EditFrame_EditBox_Cancel(EditBox); end end local function QuickFavoriteButton_OnClick(self) self.isFav = not self.isFav; if self.isFav then AddToFavorites(self.visualID); else RemoveFromFavortes(self.visualID); end self:PlayVisual(); end local function HomeButton_OnClick(self) GoToTab(1); FadeFrame(self, 0.2, 0); if self.CurrentTabIndex == 3 then --If you just go back from My Favorites, start removing selected favorites local numDeleted, numLeft = StartRemovingFavorites(); if numDeleted and numDeleted ~= 0 then MyCategoryButton.Count:SetText(numLeft); MyCategoryButton.Differential:SetText("|cffff5050-"..numDeleted); --Red ff5050 Green 7cc576 MyCategoryButton.Differential.FadeText:Play(); end end PreviewFrame:ResetCover(); end local function ScrollFrame_OnLoad(self) local buttonHeight = 16; local TotalTab = 12; local TotalHeight = floor(TotalTab * buttonHeight + 0.5); local MaxScroll = floor((TotalTab - 7) * buttonHeight + 0.5); self.scrollBar:SetMinMaxValues(0, MaxScroll) self.scrollBar:SetValueStep(0.001); self.buttonHeight = TotalHeight; self.range = MaxScroll; self.scrollBar:SetScript("OnValueChanged", function(self, value) --HybridScrollFrame_SetOffset(self:GetParent(), value) self:GetParent():SetVerticalScroll(value); UpdateInnerShadowStates(self, nil, false); end) NarciAPI_SmoothScroll_Initialization(self, nil, nil, 3/(TotalTab), 0.14); end local function Browser_OnShow(self) AnimationContariner:Show(); end local function Browser_OnHide(self) AnimationContariner:Hide(); clickCounter.leftButton = 0; clickCounter.tooltipShown = nil; end local function LoadFavorites() if not NarcissusDB then print("Cannot find NarcissusDB"); return 0; end NarcissusDB.Favorites = NarcissusDB.Favorites or {}; NarcissusDB.Favorites.FavoriteSpellVisualKitIDs = NarcissusDB.Favorites.FavoriteSpellVisualKitIDs or {}; FavoriteSpellVisualKitIDs = NarcissusDB.Favorites.FavoriteSpellVisualKitIDs; local sum = 0; local name, icon; for k, v in pairs(FavoriteSpellVisualKitIDs) do name, icon = GetSpellVisualKitInfo(k); if name == "" then --no match v[4] = false; --no preview else v[4] = true; --show preview end v[2] = icon; sum = sum + 1; IsFavorite[k] = true; end return sum; end --[[ function WipeFavorites() wipe(NarcissusDB.Favorites); end --]] local function SetAutoPlayButtonScript(self) local function SetFormat(self) if self.IsOn then self.Label:SetPoint("CENTER", self, "CENTER", 6, 0); self:SetText(self.EnabledText); else self.Label:SetPoint("CENTER", self, "CENTER", 0, 0); self:SetText(self.DisabledText); end end local function OnClick(self) self.IsOn = not self.IsOn; NarcissusDB.AutoPlayAnimation = self.IsOn; self.Tick:SetShown(self.IsOn); self.Label:ClearAllPoints(); SetFormat(self); end local state = NarcissusDB.AutoPlayAnimation; self.IsOn = state; self.Tick:SetShown(state); self.Label:ClearAllPoints(); SetFormat(self); self:SetScript("OnClick", OnClick); end local initialize = CreateFrame("Frame"); initialize:RegisterEvent("VARIABLES_LOADED"); initialize:SetScript("OnEvent", function(self) self:UnregisterEvent("VARIABLES_LOADED"); After(4.5, function() SetAutoPlayButtonScript(SuggestionFrame.AutoPlay); local numFavorites = LoadFavorites(); MyCategoryButton.Count:SetText(numFavorites); end); end); function Narci_SpellVisualBrowser_OnLoad(self) self:SetScript("OnShow", Browser_OnShow); self:SetScript("OnHide", Browser_OnHide); self:SetPoint("BOTTOMRIGHT", Narci_AnimationIDFrame, "BOTTOMLEFT", BROWSER_ANCHOR_OFFSET_COLLAPSED_X, BROWSER_ANCHOR_OFFSET_Y); BrowserFrame = self; local ExpandableFrames = self.ExpandableFrames; ListFrame = self.ExpandableFrames.ListFrame.Container; SuggestionFrame = self.ExpandableFrames.SuggestionFrame; HistoryFrame = self.ExpandableFrames.HistoryFrame; Tab1 = ListFrame.Category; ListScrollBar = ListFrame.ScrollFrame.scrollBar; ExpandableFrames.EditBox:SetScript("OnMouseWheel", EditBox_OnMouseWheel); ExpandableFrames.EditBox:SetScript("OnEnterPressed", EditBox_OnEnterPressed); ExpandableFrames.EditBox:SetScript("OnTextChanged", EditBox_OnTextChanged); ExpandableFrames.PlusButton:SetScript("OnClick", PlusButton_OnClick); ExpandableFrames.ApplyButton:SetScript("OnClick", ApplyButton_OnClick); ExpandableFrames.ResetButton:SetScript("OnClick", ResetButton_OnClick); local FavoriteButton = ExpandableFrames.FavoriteButton; FavoriteButton:SetScript("OnEnter", FavoriteButton_OnEnter); FavoriteButton:SetScript("OnLeave", FavoriteButton_OnLeave); FavoriteButton:SetScript("OnClick", FavoriteButton_OnClick); local FavoritePopUp = ExpandableFrames.PopUpFrame.HiddenFrame; FavoritePopUp.Header:SetText(L["New Favorite"]); FavoritePopUp.ConfirmButton:SetScript("OnClick", FavoritePopUp_Confirm); FavoritePopUp.CancelButton:SetScript("OnClick", FavoritePopUp_Cancel); FavoritePopUp.EditBox:SetScript("OnEscapePressed", FavoritePopUp_Cancel); FavoritePopUp.EditBox:SetScript("OnEnterPressed", FavoritePopUp_Confirm); HomeButton = ListFrame.Header.HomeButton; HomeButton:SetScript("OnClick", HomeButton_OnClick); HomeButton.tooltipDescription = L["Return"]; HistoryFrame.DeleteButton:SetScript("OnClick", DeleteButton_OnClick); HistoryFrame.DeleteButton:SetScript("OnEnter", DeleteButton_OnEnter); HistoryFrame.DeleteButton:SetScript("OnLeave", ButtonWithTooltip_OnLeave); HistoryFrame.DeleteButton.Fill.Timer:SetScript("OnFinished", DeleteButton_OnLongClick); HistoryButtonFrame = HistoryFrame.HistoryButtonFrame; SuggestionFrame.IDButton:SetScript("OnClick", SuggestedID_OnClick); UpdateCategoryButtons(); CreateHistoryButtonFrame(HistoryButtonFrame); CreateEntryButtonFrames(1); ScrollFrame_OnLoad(ListFrame.ScrollFrame); ScrollFrame_OnLoad(ListFrame.MyFavorites); QuickFavoriteButton = ListFrame.ScrollFrame.QuickFavoriteButton; QuickFavoriteButton:SetScript("OnClick", QuickFavoriteButton_OnClick); MyFavoriteEditFrame = ListFrame.MyFavorites.EditFrame; MyFavoriteEditFrame.DeleteButton:SetScript("OnClick", EditFrame_DeleteButton_OnClick); MyFavoriteEditFrame.DeleteButton.numToBeDeleted = 0; MyFavoriteEditFrame.RenameButton:SetScript("OnClick", EditFrame_RenameButton_OnClick); MyFavoriteEditFrame.EditBox:SetScript("OnEnterPressed", EditFrame_EditBox_Confirm); MyFavoriteEditFrame.EditBox:SetScript("OnEscapePressed", EditFrame_EditBox_Cancel); MyFavoriteEditFrame.EditBox:SetScript("OnEditFocusLost", EditFrame_EditBox_OnEditFocusLost); MyFavoriteEditFrame.EditBox:SetScript("OnTextChanged", EditFrame_EditBox_OnTextChanged); local IDLabel = self.VisualIDFrame.Label; IDLabel:SetText("ID"); IDLabel:SetPoint("LEFT", self.VisualIDFrame, "LEFT", 30, 0); local b = CreateFrame("Frame", nil, self.ExpandableFrames, "NarciGenericInfoButtonTemplate"); self.InfoButton = b; b:ClearAllPoints(); b:SetPoint("LEFT", self.VisualIDFrame, "LEFT", 6, 0); b:SetSize(18, 18); b:SetHitRectInsets(0, 0, 0, 0); b:SetNormalColor(0.65, 0.65, 0.65); b:SetHighlightColor(0.88, 0.88, 0.88); b:SetVisualType(2); b:SetCursorColor(2); b:SetUsePrivateTooltip(true, L["FindVisual Tooltip"]); b:SetFrameLevel(self.VisualIDFrame:GetFrameLevel() + 10); b:SetScript("OnMouseDown", function() NarciAPI.ToggleSpellVisualTutorial(); end); end ------------------------------------------------- NarciSpellVisualBrowserPreviewFrameMixin = {}; function NarciSpellVisualBrowserPreviewFrameMixin:OnLoad() PreviewFrame = self; self.packName = "Standard"; self.isStandardPack = true; self.tooltipDescription = L["Change Pack"]; end function NarciSpellVisualBrowserPreviewFrameMixin:OnClick() self.isStandardPack = not self.isStandardPack; local packID; if self.isStandardPack then packID = 0; else packID = 1; end self.packName = NarciSpellVisualBrowser:SelectPack(packID); --]] end function NarciSpellVisualBrowserPreviewFrameMixin:ResetCover() PreviewFrame.BottomImage:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SpellVisualPreviews\\Pack-".. self.packName); After(0, function() PreviewFrame.TopImage.FadeOut:Play(); end); end function NarciSpellVisualBrowserPreviewFrameMixin:OnHide() self:StopAnimating(); end function NarciSpellVisualBrowserPreviewFrameMixin:OnEnter() NarciTooltip:ShowButtonTooltip(self); end function NarciSpellVisualBrowserPreviewFrameMixin:OnLeave() NarciTooltip:HideTooltip(); end --[[ function GetReAnchor() ModelSettings:StartMoving(); ModelSettings:StopMovingOrSizing(); local point, _, relativePoint, offsetX, offsetY = ModelSettings:GetPoint(); print(point, relativePoint, offsetX, offsetY ); local oldCenterX = ModelSettings:GetCenter(); local width = ModelSettings:GetWidth()/2; local screenWidth = WorldFrame:GetWidth(); local scale = ModelSettings:GetEffectiveScale(); print("1 ", oldCenterX + width - screenWidth) print("2 ",oldCenterX + width - screenWidth/scale) print("3 ",(oldCenterX + width)*scale - screenWidth) end function SetSpellVisualBrowserOffset(offsetX) BrowserFrame:SetPoint("BOTTOMRIGHT", Narci_AnimationIDFrame, "BOTTOMLEFT", offsetX, BROWSER_ANCHOR_OFFSET_Y); end --]]