You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3594 lines
123 KiB
3594 lines
123 KiB
local _, addon = ...
|
|
local SettingFunctions = addon.SettingFunctions;
|
|
local inOutSine = addon.EasingFunctions.inOutSine;
|
|
local FadeFrame = NarciFadeUI.Fade;
|
|
|
|
local DEFAULT_FRAME_WIDTH = 720; --800 640
|
|
local DEFAULT_FRAME_HEIGHT = 405; --450 360
|
|
local DEFAULT_LEFT_WIDTH = DEFAULT_FRAME_WIDTH - DEFAULT_FRAME_HEIGHT*4/3;
|
|
local SHRIKNED_LEFT_WIDTH = (640 - 360 * 4/3);
|
|
local MAX_SCROLLFRAME_WIDTH = 394;
|
|
|
|
local PADDING_H = 18;
|
|
local PADDING_V = 12;
|
|
local CATE_LEVEL_OFFSET = 8;
|
|
local BUTTON_LEVEL_OFFSET = 12;
|
|
local CATE_OFFSET = 64;
|
|
local WIDGET_GAP = 16;
|
|
|
|
local IS_DRAGONFLIGHT = addon.IsDragonflight();
|
|
|
|
local function IsDragonflightFeature()
|
|
return IS_DRAGONFLIGHT
|
|
end
|
|
|
|
|
|
local L = Narci.L;
|
|
local BIND_ACTION_NARCISSUS = "CLICK Narci_MinimapButton:LeftButton";
|
|
_G["BINDING_NAME_"..BIND_ACTION_NARCISSUS] = L["Binding Name Open Narcissus"];
|
|
|
|
|
|
local CategoryButtons;
|
|
local CategoryOffsets;
|
|
local CategoryTabs;
|
|
local OptionButtons;
|
|
local WidgetGroups;
|
|
local MainFrame;
|
|
local AlertMessageFrame;
|
|
local Clipboard;
|
|
local DB;
|
|
local CURRENT_CATE_ID;
|
|
local RENDER_RANGE = DEFAULT_FRAME_HEIGHT;
|
|
|
|
local GAMEPAD_ENABLED = false; --Determine if we need to enable game pad surrpot
|
|
local SCROLL_LOCKED = false; --Lock scroll if user is assigning a hotkey
|
|
|
|
|
|
local math = math;
|
|
local GetCursorPosition = GetCursorPosition;
|
|
local SliderUpdator = CreateFrame("Frame");
|
|
|
|
local CreditList = {};
|
|
|
|
local function SetTextColorByID(fontString, id)
|
|
if id == 3 then
|
|
fontString:SetTextColor(0.92, 0.92, 0.92);
|
|
elseif id == 2 then
|
|
fontString:SetTextColor(0.67, 0.67, 0.67);
|
|
elseif id == 1 then
|
|
fontString:SetTextColor(0.40, 0.40, 0.40);
|
|
end
|
|
end
|
|
|
|
local function SetTextureColorByID(texture, id)
|
|
if id == 3 then
|
|
texture:SetVertexColor(0.92, 0.92, 0.92);
|
|
elseif id == 2 then
|
|
texture:SetVertexColor(0.67, 0.67, 0.67);
|
|
elseif id == 1 then
|
|
texture:SetVertexColor(0.40, 0.40, 0.40);
|
|
end
|
|
end
|
|
|
|
local function Round0(value)
|
|
return math.floor(value + 0.5)
|
|
end
|
|
|
|
local function Round1(value)
|
|
return math.floor(value * 10 + 0.5) * 0.1
|
|
end
|
|
|
|
local function Round2(value)
|
|
return math.floor(value * 100 + 0.5) * 0.01
|
|
end
|
|
|
|
local function OnClick_Checkbox(self)
|
|
if self.key then
|
|
local state = not DB[self.key];
|
|
DB[self.key] = state;
|
|
self:UpdateState();
|
|
if self.onValueChangedFunc then
|
|
self.onValueChangedFunc(self, state);
|
|
end
|
|
end
|
|
end
|
|
|
|
local function OnClick_Radio(self)
|
|
if self.key then
|
|
DB[self.key] = self.id;
|
|
self:UpdateRadioButtons();
|
|
if self.onValueChangedFunc then
|
|
self.onValueChangedFunc(self, self.id);
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
local ULTRAWIDE_MAX_OFFSET;
|
|
local ULTRAWIDE_STEP;
|
|
local IS_ULTRAWIDE;
|
|
local MAX_MODEL_SHRINKAGE = 100;
|
|
|
|
local function IsUsingUltraWideMonitor()
|
|
return IS_ULTRAWIDE
|
|
end
|
|
|
|
do
|
|
--Decides if it shows options for extra-wide monitor
|
|
local W0, H = WorldFrame:GetSize();
|
|
if (W0 and H) and H ~= 0 and (W0 / H) > (16.01 / 9) then --No resizing option on 16:9 or lower
|
|
IS_ULTRAWIDE = true;
|
|
local SLICE = 4;
|
|
local W = H / 9 * 16;
|
|
ULTRAWIDE_MAX_OFFSET = ((W0 - W)/2);
|
|
ULTRAWIDE_STEP = math.floor(ULTRAWIDE_MAX_OFFSET / SLICE);
|
|
ULTRAWIDE_MAX_OFFSET = SLICE * ULTRAWIDE_STEP;
|
|
end
|
|
|
|
local function IsUsingUltraWideMonitor()
|
|
return IS_ULTRAWIDE
|
|
end
|
|
|
|
--Calculate max model interactable area skrinkage
|
|
MAX_MODEL_SHRINKAGE = Round0( (1/3 - 1/8) *W0 );
|
|
end
|
|
|
|
local SettingsButtonMixin = {};
|
|
|
|
function SettingsButtonMixin:UpdateState_Checkbox()
|
|
self:SetState(self.key and DB[self.key]);
|
|
end
|
|
|
|
function SettingsButtonMixin:UpdateState_Radio()
|
|
self:SetState(self.key and DB[self.key] == self.id);
|
|
end
|
|
|
|
|
|
NarciSettingsSharedButtonMixin = {};
|
|
|
|
function NarciSettingsSharedButtonMixin:OnClick()
|
|
self:UpdateState();
|
|
end
|
|
|
|
function NarciSettingsSharedButtonMixin:OnEnter()
|
|
SetTextColorByID(self.Label, 3);
|
|
SetTextureColorByID(self.Border, 3);
|
|
if self.onEnterFunc then
|
|
self.onEnterFunc(self);
|
|
end
|
|
end
|
|
|
|
function NarciSettingsSharedButtonMixin:OnLeave()
|
|
SetTextColorByID(self.Label, 2);
|
|
SetTextureColorByID(self.Border, 2);
|
|
if self.onLeaveFunc then
|
|
self.onLeaveFunc(self);
|
|
end
|
|
end
|
|
|
|
function NarciSettingsSharedButtonMixin:SetState(state)
|
|
if state then
|
|
self.Selection:Show();
|
|
self.Border:SetTexCoord(0, 0.25, 0, 1);
|
|
self.selected = true;
|
|
else
|
|
self.Selection:Hide();
|
|
self.Border:SetTexCoord(0.25, 0.5, 0, 1);
|
|
self.selected = nil;
|
|
end
|
|
|
|
if self.children then
|
|
for i = 1, #self.children do
|
|
self.children[i]:SetShown(state);
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
function NarciSettingsSharedButtonMixin:SetButtonType(buttonType, keepOnClickScript)
|
|
if buttonType == "radio" then
|
|
self["UpdateState"] = SettingsButtonMixin["UpdateState_Radio"];
|
|
if not keepOnClickScript then
|
|
self:SetScript("OnClick", OnClick_Radio);
|
|
end
|
|
self.Background:SetTexCoord(0.5, 1, 0, 1);
|
|
self.Border:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\Radio");
|
|
self.Selection:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\Radio");
|
|
self.Highlight:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\Radio");
|
|
else
|
|
self["UpdateState"] = SettingsButtonMixin["UpdateState_Checkbox"];
|
|
if not keepOnClickScript then
|
|
self:SetScript("OnClick", OnClick_Checkbox);
|
|
end
|
|
self.Background:SetTexCoord(0, 0.5, 0, 1);
|
|
self.Border:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\Checkbox");
|
|
self.Selection:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\Checkbox");
|
|
self.Highlight:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\Checkbox");
|
|
end
|
|
self.Background:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\ButtonBackground");
|
|
self:OnLeave();
|
|
end
|
|
|
|
function NarciSettingsSharedButtonMixin:SetLabelText(text)
|
|
self.Label:SetText(text);
|
|
local textWidth = self.Label:GetWrappedWidth();
|
|
if textWidth then
|
|
if textWidth > 138 then
|
|
self:SetWidth(textWidth + 22);
|
|
else
|
|
self:SetWidth(160);
|
|
end
|
|
end
|
|
end
|
|
|
|
function NarciSettingsSharedButtonMixin:UpdateRadioButtons()
|
|
local groupID = self.groupID;
|
|
local buttons = WidgetGroups[groupID];
|
|
|
|
if buttons then
|
|
for i, b in ipairs(buttons) do
|
|
b:SetState(b == self);
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
---- Close Button ----
|
|
local function CloseButton_OnEnter(self)
|
|
SetTextureColorByID(self.Cross, 3);
|
|
end
|
|
|
|
local function CloseButton_OnLeave(self)
|
|
SetTextureColorByID(self.Cross, 1);
|
|
end
|
|
|
|
local function CloseButton_OnMouseDown(self)
|
|
self.Cross:SetScale(0.8);
|
|
self.Texture:SetTexCoord(0.375, 0.75, 0, 0.75);
|
|
end
|
|
|
|
local function CloseButton_OnMouseUp(self)
|
|
self.Cross:SetScale(1);
|
|
self.Texture:SetTexCoord(0, 0.375, 0, 0.75);
|
|
end
|
|
|
|
local function CloseButton_OnClick(self)
|
|
MainFrame:CloseUI();
|
|
end
|
|
|
|
|
|
---- Category Button ----
|
|
local function UpdateRenderArea(topOffset)
|
|
local bottomOffset = topOffset + RENDER_RANGE;
|
|
local tabTop, tabBottom;
|
|
|
|
for i = 1, NUM_CATE do
|
|
tabTop = CategoryOffsets[i] - CATE_OFFSET;
|
|
tabBottom = (CategoryOffsets[i + 1] or tabTop) + RENDER_RANGE;
|
|
|
|
if (tabTop < topOffset and tabBottom > topOffset) or
|
|
(tabTop < bottomOffset and tabBottom > bottomOffset) or
|
|
(tabTop > topOffset and tabBottom < bottomOffset) then
|
|
CategoryTabs[i]:Show();
|
|
else
|
|
CategoryTabs[i]:Hide();
|
|
end
|
|
end
|
|
end
|
|
|
|
local function SetCategory(id)
|
|
--category button visual
|
|
for i, b in ipairs(CategoryButtons) do
|
|
if i == id then
|
|
b.selected = true;
|
|
SetTextColorByID(b.ButtonText, 3);
|
|
else
|
|
if b.selected then
|
|
b.selected = nil;
|
|
SetTextColorByID(b.ButtonText, 1);
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local CREDIT_TAB_ID = 10;
|
|
|
|
local function FindCurrentCategory(offset)
|
|
offset = offset + 135; --is height/3 a proper position?
|
|
local matchID;
|
|
|
|
for i = NUM_CATE, 1, -1 do
|
|
if offset >= CategoryOffsets[i] then
|
|
matchID = i;
|
|
break
|
|
end
|
|
end
|
|
|
|
if matchID ~= CURRENT_CATE_ID then
|
|
CURRENT_CATE_ID = matchID;
|
|
SetCategory(matchID);
|
|
CreditList:OnFocused(matchID == CREDIT_TAB_ID);
|
|
end
|
|
|
|
UpdateRenderArea(offset);
|
|
end
|
|
|
|
|
|
local function CategoryButton_SetLabel(self, text)
|
|
self.ButtonText:SetText(text);
|
|
local numLines = self.ButtonText:GetNumLines();
|
|
if numLines > 1 then
|
|
self:SetHeight(40);
|
|
if self.ButtonText:IsTruncated() then
|
|
self.ButtonText:SetFontObject("NarciFontMedium12");
|
|
end
|
|
return 40;
|
|
else
|
|
return 24;
|
|
end
|
|
end
|
|
|
|
local function SetScrollByCategoryID(id, smoothScroll)
|
|
SetCategory(id);
|
|
if smoothScroll then
|
|
MainFrame.ScrollFrame:ScrollToOffset(CategoryOffsets[id]);
|
|
else
|
|
MainFrame.ScrollFrame:SetOffset(CategoryOffsets[id]);
|
|
end
|
|
UpdateRenderArea(CategoryOffsets[id]);
|
|
end
|
|
|
|
local function CategoryButton_OnClick(self)
|
|
SetScrollByCategoryID(self.id, true);
|
|
end
|
|
|
|
local function CategoryButton_OnEnter(self)
|
|
SetTextColorByID(self.ButtonText, 3);
|
|
end
|
|
|
|
local function CategoryButton_OnLeave(self)
|
|
if not self.selected then
|
|
SetTextColorByID(self.ButtonText, 1);
|
|
end
|
|
end
|
|
|
|
|
|
---- Feature Preview Pictures ----
|
|
local FeaturePreview = {
|
|
--textureKey[same as DB key] = {fileName, imageWidth, imageWidth, effectiveWidth, effectiveHeight}
|
|
PaperDollWidget = {"Preview-PaperDollWidget", 512, 256, 250, 185},
|
|
ConduitTooltip = {"Preview-ConduitTooltip", 512, 256, 256, 188},
|
|
NameTranslationPosition1 = {"Preview-TranslationOnTooltip", 256, 256, 149, 193},
|
|
NameTranslationPosition2 = {"Preview-TranslationOnNameplate", 256, 256, 149, 193},
|
|
};
|
|
|
|
function FeaturePreview.FadeIn_OnUpdate(f, elapsed)
|
|
f.t = f.t + elapsed;
|
|
if f.t > -0.1 and f.pendingKey then
|
|
FeaturePreview:SetupPreview(f.pendingKey);
|
|
f.pendingKey = nil;
|
|
FeaturePreview.animIn:Stop();
|
|
FeaturePreview.animIn:Play();
|
|
end
|
|
if f.t >= 0 then
|
|
if f.t < 0.25 then
|
|
f:SetAlpha(4 * f.t);
|
|
else
|
|
f:SetAlpha(1);
|
|
f:SetScript("OnUpdate", nil);
|
|
end
|
|
end
|
|
end
|
|
|
|
function FeaturePreview.FadeOut_OnUpdate(f, elapsed)
|
|
f.t = f.t + elapsed;
|
|
local alpha = f.fromAlpha - 5*f.t;
|
|
if alpha > 0 then
|
|
f:SetAlpha(alpha);
|
|
else
|
|
f:SetAlpha(0);
|
|
f:SetScript("OnUpdate", nil);
|
|
f:Hide();
|
|
end
|
|
end
|
|
|
|
function FeaturePreview:SetupPreview(previewKey)
|
|
if self[previewKey] and self.anchorTo then
|
|
self.texture:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\".. self[previewKey][1]);
|
|
local w0, h0 = self[previewKey][2], self[previewKey][3];
|
|
local w1, h1 = self[previewKey][4], self[previewKey][5];
|
|
self.frame:SetSize(w1 * 0.75, h1 * 0.75);
|
|
self.texture:SetTexCoord(1-(w1/w0), 1, 0, h1/h0); --textures are aligned to top-right in the image(tga)
|
|
|
|
self.frame:ClearAllPoints();
|
|
local offsetY = self.anchorTo:GetTop() - MainFrame.ScrollFrame:GetTop();
|
|
self.frame:SetPoint("TOPRIGHT", MainFrame.ScrollFrame, "TOPRIGHT", -PADDING_H, offsetY);
|
|
if self.frame:GetBottom() < MainFrame.ScrollFrame:GetBottom() + PADDING_H then
|
|
self.frame:ClearAllPoints();
|
|
self.frame:SetPoint("BOTTOMRIGHT", MainFrame.ScrollFrame, "BOTTOMRIGHT", -PADDING_H, PADDING_H);
|
|
end
|
|
end
|
|
end
|
|
|
|
function FeaturePreview.ShowPreview(anchorTo)
|
|
if not anchorTo.previewKey then return end;
|
|
|
|
local self = FeaturePreview;
|
|
if not self.frame then
|
|
self.frame = CreateFrame("Frame", nil, MainFrame.ScrollFrame.ScrollChild);
|
|
self.frame:SetSize(16, 16);
|
|
self.texture = self.frame:CreateTexture(nil, "OVERLAY");
|
|
self.texture:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 0, 0);
|
|
self.texture:SetPoint("BOTTOMRIGHT", self.frame, "BOTTOMRIGHT", 0, 0);
|
|
self.frame:SetScript("OnHide", function(f)
|
|
f:Hide();
|
|
f:ClearAllPoints();
|
|
f:SetScript("OnUpdate", nil);
|
|
end);
|
|
|
|
self.animIn = self.frame:CreateAnimationGroup();
|
|
local ag = self.animIn;
|
|
--[[
|
|
local path = ag:CreateAnimation("Path");
|
|
path:SetDuration(0.5);
|
|
path:SetStartDelay(0.08);
|
|
local p1 = path:CreateControlPoint(nil, nil, 1);
|
|
p1:SetOffset(0, -8);
|
|
local p2 = path:CreateControlPoint(nil, nil, 2);
|
|
p2:SetOffset(0, 0);
|
|
--]]
|
|
|
|
local tran1 = ag:CreateAnimation("translation");
|
|
tran1:SetDuration(0);
|
|
tran1:SetOrder(1);
|
|
tran1:SetOffset(0, -8);
|
|
local tran2 = ag:CreateAnimation("translation");
|
|
tran2:SetSmoothing("OUT");
|
|
tran2:SetDuration(0.25);
|
|
tran2:SetOrder(1);
|
|
tran2:SetStartDelay(0.08);
|
|
tran2:SetOffset(0, 8);
|
|
self.tran1 = tran1;
|
|
self.tran2 = tran2;
|
|
end
|
|
|
|
local deltaX, deltaY = GetCursorDelta();
|
|
local d = math.sqrt(deltaX*deltaX + deltaY*deltaY);
|
|
if d == 0 then
|
|
self.tran1:SetOffset(0, 0);
|
|
self.tran2:SetOffset(0, 0);
|
|
else
|
|
self.tran1:SetOffset(-deltaX, -deltaY);
|
|
self.tran2:SetOffset(deltaX, deltaY);
|
|
end
|
|
|
|
self.texture:SetTexture(nil);
|
|
self.anchorTo = anchorTo;
|
|
self.frame.pendingKey = anchorTo.previewKey;
|
|
self.frame:SetAlpha(0);
|
|
self.frame.t = -0.2;
|
|
self.frame:SetScript("OnUpdate", self.FadeIn_OnUpdate);
|
|
self.frame:Show();
|
|
end
|
|
|
|
function FeaturePreview.HidePreview()
|
|
local self = FeaturePreview;
|
|
if self.frame then
|
|
self.frame.fromAlpha = self.frame:GetAlpha();
|
|
if self.frame.fromAlpha > 0 then
|
|
self.frame.t = 0;
|
|
self.frame:SetScript("OnUpdate", self.FadeOut_OnUpdate);
|
|
self.frame:Show();
|
|
else
|
|
self.frame:Hide();
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
---- Options ----
|
|
local function AFKToggle_OnValueChanged(self, state)
|
|
SettingFunctions.UseAFKScreen(state);
|
|
end
|
|
|
|
|
|
local function ItemTooltipStyle_OnValueChanged(self, styleID)
|
|
SettingFunctions.SetItemTooltipStyle(styleID)
|
|
end
|
|
|
|
local function ItemTooltipShowItemID_OnValueChanged(self, state)
|
|
SettingFunctions.ShowItemIDOnTooltip(state);
|
|
end
|
|
|
|
|
|
local function ValueFormat_LetterboxRatio(value)
|
|
return Round2(value) ..":1"
|
|
end
|
|
|
|
local function DoubleTap_Setup(self)
|
|
local hotkey1, hotkey2 = GetBindingKey("TOGGLECHARACTER0");
|
|
local labelText = L["Double Tap"];
|
|
if hotkey1 then
|
|
labelText = labelText.." |cffffd100("..hotkey1..")|r";
|
|
if hotkey2 then
|
|
labelText = labelText .. "|cffffffff or |cffffd100("..hotkey2..")|r";
|
|
end
|
|
else
|
|
labelText = labelText.." |cff636363("..(NOT_APPLICABLE or "N/A")..")";
|
|
end
|
|
self:SetLabelText(labelText);
|
|
end
|
|
|
|
local function DoubleTap_OnValueChanged(self, state)
|
|
|
|
end
|
|
|
|
local function UseEscapeKey_OnValueChanged(self, state)
|
|
SettingFunctions.UseEscapeKeyForExit(state);
|
|
end
|
|
|
|
|
|
local function ItemTooltipStyle_OnEnter(self)
|
|
self.slotID = 16;
|
|
NarciEquipmentTooltip:HideTooltip();
|
|
NarciGameTooltip:Hide();
|
|
local link = "|Hitem:71086:6226:173127::::::60:577:::3:6660:7575:7696|r"; --77949
|
|
if self.id == 1 then
|
|
if Narci_Character:IsShown() then
|
|
NarciEquipmentTooltip:SetParent(Narci_Character);
|
|
else
|
|
NarciEquipmentTooltip:SetParent(UIParent);
|
|
end
|
|
NarciEquipmentTooltip:SetItemLinkAndAnchor(link, self);
|
|
NarciEquipmentTooltip:ShowHotkey(false);
|
|
elseif self.id == 2 then
|
|
if Narci_Character:IsShown() then
|
|
NarciGameTooltip:SetParent(Narci_Character);
|
|
else
|
|
NarciGameTooltip:SetParent(UIParent);
|
|
end
|
|
NarciGameTooltip:SetItemLinkAndAnchor(link, self);
|
|
end
|
|
end
|
|
|
|
local function ItemTooltipStyle_OnLeave(self)
|
|
NarciEquipmentTooltip:HideTooltip();
|
|
NarciEquipmentTooltip:SetParent(Narci_Character);
|
|
NarciEquipmentTooltip:ShowHotkey(true);
|
|
NarciGameTooltip:Hide();
|
|
NarciGameTooltip:SetParent(Narci_Character);
|
|
end
|
|
|
|
|
|
local function VignetteStrength_OnValueChanged(self, value)
|
|
SettingFunctions.SetVignetteStrength(value);
|
|
end
|
|
|
|
local function WeatherEffectToggle_OnValueChanged(self, state)
|
|
Narci_SnowEffect(state);
|
|
end
|
|
|
|
local function Letterbox_IsCompatible()
|
|
local scale = UIParent:GetEffectiveScale();
|
|
local w, h = GetScreenWidth()*scale, GetScreenHeight()*scale;
|
|
local ratio = 2;
|
|
local croppedHeight = w/ratio; --2.35/2/1.8
|
|
local maskHeight = math.floor((h - croppedHeight)/2 - 0.5);
|
|
return maskHeight > 0
|
|
end
|
|
|
|
local function LetterboxToggle_OnValueChanged(self, state)
|
|
SettingFunctions.UpdateLetterboxSize();
|
|
if state then
|
|
NarciAPI_LetterboxAnimation("IN");
|
|
else
|
|
NarciAPI_LetterboxAnimation("OUT");
|
|
end
|
|
end
|
|
|
|
local function LetterboxRatio_OnValueChanged(self, value)
|
|
SettingFunctions.UpdateLetterboxSize(value);
|
|
end
|
|
|
|
local function UltraWideOffset_OnValueChanged(self, value)
|
|
SettingFunctions.SetUltraWideFrameOffset(value);
|
|
end
|
|
|
|
local function ShowMisingEnchantAlert_OnValueChanged(self, state)
|
|
SettingFunctions.EnableMissingEnchantAlert(state);
|
|
end
|
|
|
|
local function ShowMisingEnchantAlert_IsValid()
|
|
return NarciAPI.IsPlayerAtMaxLevel();
|
|
end
|
|
|
|
local function ShowDetailedStats_OnValueChanged(self, state)
|
|
SettingFunctions.ShowDetailedStats(state);
|
|
end
|
|
|
|
local function CharacterUIScale_OnValueChanged(self, scale)
|
|
SettingFunctions.SetCharacterUIScale(scale);
|
|
end
|
|
|
|
local function ItemNameHeight_OnValueChanged(self, height)
|
|
SettingFunctions.SetItemNameTextHeight(height);
|
|
end
|
|
|
|
local function ItemNameWidth_OnValueChanged(self, width)
|
|
SettingFunctions.SetItemNameTextWidth(width);
|
|
end
|
|
|
|
local function TruncateTextToggle_OnValueChanged(self, state)
|
|
SettingFunctions.SetItemNameTruncated(state);
|
|
end
|
|
|
|
local function ShowMinimapModulePanel_OnValueChanged(self, state)
|
|
SettingFunctions.ShowMinimapModulePanel(state);
|
|
end
|
|
|
|
local function IndependentMinimapButtonToggle_OnValueChanged(self, state)
|
|
Narci_MinimapButton:SetIndependent(state);
|
|
end
|
|
|
|
|
|
local function ResetMinimapPosition_Setup(self)
|
|
self.Border:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\ResetButton");
|
|
self.Border:SetTexCoord(0, 1, 0, 1);
|
|
self.Selection:Hide();
|
|
self.Selection:SetTexture(nil);
|
|
self.Highlight:SetTexture(nil);
|
|
self.Background:Hide();
|
|
self.Background:SetTexture(nil);
|
|
|
|
local animRotate = self.Border:CreateAnimationGroup();
|
|
local r1 = animRotate:CreateAnimation("Rotation");
|
|
r1:SetDuration(1);
|
|
r1:SetOrder(1);
|
|
r1:SetDegrees(360);
|
|
r1:SetSmoothing("IN_OUT");
|
|
|
|
function self:UpdateState()
|
|
return
|
|
end
|
|
|
|
self.onEnterFunc = function()
|
|
self.Border:SetVertexColor(1, 1, 1);
|
|
end
|
|
self.onLeaveFunc = function()
|
|
SetTextureColorByID(self.Border, 2);
|
|
end
|
|
self.onLeaveFunc();
|
|
|
|
self:SetScript("OnClick", function()
|
|
Narci_MinimapButton:ResetPosition();
|
|
animRotate:Play();
|
|
end);
|
|
end
|
|
|
|
|
|
local function ScreenshotQuality_GetValue()
|
|
local value = C_CVar.GetCVar("screenshotQuality");
|
|
return tonumber(value)
|
|
end
|
|
|
|
local function ScreenshotQuality_OnValueChanged(self, value)
|
|
C_CVar.SetCVar("screenshotQuality", value);
|
|
end
|
|
|
|
local function ModelPanelScale_OnValueChanged(self, value)
|
|
SettingFunctions.SetModelPanelScale(value);
|
|
end
|
|
|
|
local function LoopAnimation_OnValueChanged(self, value)
|
|
SettingFunctions.SetModelLoopAnimation(value);
|
|
end
|
|
|
|
local function GetOppositeValue(value)
|
|
value = Round0(value);
|
|
if value > 0 then
|
|
return -value
|
|
else
|
|
return value
|
|
end
|
|
end
|
|
|
|
local function ModelHitRectShrinkage_OnValueChanged(self, value)
|
|
SettingFunctions.SetModelHitRectShrinkage(value);
|
|
end
|
|
|
|
|
|
local function CameraTransition_SetupDescription(self)
|
|
if DB[self.key] then
|
|
if self.description then
|
|
self.description:SetText(L["Camera Transition Description On"])
|
|
end
|
|
else
|
|
if self.description then
|
|
self.description:SetText(L["Camera Transition Description Off"])
|
|
end
|
|
end
|
|
end
|
|
|
|
local function CameraTransition_OnValueChanged(self, state)
|
|
SettingFunctions.UseCameraTransition(state);
|
|
CameraTransition_SetupDescription(self);
|
|
end
|
|
|
|
local function CameraOrbitToggle_SetupDescription(self)
|
|
if DB[self.key] then
|
|
if self.description then
|
|
self.description:SetText(L["Orbit Camera Description On"])
|
|
end
|
|
else
|
|
if self.description then
|
|
self.description:SetText(L["Orbit Camera Description Off"])
|
|
end
|
|
end
|
|
end
|
|
|
|
local function CameraOrbitToggle_OnValueChanged(self, state)
|
|
if Narci_Character:IsVisible() then
|
|
MoveViewRightStop();
|
|
if state then
|
|
local speed = tonumber(GetCVar("cameraYawMoveSpeed")) or 180;
|
|
MoveViewRightStart(0.005*180/speed);
|
|
end
|
|
end
|
|
|
|
CameraOrbitToggle_SetupDescription(self);
|
|
end
|
|
|
|
local function CameraSafeToggle_IsValid()
|
|
if IsAddOnLoaded("DynamicCam") then
|
|
return false
|
|
else
|
|
return true
|
|
end
|
|
end
|
|
|
|
local function CameraSafeToggle_OnValueChanged(self, state)
|
|
SettingFunctions.EnableCameraSafeMode(state);
|
|
end
|
|
|
|
local function CameraUseBustShot_OnValueChanged(self, value)
|
|
SettingFunctions.SetDefaultZoomClose(value);
|
|
end
|
|
|
|
|
|
local function GemManagerToggle_OnValueChanged(self, state)
|
|
if (not state) and Narci_EquipmentOption then
|
|
Narci_EquipmentOption:CloseUI();
|
|
end
|
|
end
|
|
|
|
local function DressingRoomToggle_OnValueChanged(self, state)
|
|
if (state and not NarciDressingRoomOverlay) or (not state and NarciDressingRoomOverlay) then
|
|
AlertMessageFrame:ShowRequiresReload();
|
|
end
|
|
end
|
|
|
|
local function PaperDollWidgetToggle_OnValueChanged(self, state)
|
|
SettingFunctions.EnablePaperDollWidget(state);
|
|
end
|
|
|
|
local function ConduitTooltipToggle_OnValueChanged(self, state)
|
|
SettingFunctions.EnableConduitTooltip(state);
|
|
end
|
|
|
|
|
|
-- dropping hearts when creadit list is focused
|
|
local LoveGenerator = {};
|
|
|
|
function LoveGenerator.HeartAnimationOnStop(animGroup)
|
|
local tex = animGroup:GetParent();
|
|
tex:Hide();
|
|
table.insert(LoveGenerator.recyledTextures, tex);
|
|
end
|
|
|
|
function LoveGenerator:GetHeart()
|
|
if not self.textures then
|
|
self.textures = {};
|
|
end
|
|
if not self.recyledTextures then
|
|
self.recyledTextures = {};
|
|
end
|
|
|
|
if #self.recyledTextures > 0 then
|
|
return table.remove(self.recyledTextures, #self.recyledTextures)
|
|
else
|
|
local tex = MainFrame.HeartContainer:CreateTexture(nil, "OVERLAY", "NarciPinkHeartTemplate", 2);
|
|
tex.FlyDown:SetScript("OnFinished", LoveGenerator.HeartAnimationOnStop);
|
|
tex.FlyDown:SetScript("OnStop", LoveGenerator.HeartAnimationOnStop);
|
|
self.textures[ #self.textures + 1 ] = tex;
|
|
return tex
|
|
end
|
|
end
|
|
|
|
function LoveGenerator:CreateHeartAtCursorPosition()
|
|
if MainFrame.HeartContainer:IsMouseOver() then
|
|
local heart = self:GetHeart();
|
|
|
|
local px, py = GetCursorPosition();
|
|
local scale = MainFrame:GetEffectiveScale();
|
|
px, py = px / scale, py / scale;
|
|
|
|
local d = math.max(py - MainFrame:GetBottom() + 16, 0); --distance
|
|
local depth = math.random(1, 8);
|
|
local scale = 0.25 + 0.25 * depth;
|
|
local size = 32 * scale;
|
|
local alpha = 1.35 - 0.15 * depth;
|
|
local v = 20 + 10 * depth;
|
|
local t= d / v;
|
|
|
|
if alpha > 0.67 then
|
|
alpha = 0.67;
|
|
end
|
|
|
|
heart.FlyDown.Translation:SetOffset(0, -d);
|
|
heart.FlyDown.Translation:SetDuration(t);
|
|
heart:ClearAllPoints();
|
|
heart:SetPoint("CENTER", UIParent, "BOTTOMLEFT" , px, py);
|
|
|
|
heart:SetSize(size, size);
|
|
heart:SetAlpha(alpha);
|
|
heart.FlyDown:Play();
|
|
heart:Show();
|
|
end
|
|
end
|
|
|
|
function LoveGenerator:StopAnimation()
|
|
if self.textures then
|
|
for _, tex in ipairs(self.textures) do
|
|
tex.FlyDown:Stop();
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
function CreditList:CreateList(parent, anchorTo, fromOffsetY)
|
|
local active = {"Albator S.", "Lala.Marie", "Erik Shafer", "Celierra&Darvian", "Pierre-Yves Bertolus", "Terradon", "Miroslav Kovac", "Ryan Zerbin", "Helene Rigo"};
|
|
local inactive = {"Alex Boehm", "Solanya", "Elexys", "Ben Ashley", "Knightlord", "Brian Haberer", "Andrew Phoenix", "Nantangitan", "Blastflight", "Lars Norberg", "Valnoressa", "Nimrodan", "Brux",
|
|
"Karl", "Webb", "acein", "Christian Williamson", "Tzutzu", "Anthony Cordeiro", "Nina Recchia", "heiteo", "Psyloken", "Jesse Blick", "Victor Torres", "Nisutec", "Tezenari", "Gina"};
|
|
local special = {"Marlamin | WoW.tools", "Keyboardturner | Avid Bug Finder(Generator)", "Meorawr | Wondrous Wisdomball", "Ghost | Real Person", "Hubbotu | Translator - Russian", "Romanv | Translator - Spanish", "Onizenos | Translator - Portuguese"};
|
|
|
|
local aciveColor = "|cff914270";
|
|
|
|
local numTotal = #active;
|
|
local mergedList = active;
|
|
local totalHeight;
|
|
|
|
for i = 1, #active do
|
|
active[i] = aciveColor ..active[i].."|r";
|
|
end
|
|
|
|
for i = 1, #inactive do
|
|
numTotal = numTotal + 1;
|
|
mergedList[numTotal] = inactive[i];
|
|
end
|
|
|
|
local upper = string.upper;
|
|
local gsub = string.gsub;
|
|
|
|
table.sort(mergedList, function(a, b)
|
|
return upper( gsub(a, aciveColor, "") ) < upper( gsub(b, aciveColor, "") )
|
|
end);
|
|
|
|
|
|
local header = parent:CreateFontString(nil, "OVERLAY", "NarciFontMedium13");
|
|
header:SetPoint("TOP", anchorTo, "TOP", 0, fromOffsetY);
|
|
header:SetText(string.upper("Patrons"));
|
|
SetTextColorByID(header, 1);
|
|
|
|
totalHeight = header:GetHeight() + 12;
|
|
fromOffsetY = fromOffsetY - totalHeight;
|
|
|
|
local numRow = math.ceil(numTotal/3);
|
|
|
|
local sidePadding = PADDING_H + BUTTON_LEVEL_OFFSET;
|
|
self.sidePadding = sidePadding;
|
|
self.anchorTo = anchorTo;
|
|
self.parent = parent;
|
|
|
|
local colWidth = (MainFrame.ScrollFrame:GetWidth() - sidePadding*2) / 3;
|
|
local text;
|
|
local fontString;
|
|
local height;
|
|
|
|
local i = 0;
|
|
local maxHeight = 0;
|
|
local totalTextWidth = 0;
|
|
local width = 0;
|
|
|
|
local fontStrings = {};
|
|
|
|
for col = 1, 3 do
|
|
fontString = parent:CreateFontString(nil, "OVERLAY", "NarciFontMedium13");
|
|
fontString:SetWidth(colWidth);
|
|
fontString:SetPoint("TOPLEFT", anchorTo, "TOPLEFT", 0, fromOffsetY);
|
|
fontString:SetJustifyH("LEFT");
|
|
fontString:SetJustifyV("TOP");
|
|
fontString:SetSpacing(8);
|
|
fontStrings[col] = fontString;
|
|
SetTextColorByID(fontString, 1);
|
|
|
|
text = nil;
|
|
for row = 1, numRow do
|
|
i = i + 1;
|
|
if mergedList[i] then
|
|
if text then
|
|
text = text .. "\n" .. mergedList[i];
|
|
else
|
|
text = mergedList[i];
|
|
end
|
|
end
|
|
end
|
|
|
|
fontString:SetText(text);
|
|
height = fontString:GetHeight();
|
|
width = fontString:GetWrappedWidth();
|
|
totalTextWidth = totalTextWidth + width;
|
|
|
|
if height > maxHeight then
|
|
maxHeight = height;
|
|
end
|
|
end
|
|
|
|
self.totalTextWidth = totalTextWidth;
|
|
self.fontStrings = fontStrings;
|
|
self.offsetY = fromOffsetY;
|
|
|
|
fromOffsetY = fromOffsetY - maxHeight - 48;
|
|
|
|
local header2 = parent:CreateFontString(nil, "OVERLAY", "NarciFontMedium13");
|
|
header2:SetPoint("TOP", anchorTo, "TOP", 0, fromOffsetY);
|
|
header2:SetText(string.upper("special thanks"));
|
|
SetTextColorByID(header2, 1);
|
|
|
|
|
|
text = nil;
|
|
for i = 1, #special do
|
|
if i == 1 then
|
|
text = special[i];
|
|
else
|
|
text = text .. "\n" .. special[i];
|
|
end
|
|
end
|
|
|
|
fromOffsetY = fromOffsetY - header2:GetHeight() - 12;
|
|
|
|
fontString = parent:CreateFontString(nil, "OVERLAY", "NarciFontMedium13");
|
|
fontString:SetPoint("TOPLEFT", anchorTo, "TOPLEFT", sidePadding, fromOffsetY);
|
|
fontString:SetJustifyH("LEFT");
|
|
fontString:SetJustifyV("TOP");
|
|
fontString:SetSpacing(8);
|
|
fontString:SetText(text);
|
|
SetTextColorByID(fontString, 1);
|
|
|
|
self.specialNames = fontString;
|
|
self.specialNamesOffsetY = fromOffsetY;
|
|
|
|
totalHeight = Round0(header:GetTop() - fontString:GetBottom() + 36);
|
|
|
|
self:UpdateAlignment();
|
|
|
|
wipe(active);
|
|
wipe(inactive);
|
|
active = nil;
|
|
inactive = nil;
|
|
|
|
return totalHeight
|
|
end
|
|
|
|
function CreditList:UpdateAlignment()
|
|
if self.fontStrings then
|
|
local offsetX = self.sidePadding;
|
|
local parentWidth = MainFrame.ScrollFrame:GetWidth();
|
|
|
|
local gap = (parentWidth - self.sidePadding*2 - self.totalTextWidth) * 0.5;
|
|
for col = 1, 3 do
|
|
self.fontStrings[col]:ClearAllPoints();
|
|
self.fontStrings[col]:SetPoint("TOPLEFT", self.anchorTo, "TOPLEFT", offsetX, self.offsetY);
|
|
offsetX = offsetX + self.fontStrings[col]:GetWrappedWidth() + gap;
|
|
end
|
|
|
|
local specialNameWidth = self.specialNames:GetWrappedWidth();
|
|
offsetX = (parentWidth - specialNameWidth) * 0.5;
|
|
self.specialNames:SetPoint("TOPLEFT", self.anchorTo, "TOPLEFT", offsetX, self.specialNamesOffsetY);
|
|
end
|
|
end
|
|
|
|
function CreditList.TimerOnUpdate(f, elapsed)
|
|
f.t = f.t + elapsed;
|
|
if f.t > 3 then
|
|
f.t = 0;
|
|
LoveGenerator:CreateHeartAtCursorPosition();
|
|
end
|
|
end
|
|
|
|
function CreditList:OnFocused(state)
|
|
if state then
|
|
if not self.focused then
|
|
self.focused = true;
|
|
self.parent.t = 0;
|
|
self.parent:SetScript("OnUpdate", CreditList.TimerOnUpdate);
|
|
FadeFrame(MainFrame.HeartContainer, 0.5, 1);
|
|
end
|
|
else
|
|
if self.focused then
|
|
self.focused = nil;
|
|
self.parent:SetScript("OnUpdate", nil);
|
|
FadeFrame(MainFrame.HeartContainer, 0.5, 0);
|
|
end
|
|
end
|
|
end
|
|
|
|
function CreditList:StopAnimation()
|
|
if self.focused then
|
|
LoveGenerator:StopAnimation();
|
|
end
|
|
end
|
|
|
|
|
|
local AboutTab = {};
|
|
|
|
function AboutTab:CreateTab(parent, anchorTo, fromOffsetY)
|
|
self.anchorTo = anchorTo;
|
|
|
|
local sidePadding = PADDING_H + BUTTON_LEVEL_OFFSET;
|
|
self.sidePadding = sidePadding;
|
|
|
|
--Version Info
|
|
local fontString = parent:CreateFontString(nil, "OVERLAY", "NarciFontMedium13");
|
|
fontString:SetJustifyH("LEFT");
|
|
fontString:SetJustifyV("TOP");
|
|
SetTextColorByID(fontString, 1);
|
|
fontString:SetSpacing(8);
|
|
fontString:SetPoint("TOPLEFT", anchorTo, "TOPLEFT", sidePadding, fromOffsetY);
|
|
|
|
local version, releaseDate, timeDiff = NarciAPI.GetAddOnVersionInfo();
|
|
local text = L["Version Colon"]..version.."\n"..L["Date Colon"]..releaseDate;
|
|
if timeDiff then
|
|
text = text .." ("..timeDiff..")";
|
|
end
|
|
text = text .. "\n"..L["Developer Colon"].."Peterodox";
|
|
|
|
fontString:SetText(text);
|
|
|
|
local textHeight = Round0(fontString:GetHeight());
|
|
fromOffsetY = fromOffsetY - textHeight - 2*WIDGET_GAP;
|
|
|
|
|
|
--Project Websites
|
|
local projectHeader = parent:CreateFontString(nil, "OVERLAY", "NarciFontMedium13");
|
|
projectHeader:SetJustifyH("LEFT");
|
|
projectHeader:SetJustifyV("TOP");
|
|
SetTextColorByID(projectHeader, 1);
|
|
projectHeader:SetText(L["Project Page"]);
|
|
projectHeader:SetPoint("TOP", anchorTo, "TOP", 0, fromOffsetY);
|
|
self.projectHeader = projectHeader;
|
|
|
|
--Animation after successfully copying link
|
|
local animFadeIn = projectHeader:CreateAnimationGroup();
|
|
local fadeIn1 = animFadeIn:CreateAnimation("Alpha");
|
|
fadeIn1:SetOrder(1);
|
|
fadeIn1:SetFromAlpha(0);
|
|
fadeIn1:SetToAlpha(1);
|
|
fadeIn1:SetDuration(0.25);
|
|
|
|
local animSuccess = projectHeader:CreateAnimationGroup();
|
|
projectHeader.animSuccess = animSuccess;
|
|
local fadeOut1 = animSuccess:CreateAnimation("Alpha");
|
|
fadeOut1:SetOrder(1);
|
|
fadeOut1:SetFromAlpha(1);
|
|
fadeOut1:SetToAlpha(0);
|
|
fadeOut1:SetDuration(0.25);
|
|
fadeOut1:SetStartDelay(1);
|
|
fadeOut1:SetScript("OnFinished", function()
|
|
projectHeader:SetText(L["Project Page"]);
|
|
animFadeIn:Play();
|
|
end);
|
|
|
|
|
|
fromOffsetY = fromOffsetY - 24;
|
|
|
|
local addonPages = {
|
|
{"Curseforge", "https://wow.curseforge.com/projects/narcissus"};
|
|
{"Wago", "https://addons.wago.io/addons/narcissus"},
|
|
};
|
|
|
|
local numWebsiteButton = #addonPages;
|
|
local textWidth;
|
|
self.websiteButtons = {};
|
|
self.websiteButtonFromOffsetY = fromOffsetY;
|
|
|
|
for i = 1, numWebsiteButton do
|
|
self.websiteButtons[i] = CreateFrame("Button", nil, parent, "NarciSettingsClipboardButtonTemplate");
|
|
self.websiteButtons[i]:SetPoint("TOPLEFT", anchorTo, "TOPLEFT", sidePadding, fromOffsetY);
|
|
self.websiteButtons[i].ButtonText:SetText(addonPages[i][1]);
|
|
self.websiteButtons[i].link = addonPages[i][2];
|
|
self.websiteButtons[i].Logo:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\Website-"..addonPages[i][1]);
|
|
textWidth = self.websiteButtons[i].ButtonText:GetWrappedWidth();
|
|
self.websiteButtons[i].ButtonText:SetWidth(textWidth + 2);
|
|
self.websiteButtons[i].id = i;
|
|
end
|
|
|
|
fromOffsetY = fromOffsetY - 48 - 2*WIDGET_GAP;
|
|
|
|
--Other Notes & Social Media
|
|
local notes = parent:CreateFontString(nil, "OVERLAY", "NarciFontMedium13");
|
|
notes:SetJustifyH("LEFT");
|
|
notes:SetJustifyV("TOP");
|
|
notes:SetSpacing(4);
|
|
notes:SetPoint("TOPLEFT", anchorTo, "TOPLEFT", sidePadding, fromOffsetY);
|
|
notes:SetPoint("RIGHT", anchorTo, "RIGHT", -sidePadding, 0);
|
|
notes:SetText(L["AboutTab Developer Note"]);
|
|
SetTextColorByID(notes, 1);
|
|
|
|
local platLogo, platName;
|
|
for i = 1, 2 do
|
|
platLogo = parent:CreateTexture(nil, "OVERLAY");
|
|
platLogo:SetSize(24, 24);
|
|
platLogo:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\PlatformLogo");
|
|
if i == 1 then
|
|
platLogo:SetPoint("TOPLEFT", notes, "BOTTOMLEFT", 0, -24 + 4)
|
|
platLogo:SetTexCoord(0, 0.5, 0, 1);
|
|
else
|
|
platLogo:SetPoint("LEFT", platName, "RIGHT", 24, 0);
|
|
platLogo:SetTexCoord(0.5, 1, 0, 1);
|
|
end
|
|
platName = parent:CreateFontString(nil, "OVERLAY", "NarciFontMedium13");
|
|
platName:SetJustifyH("LEFT");
|
|
platName:SetJustifyV("MIDDLE");
|
|
platName:SetText("Peterodox");
|
|
platName:SetPoint("LEFT", platLogo, "RIGHT", 2, 0);
|
|
SetTextColorByID(platName, 1);
|
|
SetTextureColorByID(platLogo, 2);
|
|
end
|
|
end
|
|
|
|
function AboutTab:UpdateWebsiteButtons(selectedButtonID)
|
|
if self.websiteButtons then
|
|
local parentWidth = MainFrame.ScrollFrame:GetWidth();
|
|
local numWebsiteButton = #self.websiteButtons;
|
|
local websiteButtonGap = BUTTON_LEVEL_OFFSET;
|
|
|
|
if selectedButtonID then
|
|
--make the selected one maximized and minimize other ones
|
|
self.projectHeader:StopAnimating();
|
|
self.projectHeader:SetText(L["Press Copy Yellow"]);
|
|
|
|
local fromOffsetX = self.sidePadding;
|
|
local minimizedWidth = 36.0;
|
|
local maximizedWidth = Round0( parentWidth - 2*self.sidePadding - (numWebsiteButton - 1) * (minimizedWidth + websiteButtonGap) )
|
|
for i, button in ipairs(self.websiteButtons) do
|
|
button:ClearAllPoints();
|
|
button:SetPoint("TOPLEFT", self.anchorTo, "TOPLEFT", fromOffsetX, self.websiteButtonFromOffsetY);
|
|
if button.id == selectedButtonID then
|
|
button:SetLogoOnlyMode(false);
|
|
button.ButtonText:Hide();
|
|
button:SetWidth(maximizedWidth);
|
|
fromOffsetX = fromOffsetX + maximizedWidth + websiteButtonGap;
|
|
else
|
|
button:SetLogoOnlyMode(true);
|
|
button:SetWidth(minimizedWidth);
|
|
button.isActive = nil;
|
|
if not button:IsMouseOver() then
|
|
button:OnLeave();
|
|
end
|
|
fromOffsetX = fromOffsetX + minimizedWidth + websiteButtonGap;
|
|
end
|
|
|
|
end
|
|
else
|
|
--equal width
|
|
if not self.projectHeader.animSuccess:IsPlaying() then
|
|
self.projectHeader:SetText(L["Project Page"]);
|
|
end
|
|
|
|
local websiteButtonWidth = Round0( (parentWidth - 2*self.sidePadding - (numWebsiteButton - 1)*websiteButtonGap) / numWebsiteButton );
|
|
for i, button in ipairs(self.websiteButtons) do
|
|
button:ClearAllPoints();
|
|
button:SetPoint("TOPLEFT", self.anchorTo, "TOPLEFT", self.sidePadding + (i - 1)*(websiteButtonWidth + websiteButtonGap), self.websiteButtonFromOffsetY);
|
|
button:SetWidth(websiteButtonWidth);
|
|
button.maximizedWidth = websiteButtonWidth;
|
|
button:SetLogoOnlyMode(false);
|
|
button.Logo:Show();
|
|
button.isActive = nil;
|
|
if button:IsMouseOver() then
|
|
button:OnEnter();
|
|
else
|
|
button:OnLeave();
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
---- Minimap Button Skin ----
|
|
local MinimapButtonSkin = {};
|
|
|
|
function MinimapButtonSkin.OnEnter(self)
|
|
self.AnimIn:Stop();
|
|
self.AnimDelay:Stop();
|
|
self.AnimDelay:Play();
|
|
SetTextColorByID(self.SkinName, 3);
|
|
end
|
|
|
|
function MinimapButtonSkin.OnDelayFinished(self)
|
|
local button = self:GetParent();
|
|
button.AnimIn:Play();
|
|
button.AnimIn.Bounce1:SetDuration(0.2);
|
|
button.AnimIn.Bounce2:SetDuration(0.2);
|
|
button.AnimIn.Hold1:SetDuration(20);
|
|
button.AnimIn.Hold2:SetDuration(20);
|
|
FadeFrame(button.HighlightTexture, 0.2, 1);
|
|
end
|
|
|
|
function MinimapButtonSkin.OnLeave(self)
|
|
self.AnimDelay:Stop();
|
|
self.AnimIn.Bounce1:SetDuration(0);
|
|
self.AnimIn.Bounce2:SetDuration(0);
|
|
self.AnimIn.Hold1:SetDuration(0);
|
|
self.AnimIn.Hold2:SetDuration(0);
|
|
FadeFrame(self.HighlightTexture, 0.2, 0);
|
|
SetTextColorByID(self.SkinName, 2);
|
|
end
|
|
|
|
function MinimapButtonSkin.OnClick(self)
|
|
NarcissusDB.MinimapIconStyle = self.skinID;
|
|
Narci_MinimapButton:SetBackground();
|
|
MinimapButtonSkin:UpdateState();
|
|
end
|
|
|
|
function MinimapButtonSkin.CreateOptions(parentLabel, parent, anchorTo, fromOffsetY)
|
|
local data = {
|
|
{"Minimap\\LOGO-Cyan", "Dark"},
|
|
{"Minimap\\LOGO-Thick", "AzeriteUI"},
|
|
{"Minimap\\LOGO-Hollow", "SexyMap"},
|
|
{"Minimap\\LOGO-Dragonflight", "Dragonflight"},
|
|
};
|
|
|
|
local buttonWidth = 64;
|
|
local buttonHeight = 64;
|
|
local buttonPerRow = 4;
|
|
local gap = 0;
|
|
|
|
local self = MinimapButtonSkin;
|
|
|
|
self.buttonWidth = buttonWidth;
|
|
self.buttonHeight = buttonHeight;
|
|
self.buttonPerRow = buttonPerRow;
|
|
self.gap = gap;
|
|
self.fromOffsetY = fromOffsetY + 24;
|
|
self.buttons = {};
|
|
self.anchorTo = anchorTo;
|
|
self.container = CreateFrame("Frame", nil, parent);
|
|
--self.container:Hide();
|
|
--self.container:SetAlpha(0);
|
|
|
|
local col, row = 1, 1;
|
|
local b;
|
|
|
|
for i = 1, #data do
|
|
self.buttons[i] = CreateFrame("Button", nil, self.container, "NarciMinimapSkinOptionTemplate");
|
|
b = self.buttons[i];
|
|
if col > buttonPerRow then
|
|
col = 1;
|
|
row = row + 1;
|
|
end
|
|
b:SetPoint("TOPLEFT", anchorTo, "TOPLEFT", PADDING_H + (i - 1) * (buttonWidth + gap), fromOffsetY - (row - 1)*(buttonHeight + gap));
|
|
b:SetScript("OnEnter", self.OnEnter);
|
|
b:SetScript("OnLeave", self.OnLeave);
|
|
b:SetScript("OnClick", self.OnClick);
|
|
b.AnimDelay:SetScript("OnFinished", self.OnDelayFinished)
|
|
b.skinID = i;
|
|
b.NormalTexture:SetTexture("Interface\\AddOns\\Narcissus\\Art\\"..data[i][1]);
|
|
b.HighlightTexture:SetTexture("Interface\\AddOns\\Narcissus\\Art\\"..data[i][1]);
|
|
b.SkinName:SetText(data[i][2]);
|
|
SetTextColorByID(b.SkinName, 2);
|
|
col = col + 1;
|
|
end
|
|
|
|
MinimapButtonSkin:UpdateAlignment();
|
|
|
|
table.insert(OptionButtons, MinimapButtonSkin);
|
|
|
|
local newHeight = row * (buttonHeight + gap) - gap;
|
|
local newObj = self.container;
|
|
|
|
return newHeight, newObj
|
|
end
|
|
|
|
function MinimapButtonSkin:UpdateAlignment()
|
|
local parentWidth = MainFrame.ScrollFrame:GetWidth();
|
|
--local gap = (parentWidth - 2 * PADDING_H)/self.buttonPerRow;
|
|
local gap = (parentWidth - 2 * 30 - (self.buttonWidth*self.buttonPerRow))/(self.buttonPerRow - 1);
|
|
if gap > 48 then
|
|
gap = 48;
|
|
end
|
|
|
|
local fromOffsetX = 0.5*(parentWidth - (self.buttonPerRow * (self.buttonWidth + gap) - gap) );
|
|
local col, row = 1, 0;
|
|
|
|
for i, b in ipairs(self.buttons) do
|
|
if col > self.buttonPerRow then
|
|
col = 1;
|
|
row = row + 1;
|
|
end
|
|
b:ClearAllPoints();
|
|
b:SetPoint("TOPLEFT", self.anchorTo, "TOPLEFT", fromOffsetX + (i - 1) * (self.buttonWidth + gap), self.fromOffsetY - row*(self.buttonHeight + gap));
|
|
end
|
|
end
|
|
|
|
function MinimapButtonSkin:UpdateState()
|
|
local skinID = NarcissusDB.MinimapIconStyle;
|
|
if not skinID then
|
|
skinID = 0;
|
|
end
|
|
for i, b in ipairs(self.buttons) do
|
|
b.Selection:SetShown(i == skinID);
|
|
end
|
|
end
|
|
|
|
local function MinimapButtonToggle_OnValueChanged(self, state)
|
|
SettingFunctions.ShowMinimapButton(state);
|
|
if state then
|
|
Narci_MinimapButton:PlayBling();
|
|
end
|
|
end
|
|
|
|
local function MinimapButtonFadeOut_OnValueChanged(self, state)
|
|
SettingFunctions.FadeOutMinimapButton(state);
|
|
end
|
|
|
|
|
|
|
|
local LanguageSelector = {};
|
|
|
|
function LanguageSelector:CreateFrame()
|
|
if not self.frame then
|
|
self.frame = CreateFrame("Frame", nil, MainFrame.ScrollFrame);
|
|
local f = self.frame;
|
|
f:Hide();
|
|
f:SetSize(400, 300);
|
|
local frameLevel = 10;
|
|
f:SetPoint("CENTER", MainFrame.ScrollFrame, "CENTER", 0, 0);
|
|
f:SetFrameLevel(frameLevel);
|
|
f.BorderFrame = CreateFrame("Frame", nil, f);
|
|
f.BorderFrame:SetPoint("TOPLEFT", f, "TOPLEFT", 0, 0);
|
|
f.BorderFrame:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", 0, 0);
|
|
f.BorderFrame:SetFrameLevel(frameLevel + 6);
|
|
f.BackgroundFrame = CreateFrame("Frame", nil, f);
|
|
f.BackgroundFrame:SetPoint("TOPLEFT", f, "TOPLEFT", 0, 0);
|
|
f.BackgroundFrame:SetPoint("TOPLEFT", f, "TOPLEFT", 0, 0);
|
|
f.BackgroundFrame:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", 0, 0);
|
|
f.BackgroundFrame:SetFrameLevel(frameLevel - 2);
|
|
NarciAPI.NineSliceUtil.SetUp(f.BorderFrame, "settingsBorder", "backdrop");
|
|
NarciAPI.NineSliceUtil.SetUp(f.BackgroundFrame, "settingsBackground", "backdrop");
|
|
|
|
self.header = f:CreateFontString(nil, "OVERLAY", "NarciFontMedium13");
|
|
self.header:SetJustifyH("CENTER");
|
|
self.header:SetPoint("TOP", f, "TOP", 0, -PADDING_V);
|
|
SetTextColorByID(self.header, 1);
|
|
|
|
f:SetScript("OnShow", function()
|
|
f:RegisterEvent("GLOBAL_MOUSE_DOWN");
|
|
end);
|
|
|
|
f:SetScript("OnHide", function()
|
|
f:UnregisterEvent("GLOBAL_MOUSE_DOWN");
|
|
f:Hide();
|
|
end);
|
|
|
|
f:SetScript("OnEvent", function()
|
|
if not f:IsMouseOver() then
|
|
f:Hide();
|
|
end
|
|
end);
|
|
|
|
f:SetScript("OnMouseWheel", function()
|
|
f:Hide();
|
|
end)
|
|
|
|
f:SetScript("OnMouseDown", function(_, button)
|
|
if button == "RightButton" then
|
|
f:Hide();
|
|
end
|
|
end)
|
|
|
|
local gameLocale = GetLocale();
|
|
|
|
local LANGUAGES = {
|
|
{"enUS", LFG_LIST_LANGUAGE_ENUS},
|
|
{"frFR", LFG_LIST_LANGUAGE_FRFR},
|
|
{"deDE", LFG_LIST_LANGUAGE_DEDE},
|
|
{"itIT", LFG_LIST_LANGUAGE_ITIT},
|
|
{"koKR", LFG_LIST_LANGUAGE_KOKR},
|
|
{"ptBR", LFG_LIST_LANGUAGE_PTBR},
|
|
{"ruRU", LFG_LIST_LANGUAGE_RURU},
|
|
{"esES", ESES},
|
|
{"esMX", ESMX},
|
|
{"zhCN", ZHCN},
|
|
{"zhTW", ZHTW},
|
|
};
|
|
|
|
local MIN_LABEL_WIDTH = 74;
|
|
local MAX_ROW = math.ceil(#LANGUAGES / 2);
|
|
local row = 0;
|
|
local col = 0;
|
|
local offsetX = PADDING_H + BUTTON_LEVEL_OFFSET;
|
|
local offsetY = -24 - WIDGET_GAP;
|
|
|
|
self.choiceButtons = {};
|
|
|
|
local maxLabelThisCol = MIN_LABEL_WIDTH;
|
|
local labelWidth, buttonWidth;
|
|
local lastColButtonIndex;
|
|
local choiceButton;
|
|
|
|
for i, languageData in ipairs(LANGUAGES) do
|
|
row = row + 1;
|
|
if row > MAX_ROW then
|
|
col = col + 1;
|
|
row = 1;
|
|
buttonWidth = Round0(maxLabelThisCol + 22);
|
|
for j = i-1, i-MAX_ROW, -1 do
|
|
self.choiceButtons[j]:SetWidth(buttonWidth);
|
|
end
|
|
offsetX = offsetX + buttonWidth + 24 + 0.5*WIDGET_GAP;
|
|
maxLabelThisCol = MIN_LABEL_WIDTH;
|
|
lastColButtonIndex = i;
|
|
end
|
|
self.choiceButtons[i] = CreateFrame("Button", nil, f, "NarciSettingsSharedButtonTemplate");
|
|
choiceButton = self.choiceButtons[i];
|
|
choiceButton:SetPoint("TOPLEFT", f, "TOPLEFT", offsetX, offsetY - (row - 1) * (24 + 0.5*WIDGET_GAP));
|
|
choiceButton.locale = languageData[1];
|
|
choiceButton.Label:SetText(languageData[2]);
|
|
choiceButton:SetScript("OnClick", self.ChoiceButton_OnClick);
|
|
|
|
labelWidth = choiceButton.Label:GetWrappedWidth();
|
|
if labelWidth > maxLabelThisCol then
|
|
maxLabelThisCol = labelWidth;
|
|
end
|
|
|
|
if languageData[1] == gameLocale then
|
|
choiceButton:Disable();
|
|
choiceButton.alwaysOn = true;
|
|
end
|
|
end
|
|
|
|
buttonWidth = Round0(maxLabelThisCol + 22);
|
|
for j = lastColButtonIndex, #self.choiceButtons do
|
|
self.choiceButtons[j]:SetWidth(buttonWidth);
|
|
end
|
|
local frameWidth = math.max( (offsetX + buttonWidth + PADDING_H + BUTTON_LEVEL_OFFSET), Round0(self.header:GetWrappedWidth() + 2*PADDING_H) );
|
|
local frameHeight = 36 + WIDGET_GAP + MAX_ROW * (24 + 0.5*WIDGET_GAP);
|
|
f:SetSize(frameWidth, frameHeight);
|
|
end
|
|
end
|
|
|
|
function LanguageSelector:ShowSelector()
|
|
self:CreateFrame();
|
|
|
|
local isSingleChoice = DB.NameTranslationPosition == 2;
|
|
|
|
if isSingleChoice ~= self.isSingleChoice then
|
|
self.isSingleChoice = isSingleChoice;
|
|
local buttonType;
|
|
if isSingleChoice then
|
|
self.header:SetText(L["Select Language Single"]);
|
|
buttonType = "radio";
|
|
else
|
|
self.header:SetText(L["Select Language Multiple"]);
|
|
buttonType = "checkbox";
|
|
end
|
|
|
|
for i, button in ipairs(self.choiceButtons) do
|
|
button:SetButtonType(buttonType, true);
|
|
if button.alwaysOn then
|
|
SetTextColorByID(button.Label, 1);
|
|
SetTextureColorByID(button.Selection, 1);
|
|
SetTextureColorByID(button.Border, 1);
|
|
button.Selection:Hide();
|
|
end
|
|
end
|
|
end
|
|
|
|
self.frame:Show();
|
|
self:UpdateSelection();
|
|
end
|
|
|
|
function LanguageSelector:ToggleSelector()
|
|
if self.frame then
|
|
self.frame:SetShown(not self.frame:IsShown());
|
|
end
|
|
end
|
|
|
|
function LanguageSelector:UpdateSelection()
|
|
local languageText;
|
|
local isSingleChoice = DB.NameTranslationPosition == 2;
|
|
|
|
if self.choiceButtons then
|
|
if isSingleChoice then
|
|
local locale = DB.NamePlateLanguage;
|
|
for i, button in ipairs(self.choiceButtons) do
|
|
if button.alwaysOn then
|
|
button:SetState(false);
|
|
else
|
|
button:SetState(button.locale == locale);
|
|
end
|
|
end
|
|
languageText = locale;
|
|
else
|
|
local count = 0;
|
|
local isSelected;
|
|
for i, button in ipairs(self.choiceButtons) do
|
|
if not button.alwaysOn then
|
|
isSelected = DB.TooltipLanguages[button.locale];
|
|
button:SetState(isSelected);
|
|
if isSelected then
|
|
count = count + 1;
|
|
if count <= 3 then
|
|
if languageText then
|
|
languageText = languageText..", "..button.locale;
|
|
else
|
|
languageText = button.locale;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if count > 3 then
|
|
languageText = languageText..", +"..(count - 3);
|
|
end
|
|
end
|
|
else
|
|
|
|
if isSingleChoice then
|
|
local locale = DB.NamePlateLanguage;
|
|
if locale then
|
|
languageText = locale;
|
|
end
|
|
else
|
|
local count = 0;
|
|
for locale, state in pairs(DB.TooltipLanguages) do
|
|
if state then
|
|
count = count + 1;
|
|
if count <= 3 then
|
|
if languageText then
|
|
languageText = languageText..", "..locale;
|
|
else
|
|
languageText = locale;
|
|
end
|
|
end
|
|
if count > 3 then
|
|
languageText = languageText..", +"..(count - 3);
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if self.toggle then
|
|
if languageText then
|
|
self.toggle.Label:SetText(languageText);
|
|
else
|
|
self.toggle.Label:SetText(NONE);
|
|
end
|
|
end
|
|
end
|
|
|
|
function LanguageSelector.SetupToggle(f)
|
|
LanguageSelector.toggle = f;
|
|
|
|
f:SetScript("OnClick", function ()
|
|
LanguageSelector:ShowSelector();
|
|
end)
|
|
|
|
function f:UpdateState()
|
|
LanguageSelector:UpdateSelection();
|
|
end
|
|
|
|
f.Border:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\OpenNewWindowButton");
|
|
f.Border:SetTexCoord(0, 1, 0, 1);
|
|
f.Selection:Hide();
|
|
f.Selection:SetTexture(nil);
|
|
f.Highlight:SetTexture(nil);
|
|
f.Background:Hide();
|
|
f.Background:SetTexture(nil);
|
|
end
|
|
|
|
function LanguageSelector:IsCreatureDatabaseLoaded(locale)
|
|
locale = locale or "enUS";
|
|
if NarciCreatureInfo and NarciCreatureInfo.isLanguageLoaded[locale] then
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
function LanguageSelector:AreRequiredDatabaseLoaded()
|
|
local allLoaded = true;
|
|
|
|
if DB.TranslateName then
|
|
if DB.NameTranslationPosition == 2 then
|
|
local locale = DB.NamePlateLanguage;
|
|
allLoaded = self:IsCreatureDatabaseLoaded(locale);
|
|
else
|
|
local locales = DB.TooltipLanguages;
|
|
for locale, state in pairs(locales) do
|
|
if state then
|
|
allLoaded = allLoaded and self:IsCreatureDatabaseLoaded(locale);
|
|
if not allLoaded then
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if not allLoaded then
|
|
return false
|
|
end
|
|
|
|
if DB.SearchRelatives then
|
|
allLoaded = self:IsCreatureDatabaseLoaded("enUS");
|
|
end
|
|
|
|
return allLoaded
|
|
end
|
|
|
|
|
|
local function UpdateNPCSettings()
|
|
if NarciCreatureInfo then
|
|
NarciCreatureInfo.UpdateNPCSettings();
|
|
end
|
|
end
|
|
|
|
local function CheckReloadRequirement()
|
|
local allLoaded = LanguageSelector:AreRequiredDatabaseLoaded();
|
|
if allLoaded then
|
|
--AlertMessageFrame:Hide();
|
|
else
|
|
AlertMessageFrame:ShowRequiresReload();
|
|
end
|
|
end
|
|
|
|
|
|
function LanguageSelector.ChoiceButton_OnClick(f)
|
|
if LanguageSelector.isSingleChoice then
|
|
DB.NamePlateLanguage = f.locale;
|
|
else
|
|
DB.TooltipLanguages[f.locale] = not DB.TooltipLanguages[f.locale];
|
|
end
|
|
LanguageSelector:UpdateSelection();
|
|
CheckReloadRequirement();
|
|
end
|
|
|
|
local function TranslateNameToggle_OnValueChanged(self, state)
|
|
UpdateNPCSettings();
|
|
if state then
|
|
CheckReloadRequirement();
|
|
end
|
|
end
|
|
|
|
local function NameTranslationPosition_OnValueChanged(self, index)
|
|
LanguageSelector:UpdateSelection();
|
|
UpdateNPCSettings();
|
|
CheckReloadRequirement();
|
|
end
|
|
|
|
local function NameTranslationPosition_Setup(lastRadioButton)
|
|
local groupID = lastRadioButton.groupID;
|
|
local buttons = WidgetGroups[groupID];
|
|
if buttons then
|
|
for i, button in ipairs(buttons) do
|
|
if i == 2 then
|
|
local f = CreateFrame("Frame", nil, button, "NarciSettingsSliderTemplate");
|
|
local labelWidth = Round0(button.Label:GetWrappedWidth());
|
|
f:SetPoint("TOPLEFT", button, "TOPLEFT", labelWidth, 0);
|
|
f.Label:SetText(L["Offset Y"]);
|
|
SetTextColorByID(f.Label, 2);
|
|
local slider = f.Slider;
|
|
SetTextColorByID(slider.ValueText, 2);
|
|
slider.key = "NamePlateNameOffset";
|
|
slider.valueFormatFunc = Round0;
|
|
slider.convertionFunc = Round0;
|
|
slider:SetMinMaxValues(-20, 20);
|
|
slider:SetObeyStepOnDrag(false);
|
|
slider.onValueChangedFunc = function(self, value)
|
|
if NarciCreatureInfo then
|
|
NarciCreatureInfo.SetNamePlateNameOffset(value);
|
|
end
|
|
end;
|
|
slider.getValueFunc = function()
|
|
return tonumber(DB.NamePlateNameOffset) or 0
|
|
end;
|
|
slider:SetSliderWidth(96, true);
|
|
slider:SetValue( slider.getValueFunc() );
|
|
f.Label:ClearAllPoints();
|
|
f.Label:SetPoint("BOTTOM", slider, "TOP", 0, 2);
|
|
f.Label:SetJustifyH("CENTER");
|
|
|
|
button.children = {};
|
|
button.children[1] = f;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function SearchRelativesToggle_OnValueChanged(self, state)
|
|
if state then
|
|
CheckReloadRequirement();
|
|
end
|
|
UpdateNPCSettings();
|
|
end
|
|
|
|
|
|
|
|
local function UpdateAlignment()
|
|
MinimapButtonSkin:UpdateAlignment();
|
|
CreditList:UpdateAlignment();
|
|
AboutTab:UpdateWebsiteButtons();
|
|
end
|
|
|
|
local function AddObjectAsChild(childObject, isTextObject)
|
|
local parentObj;
|
|
local i;
|
|
|
|
if isTextObject then
|
|
i = #OptionButtons;
|
|
else
|
|
i = #OptionButtons - 1;
|
|
end
|
|
parentObj = OptionButtons[i];
|
|
|
|
while parentObj and parentObj.isChild do
|
|
i = i - 1;
|
|
parentObj = OptionButtons[i];
|
|
end
|
|
|
|
if parentObj then
|
|
if not parentObj.children then
|
|
parentObj.children = {};
|
|
end
|
|
table.insert(parentObj.children, childObject);
|
|
childObject.isChild = true;
|
|
end
|
|
end
|
|
|
|
local function CreateWidget(parent, anchorTo, offsetX, offsetY, widgetData)
|
|
if widgetData.validityCheckFunc then
|
|
if not widgetData.validityCheckFunc() then
|
|
return nil, 0
|
|
end
|
|
end
|
|
|
|
local height;
|
|
local widgetType = widgetData.type;
|
|
local obj;
|
|
|
|
|
|
local isTextObject;
|
|
if widgetType == "header" or widgetType == "subheader" then
|
|
height = 12;
|
|
isTextObject = true;
|
|
else
|
|
height = 24;
|
|
end
|
|
|
|
if widgetData.extraTopPadding then
|
|
local extraOffset = WIDGET_GAP * widgetData.extraTopPadding;
|
|
offsetY = offsetY - extraOffset;
|
|
height = height + extraOffset;
|
|
end
|
|
|
|
if widgetData.isNew then
|
|
if widgetData.text then
|
|
widgetData.text = NARCI_NEW_ENTRY_PREFIX..widgetData.text.."|r"
|
|
end
|
|
end
|
|
|
|
if isTextObject then
|
|
obj = parent:CreateFontString(nil, "OVERLAY", "NarciFontMedium13");
|
|
|
|
if widgetData.alignToCenter then
|
|
obj:SetPoint("TOP", anchorTo, "TOP", 0, offsetY);
|
|
obj:SetJustifyH("CENTER");
|
|
else
|
|
obj:SetPoint("TOPLEFT", anchorTo, "TOPLEFT", offsetX + ((widgetData.level and widgetData.level * BUTTON_LEVEL_OFFSET) or 0), offsetY);
|
|
obj:SetJustifyH("LEFT");
|
|
end
|
|
|
|
obj:SetJustifyV("TOP");
|
|
SetTextColorByID(obj, 1);
|
|
height = height + WIDGET_GAP;
|
|
|
|
if widgetType == "header" then
|
|
obj:SetText(string.upper(widgetData.text));
|
|
else
|
|
obj:SetText(widgetData.text);
|
|
end
|
|
|
|
elseif widgetType == "radio" then
|
|
local numButtons = #widgetData.texts;
|
|
|
|
local preview;
|
|
local sectorHeight;
|
|
|
|
local groupID = #WidgetGroups + 1;
|
|
WidgetGroups[groupID] = {};
|
|
|
|
for i = 1, numButtons do
|
|
obj = CreateFrame("Button", nil, parent, "NarciSettingsSharedButtonTemplate");
|
|
table.insert(OptionButtons, obj);
|
|
obj:SetPoint("TOPLEFT", anchorTo, "TOPLEFT", offsetX + ((widgetData.level and widgetData.level * BUTTON_LEVEL_OFFSET) or 0), offsetY + (1 - i) * (24 + 0.5*WIDGET_GAP));
|
|
obj:SetButtonType("radio");
|
|
obj.groupID = groupID;
|
|
obj.id = i;
|
|
obj.key = widgetData.key;
|
|
obj:SetLabelText(widgetData.texts[i]);
|
|
|
|
if widgetData.previewImage and not preview then
|
|
preview = obj:CreateTexture(nil, "ARTWORK");
|
|
preview:SetSize(widgetData.previewWidth, widgetData.previewHeight);
|
|
preview:SetPoint("TOPRIGHT", anchorTo, "TOPRIGHT", -24, offsetY + (widgetData.previewOffsetY or 0));
|
|
preview:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\"..widgetData.previewImage);
|
|
sectorHeight = widgetData.previewHeight - (widgetData.previewOffsetY or 0);
|
|
end
|
|
obj.preview = preview;
|
|
SetTextColorByID(obj.Label, 2);
|
|
WidgetGroups[groupID][i] = obj;
|
|
obj.onValueChangedFunc = widgetData.onValueChangedFunc;
|
|
if widgetData.isChild then
|
|
AddObjectAsChild(obj);
|
|
end
|
|
obj.onEnterFunc = widgetData.onEnterFunc;
|
|
obj.onLeaveFunc = widgetData.onLeaveFunc;
|
|
|
|
if widgetData.showFeaturePreview then
|
|
obj.previewKey = widgetData.key..i;
|
|
end
|
|
end
|
|
|
|
height = (24 + 0.5*WIDGET_GAP) * numButtons;
|
|
if sectorHeight and height < sectorHeight then
|
|
height = sectorHeight;
|
|
end
|
|
height = height + WIDGET_GAP;
|
|
|
|
elseif widgetType == "checkbox" then
|
|
obj = CreateFrame("Button", nil, parent, "NarciSettingsSharedButtonTemplate");
|
|
table.insert(OptionButtons, obj);
|
|
obj:SetPoint("TOPLEFT", anchorTo, "TOPLEFT", offsetX + ((widgetData.level and widgetData.level * BUTTON_LEVEL_OFFSET) or 0), offsetY);
|
|
obj:SetButtonType("checkbox");
|
|
obj.key = widgetData.key;
|
|
obj:SetLabelText(widgetData.text);
|
|
SetTextColorByID(obj.Label, 2);
|
|
obj.onValueChangedFunc = widgetData.onValueChangedFunc;
|
|
|
|
if widgetData.description then
|
|
local desc = obj:CreateFontString(nil, "OVERLAY", "NarciFontThin13");
|
|
obj.description = desc;
|
|
SetTextColorByID(desc, 1);
|
|
desc:SetSpacing(4);
|
|
desc:SetJustifyH("LEFT");
|
|
desc:SetJustifyV("TOP");
|
|
desc:SetPoint("TOPLEFT", obj.Label, "BOTTOMLEFT", 0, -6);
|
|
desc:SetWidth(300);
|
|
desc:SetText(widgetData.description);
|
|
|
|
local extraHeight = obj:GetBottom() - desc:GetBottom();
|
|
extraHeight = Round0(extraHeight);
|
|
height = height + extraHeight;
|
|
end
|
|
|
|
height = height + WIDGET_GAP;
|
|
|
|
if widgetData.showFeaturePreview then
|
|
obj.previewKey = widgetData.key;
|
|
end
|
|
|
|
elseif widgetType == "slider" then
|
|
obj = CreateFrame("Frame", nil, parent, "NarciSettingsSliderTemplate");
|
|
local slider = obj.Slider;
|
|
table.insert(OptionButtons, slider);
|
|
obj:SetPoint("TOPLEFT", anchorTo, "TOPLEFT", offsetX + ((widgetData.level and widgetData.level * BUTTON_LEVEL_OFFSET) or 0), offsetY);
|
|
SetTextColorByID(obj.Label, 2);
|
|
SetTextColorByID(slider.ValueText, 2);
|
|
obj.Label:SetText(widgetData.text);
|
|
slider.key = widgetData.key;
|
|
slider.valueFormatFunc = widgetData.valueFormatFunc;
|
|
slider.convertionFunc = widgetData.convertionFunc;
|
|
slider:SetMinMaxValues(widgetData.minValue, widgetData.maxValue);
|
|
|
|
if widgetData.valueStep then
|
|
slider:SetValueStep(widgetData.valueStep);
|
|
slider:SetObeyStepOnDrag(true);
|
|
else
|
|
slider:SetObeyStepOnDrag(false);
|
|
end
|
|
|
|
slider.onValueChangedFunc = widgetData.onValueChangedFunc;
|
|
slider.getValueFunc = widgetData.getValueFunc;
|
|
|
|
if widgetData.sliderWidth then
|
|
slider:SetSliderWidth(widgetData.sliderWidth, true);
|
|
end
|
|
|
|
height = height + WIDGET_GAP;
|
|
|
|
--local left = MainFrame.ScrollFrame:GetLeft();
|
|
--local right = slider:GetRight() + PADDING_H;
|
|
--print(left - right);
|
|
elseif widgetType == "keybinding" then
|
|
obj = CreateFrame("Button", nil, parent, "NarciSettingsKeybindingButtonTemplate");
|
|
table.insert(OptionButtons, obj);
|
|
obj:SetPoint("TOP", anchorTo, "TOP", (widgetData.level and widgetData.level * BUTTON_LEVEL_OFFSET) or 0, offsetY);
|
|
obj.Label:SetText(widgetData.text);
|
|
if widgetData.externalAction then
|
|
obj:SetExternalAction(widgetData.externalAction);
|
|
else
|
|
obj:SetInternalAction(widgetData.internalAction);
|
|
end
|
|
height = 24 + WIDGET_GAP;
|
|
end
|
|
|
|
if widgetType ~= "radio" then
|
|
obj.onEnterFunc = widgetData.onEnterFunc;
|
|
obj.onLeaveFunc = widgetData.onLeaveFunc;
|
|
if widgetData.isChild then
|
|
AddObjectAsChild(obj, isTextObject);
|
|
end
|
|
end
|
|
|
|
if widgetData.setupFunc then
|
|
local extraHeight, newObject = widgetData.setupFunc(obj, parent, anchorTo, offsetY - height);
|
|
if extraHeight then
|
|
height = height + extraHeight;
|
|
end
|
|
if newObject and widgetData.isChild then
|
|
AddObjectAsChild(newObject);
|
|
end
|
|
end
|
|
|
|
return obj, Round0(height)
|
|
end
|
|
|
|
|
|
local Categories = {
|
|
--{ CategoryName }
|
|
{name = L["Character Panel"], level = 0, key = "characterPanel",
|
|
widgets = {
|
|
{type = "header", level = 0, text = L["Character Panel"]},
|
|
{type = "slider", level = 1, key = "GlobalScale", text = UI_SCALE, onValueChangedFunc = CharacterUIScale_OnValueChanged, minValue = 0.7, maxValue = 1, valueStep = 0.1, },
|
|
{type = "slider", level = 1, key = "BaseLineOffset", text = L["Baseline Offset"], validityCheckFunc = IsUsingUltraWideMonitor, onValueChangedFunc = UltraWideOffset_OnValueChanged, minValue = 0, maxValue = ULTRAWIDE_MAX_OFFSET, valueStep = ULTRAWIDE_STEP, },
|
|
{type = "checkbox", level = 1, key = "MissingEnchantAlert", text = L["Missing Enchant Alert"], onValueChangedFunc = ShowMisingEnchantAlert_OnValueChanged, validityCheckFunc = ShowMisingEnchantAlert_IsValid, isNew = false},
|
|
{type = "checkbox", level = 1, key = "DetailedIlvlInfo", text = L["Show Detailed Stats"], onValueChangedFunc = ShowDetailedStats_OnValueChanged},
|
|
{type = "checkbox", level = 1, key = "AFKScreen", text = L["AFK Screen Description"], onValueChangedFunc = AFKToggle_OnValueChanged, },
|
|
{type = "checkbox", level = 3, key = "AKFScreenDelay", text = L["AFK Screen Delay"], onValueChangedFunc = nil, isChild = true},
|
|
{type = "subheader", level = 1, text = L["Item Names"], extraTopPadding = 1},
|
|
{type = "slider", level = 1, key = "FontHeightItemName", text = FONT_SIZE, onValueChangedFunc = ItemNameHeight_OnValueChanged, minValue = 10, maxValue = 12, valueStep = 1, },
|
|
{type = "slider", level = 1, key = "ItemNameWidth", text = L["Text Width"], onValueChangedFunc = ItemNameWidth_OnValueChanged, minValue = 100, maxValue = 200, valueStep = 20, },
|
|
{type = "checkbox", level = 1, key = "TruncateText", text = L["Truncate Text"], onValueChangedFunc = TruncateTextToggle_OnValueChanged},
|
|
},
|
|
},
|
|
|
|
{name = L["Hotkey"], level = 1, key = "hotkey",
|
|
widgets = {
|
|
{type = "header", level = 0, text = L["Hotkey"]},
|
|
{type = "keybinding", level = 1, text = L["Open Narcissus"], externalAction = BIND_ACTION_NARCISSUS},
|
|
{type = "checkbox", level = 1, key = "EnableDoubleTap", extraTopPadding = 1, text = L["Double Tap"], description = L["Double Tap Description"], onValueChangedFunc = DoubleTap_OnValueChanged, setupFunc = DoubleTap_Setup},
|
|
{type = "checkbox", level = 1, key = "UseEscapeButton", text = L["Use Escape Button"], description = L["Use Escape Button Description"], onValueChangedFunc = UseEscapeKey_OnValueChanged},
|
|
},
|
|
},
|
|
|
|
{name = L["Item Tooltip"], level = 1, key = "itemTooltip",
|
|
widgets = {
|
|
{type = "header", level = 0, text = L["Item Tooltip"]},
|
|
{type = "subheader", level = 1, text= L["Style"]},
|
|
{type = "radio", level = 1, key = "ItemTooltipStyle", texts = {L["Tooltip Style 1"], L["Tooltip Style 2"]}, onValueChangedFunc = ItemTooltipStyle_OnValueChanged, onEnterFunc = ItemTooltipStyle_OnEnter, onLeaveFunc = ItemTooltipStyle_OnLeave},
|
|
{type = "subheader", level = 1, text = L["Addtional Info"], extraTopPadding = 0},
|
|
{type = "checkbox", level = 1, key = "ShowItemID", text = L["Item ID"], onValueChangedFunc = ItemTooltipShowItemID_OnValueChanged},
|
|
},
|
|
},
|
|
|
|
{name = L["Screen Effects"], level = 1, key = "screenEffects",
|
|
widgets = {
|
|
{type = "header", level = 0, text = L["Screen Effects"]},
|
|
{type = "slider", level = 1, key = "VignetteStrength", text = L["Vignette Strength"], valueFormatFunc = Round1, convertionFunc = Round1, onValueChangedFunc = VignetteStrength_OnValueChanged, minValue = 0, maxValue = 1, valueStep = nil, },
|
|
{type = "checkbox", level = 1, key = "WeatherEffect", text = L["Weather Effect"], onValueChangedFunc = WeatherEffectToggle_OnValueChanged},
|
|
{type = "checkbox", level = 1, key = "LetterboxEffect", text = L["Letterbox"], validityCheckFunc = Letterbox_IsCompatible, onValueChangedFunc = LetterboxToggle_OnValueChanged},
|
|
{type = "slider", level = 3, key = "LetterboxRatio", text = L["Letterbox Ratio"], validityCheckFunc = Letterbox_IsCompatible, isChild = true, onValueChangedFunc = LetterboxRatio_OnValueChanged, minValue = 2, maxValue = 2.35, valueStep = 0.35, sliderWidth = 64, valueFormatFunc = ValueFormat_LetterboxRatio, },
|
|
},
|
|
},
|
|
|
|
{name = L["Camera"], level = 1, key = "camera",
|
|
widgets = {
|
|
{type = "header", level = 0, text = L["Camera"]},
|
|
{type = "checkbox", level = 1, key = "CameraTransition", text = L["Camera Transition"], onValueChangedFunc = CameraTransition_OnValueChanged, description = L["Camera Transition Description Off"], setupFunc = CameraTransition_SetupDescription},
|
|
{type = "checkbox", level = 1, key = "CameraOrbit", text = L["Orbit Camera"], onValueChangedFunc = CameraOrbitToggle_OnValueChanged, description = L["Orbit Camera Description On"], setupFunc = CameraOrbitToggle_SetupDescription},
|
|
{type = "checkbox", level = 1, key = "CameraSafeMode", text = L["Camera Safe Mode"], onValueChangedFunc = CameraSafeToggle_OnValueChanged, description = L["Camera Safe Mode Description"], validityCheckFunc = CameraSafeToggle_IsValid},
|
|
{type = "checkbox", level = 1, key = "UseBustShot", text = L["Use Bust Shot"], onValueChangedFunc = CameraUseBustShot_OnValueChanged},
|
|
},
|
|
},
|
|
|
|
{name = L["Minimap Button"], level = 0, key = "minimapButton",
|
|
widgets = {
|
|
{type = "header", level = 0, text = L["Minimap Button"]},
|
|
{type = "checkbox", level = 1, key = "ShowMinimapButton", text = ENABLE, onValueChangedFunc = MinimapButtonToggle_OnValueChanged},
|
|
{type = "checkbox", level = 3, customButtonScript = true, text = RESET_POSITION or "Reset Position", isChild = true, setupFunc = ResetMinimapPosition_Setup},
|
|
{type = "checkbox", level = 3, key = "ShowModulePanelOnMouseOver", text = L["Show Module Panel Gesture"], isChild = true, onValueChangedFunc = ShowMinimapModulePanel_OnValueChanged},
|
|
{type = "checkbox", level = 3, key = "IndependentMinimapButton", text = L["Independent Minimap Button"], isChild = true, onValueChangedFunc = IndependentMinimapButtonToggle_OnValueChanged},
|
|
{type = "checkbox", level = 3, key = "FadeButton", text = L["Fade Out Description"], isChild = true, onValueChangedFunc = MinimapButtonFadeOut_OnValueChanged},
|
|
{type = "subheader", level = 3, text = L["Style"], extraTopPadding = 1, isChild = true, setupFunc = MinimapButtonSkin.CreateOptions},
|
|
},
|
|
},
|
|
|
|
{name = L["Photo Mode"], level = 0, key = "photoMode",
|
|
widgets = {
|
|
{type = "header", level = 0, text = L["Photo Mode"]},
|
|
{type = "checkbox", level = 1, key = "LoopAnimation", text = L["Loop Animation"], onValueChangedFunc = LoopAnimation_OnValueChanged},
|
|
{type = "slider", level = 1, key = "screenshotQuality", text = L["Sceenshot Quality"], onValueChangedFunc = ScreenshotQuality_OnValueChanged, minValue = 3, maxValue = 10, getValueFunc = ScreenshotQuality_GetValue, valueFormatFunc = Round0, convertionFunc = Round0},
|
|
{type = "subheader", level = 1, text = L["Screenshot Quality Description"]},
|
|
{type = "slider", level = 1, key = "ModelPanelScale", text = L["Panel Scale"], onValueChangedFunc = ModelPanelScale_OnValueChanged, minValue = 0.8, maxValue = 1, valueStep = 0.1, extraTopPadding = 1, valueFormatFunc = Round1},
|
|
{type = "slider", level = 1, key = "ShrinkArea", text = L["Interactive Area"], onValueChangedFunc = ModelHitRectShrinkage_OnValueChanged, minValue = 0, maxValue = MAX_MODEL_SHRINKAGE, valueFormatFunc = GetOppositeValue, convertionFunc = Round0},
|
|
},
|
|
},
|
|
|
|
{name = "NPC", level = 0, key = "npc",
|
|
widgets = {
|
|
{type = "header", level = 0, text = L["Creature Tooltip"]},
|
|
{type = "checkbox", level = 1, key = "SearchRelatives", text = L["Find Relatives"], onValueChangedFunc = SearchRelativesToggle_OnValueChanged, },
|
|
{type = "checkbox", level = 1, key = "TranslateName", text = L["Translate Names"], onValueChangedFunc = TranslateNameToggle_OnValueChanged, },
|
|
{type = "subheader", level = 3, text = L["Translate Names Description"], extraTopPadding = 0, isChild = true},
|
|
{type = "radio", level = 3, key = "NameTranslationPosition", texts = {L["Tooltip"], L["Name Plate"]}, isChild = true, onValueChangedFunc = NameTranslationPosition_OnValueChanged, showFeaturePreview = true, onEnterFunc = FeaturePreview.ShowPreview, onLeaveFunc = FeaturePreview.HidePreview, setupFunc = NameTranslationPosition_Setup},
|
|
{type = "subheader", level = 3, text = L["Translate Names Languages"], extraTopPadding = 0, isChild = true},
|
|
{type = "checkbox", level = 3, text = "Select Languages", isChild = true, setupFunc = LanguageSelector.SetupToggle},
|
|
},
|
|
},
|
|
|
|
{name = L["Extensions"], level = 0, key = "extensions",
|
|
widgets = {
|
|
{type = "header", level = 0, text = L["Extensions"]},
|
|
{type = "checkbox", level = 1, key = "GemManager", text = L["Gem Manager"], onValueChangedFunc = GemManagerToggle_OnValueChanged, description = L["Gemma Description"]},
|
|
{type = "checkbox", level = 1, key = "DressingRoom", text = L["Dressing Room"], onValueChangedFunc = DressingRoomToggle_OnValueChanged, description = L["Dressing Room Description"]},
|
|
{type = "subheader", level = 1, text = L["Expansion Features"], extraTopPadding = 1},
|
|
{type = "checkbox", level = 1, key = "PaperDollWidget", text = L["Paperdoll Widget"], onValueChangedFunc = PaperDollWidgetToggle_OnValueChanged, showFeaturePreview = true, onEnterFunc = FeaturePreview.ShowPreview, onLeaveFunc = FeaturePreview.HidePreview},
|
|
--{type = "checkbox", level = 1, key = "ConduitTooltip", text = L["Conduit Tooltip"], onValueChangedFunc = ConduitTooltipToggle_OnValueChanged, showFeaturePreview = true, onEnterFunc = FeaturePreview.ShowPreview, onLeaveFunc = FeaturePreview.HidePreview},
|
|
},
|
|
},
|
|
|
|
|
|
|
|
{name = L["Credits"], level = 0, key = "credits", isBottom = true},
|
|
{name = L["About"], level = 0, key = "about", isBottom = true,
|
|
widgets = {
|
|
{type = "header", level = 0, text = L["About"]},
|
|
},
|
|
},
|
|
};
|
|
|
|
local function InsertCategory(newCategory)
|
|
table.insert(Categories, #Categories -1, newCategory);
|
|
end
|
|
|
|
if IS_DRAGONFLIGHT then
|
|
local function ShowTreeCase1(self, state)
|
|
SettingFunctions.ShowMiniTalentTreeForPaperDoll(state);
|
|
end
|
|
|
|
local function ShowTreeCase2(self, state)
|
|
SettingFunctions.ShowMiniTalentTreeForInspection(state);
|
|
end
|
|
|
|
local function ShowTreeCase3(self, state)
|
|
SettingFunctions.ShowMiniTalentTreeForEquipmentManager(state);
|
|
end
|
|
|
|
local function TalentTreeSetPosition(self, id)
|
|
SettingFunctions.SetTalentTreePosition(id);
|
|
end
|
|
|
|
local function TalentTreeUseClassBackground(self, state)
|
|
SettingFunctions.SetUseClassBackground(state);
|
|
end
|
|
|
|
local function TalentTreeUseBiggerUI(self, state)
|
|
SettingFunctions.SetUseBiggerUI(state);
|
|
end
|
|
|
|
local talentCategory = {name = TALENTS or "Talents", level = 1, key = "talents",
|
|
widgets = {
|
|
{type = "header", level = 0, text = L["Mini Talent Tree"]},
|
|
{type = "subheader", level = 1, text = L["Show Talent Tree When"]},
|
|
{type = "checkbox", level = 1, key = "TalentTreeForPaperDoll",text = L["Show Talent Tree Paperdoll"], onValueChangedFunc = ShowTreeCase1},
|
|
{type = "checkbox", level = 1, key = "TalentTreeForInspection", text = L["Show Talent Tree Inspection"], onValueChangedFunc = ShowTreeCase2},
|
|
{type = "checkbox", level = 1, key = "TalentTreeForEquipmentManager", text = L["Show Talent Tree Equipment Manager"], onValueChangedFunc = ShowTreeCase3},
|
|
|
|
{type = "subheader", level = 1, text = L["Place UI"], extraTopPadding = 1},
|
|
{type = "radio", level = 1, key = "TalentTreeAnchor", texts = {L["Place Talent UI Right"], L["Place Talent UI Bottom"]}, onValueChangedFunc = TalentTreeSetPosition},
|
|
|
|
{type = "subheader", level = 1, text = L["Appearance"], extraTopPadding = 1},
|
|
{type = "checkbox", level = 1, key = "TalentTreeUseClassBackground", text = L["Use Class Background"], onValueChangedFunc = TalentTreeUseClassBackground},
|
|
{type = "checkbox", level = 1, key = "TalentTreeBiggerUI", text = L["Use Bigger UI"], onValueChangedFunc = TalentTreeUseBiggerUI},
|
|
}
|
|
};
|
|
|
|
InsertCategory(talentCategory);
|
|
|
|
|
|
local function NarciBagItemFilter_LoadAddOn()
|
|
if not NarciBagItemFilterSettings then
|
|
LoadAddOn("Narcissus_BagFilter");
|
|
end
|
|
end
|
|
|
|
local function ItemSearchToggle_OnValueChanged(self, state)
|
|
if state then
|
|
NarciBagItemFilter_LoadAddOn();
|
|
end
|
|
|
|
if NarciBagItemFilterSettings then
|
|
NarciBagItemFilterSettings.SetEnableSearchSuggestion(state);
|
|
end
|
|
end
|
|
|
|
local function ItemSearchDirectionButton_OnValueChanged(self, id)
|
|
NarciBagItemFilterSettings.SetItemSearchPopupDirection(id);
|
|
if id == 1 then
|
|
self.preview:SetTexCoord(0, 0.5, 0, 0.8125);
|
|
else
|
|
self.preview:SetTexCoord(0.5, 1, 0, 0.8125);
|
|
end
|
|
end
|
|
|
|
local function ItemSearchDirection_Setup(radioButton)
|
|
if radioButton.preview then
|
|
if DB and DB.SearchSuggestDirection == 2 then
|
|
radioButton.preview:SetTexCoord(0.5, 1, 0, 0.8125);
|
|
else
|
|
radioButton.preview:SetTexCoord(0, 0.5, 0, 0.8125);
|
|
end
|
|
end
|
|
end
|
|
|
|
local function AutoFilterMail_OnValueChanged(self, state)
|
|
NarciBagItemFilterSettings.AutoFilterMail(state);
|
|
end
|
|
|
|
local function AutoFilterAuction_OnValueChanged(self, state)
|
|
NarciBagItemFilterSettings.AutoFilterAuction(state);
|
|
end
|
|
|
|
local function AutoFilterGem_OnValueChanged(self, state)
|
|
NarciBagItemFilterSettings.AutoFilterGem(state);
|
|
end
|
|
|
|
local function IsBagItemFilterAddOnLoaded()
|
|
--return NarciBagItemFilterSettings ~= nil
|
|
return true --changed this module to load-on-demand, so we need to keep its settings visible
|
|
end
|
|
|
|
local bagCategory = {name = L["Bag Item Filter"], level = 1, key = "bagitemfilter", validityCheckFunc = IsBagItemFilterAddOnLoaded,
|
|
widgets = {
|
|
{type = "header", level = 0, text = L["Bag Item Filter"]},
|
|
{type = "checkbox", level = 1, key = "SearchSuggestEnable", text = L["Bag Item Filter Enable"], onValueChangedFunc = ItemSearchToggle_OnValueChanged},
|
|
{type = "subheader", level = 3, text = L["Place Window"], extraTopPadding = 1, isChild = true},
|
|
{type = "radio", level = 3, key = "SearchSuggestDirection", texts = {L["Below Search Box"], L["Above Search Box"]}, onValueChangedFunc = ItemSearchDirectionButton_OnValueChanged, setupFunc = ItemSearchDirection_Setup,
|
|
previewImage = "Preview-PopupPosition", previewWidth = 200, previewHeight = 162, previewOffsetY = 28, isChild = true
|
|
},
|
|
{type = "subheader", level = 3, text = L["Auto Filter Case"], extraTopPadding = 1, isChild = true},
|
|
{type = "checkbox", level = 3, key = "AutoFilterMail", text = L["Send Mails"], onValueChangedFunc = AutoFilterMail_OnValueChanged, isChild = true},
|
|
{type = "checkbox", level = 3, key = "AutoFilterAuction", text = L["Create Auctions"], onValueChangedFunc = AutoFilterAuction_OnValueChanged, isChild = true},
|
|
{type = "checkbox", level = 3, key = "AutoFilterGem", text = L["Socket Items"], onValueChangedFunc = AutoFilterGem_OnValueChanged, isChild = true},
|
|
}};
|
|
|
|
InsertCategory(bagCategory);
|
|
|
|
|
|
local function AutoDisplayQuestItemToggle_OnValueChanged(self, state)
|
|
SettingFunctions.SetAutoDisplayQuestItem(state);
|
|
end
|
|
|
|
local function QuestCardStyleButton_OnValueChanged(self, id)
|
|
if id == 2 then
|
|
self.preview:SetTexCoord(0, 1, 0.375, 0.75);
|
|
else
|
|
self.preview:SetTexCoord(0, 1, 0, 0.375);
|
|
end
|
|
|
|
NarciQuestItemDisplay:SetTheme(id);
|
|
end
|
|
|
|
local function QuestCardStyle_Setup(radioButton)
|
|
if radioButton.preview then
|
|
if DB and DB.QuestCardTheme == 2 then
|
|
radioButton.preview:SetTexCoord(0, 1, 0.375, 0.75);
|
|
else
|
|
radioButton.preview:SetTexCoord(0, 1, 0, 0.375);
|
|
end
|
|
end
|
|
end
|
|
|
|
local function QuestCardPositionButton_Setup(f)
|
|
f:SetScript("OnClick", function ()
|
|
NarciQuestItemDisplay:ChangePosition()
|
|
end)
|
|
|
|
function f:UpdateState()
|
|
return
|
|
end
|
|
|
|
f.Border:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\FourWayArrow");
|
|
f.Border:SetTexCoord(0, 1, 0, 1);
|
|
f.Selection:Hide();
|
|
f.Selection:SetTexture(nil);
|
|
f.Highlight:SetTexture(nil);
|
|
f.Background:Hide();
|
|
f.Background:SetTexture(nil);
|
|
end
|
|
|
|
local questCategory = {name = TRANSMOG_SOURCE_2 or "Quest", level = 1, key = "quest",
|
|
widgets = {
|
|
{type = "header", level = 0, text = TRANSMOG_SOURCE_2 or "Quest"},
|
|
{type = "checkbox", level = 1, key = "AutoDisplayQuestItem", text = L["Auto Display Quest Item"], onValueChangedFunc = AutoDisplayQuestItemToggle_OnValueChanged},
|
|
{type = "subheader", level = 3, text = L["Appearance"], extraTopPadding = 1, isChild = true},
|
|
{type = "radio", level = 3, key = "QuestCardTheme", texts = {L["Border Theme Bright"], L["Border Theme Dark"]}, onValueChangedFunc = QuestCardStyleButton_OnValueChanged, setupFunc = QuestCardStyle_Setup,
|
|
previewImage = "Preview-QuestCardTheme", previewWidth = 200, previewHeight = 75, previewOffsetY = 10, isChild = true
|
|
},
|
|
{type = "checkbox", level = 3, text = L["Change Position"], isChild = true, setupFunc = QuestCardPositionButton_Setup},
|
|
}};
|
|
|
|
InsertCategory(questCategory);
|
|
end
|
|
|
|
|
|
local function SetupFrame()
|
|
if CategoryButtons then return end;
|
|
|
|
DB = NarcissusDB;
|
|
|
|
local f = MainFrame;
|
|
local texPath = "Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\";
|
|
|
|
f.CategoryFrame:SetWidth(DEFAULT_LEFT_WIDTH);
|
|
f.ScrollFrame.ScrollChild:SetWidth(DEFAULT_FRAME_WIDTH - DEFAULT_LEFT_WIDTH);
|
|
|
|
f.Divider = f.OverlayFrame:CreateTexture(nil, "OVERLAY", nil, 1);
|
|
f.Divider:SetPoint("TOP", f.CategoryFrame, "TOPRIGHT", 0, -1);
|
|
f.Divider:SetPoint("BOTTOM", f.CategoryFrame, "BOTTOMRIGHT", 0, 1);
|
|
f.Divider:SetWidth(32);
|
|
f.Divider:SetTexture(texPath.."DividerVertical");
|
|
|
|
NarciAPI.NineSliceUtil.SetUp(f.BorderFrame, "settingsBorder", "backdrop");
|
|
NarciAPI.NineSliceUtil.SetUp(f.BackgroundFrame, "settingsBackground", "backdrop");
|
|
NarciAPI.AddPixelPerfectTexture(f.BorderFrame, f.Divider, 32);
|
|
|
|
local cateButtonHeight = 24;
|
|
local numCate = #Categories;
|
|
local bottomIndex = 0;
|
|
local p = 0; --numEffectiveCate
|
|
local frameHeight = Round0(f.ScrollFrame:GetHeight());
|
|
|
|
CategoryButtons = {};
|
|
CategoryOffsets = {};
|
|
CategoryTabs = {};
|
|
OptionButtons = {};
|
|
WidgetGroups = {};
|
|
|
|
local obj;
|
|
local height;
|
|
local totalScrollHeight = PADDING_H;
|
|
|
|
local cateHeight, totalCateHeight = 0, 0;
|
|
|
|
for i, cateData in ipairs(Categories) do
|
|
if (not cateData.validityCheckFunc) or (cateData.validityCheckFunc and cateData.validityCheckFunc()) then
|
|
p = p + 1;
|
|
obj = CreateFrame("Button", nil, f.CategoryFrame, "NarciSettingsCategoryButtonTemplate");
|
|
CategoryButtons[p] = obj;
|
|
CategoryOffsets[p] = totalScrollHeight - PADDING_H;
|
|
|
|
obj.id = p;
|
|
obj.level = cateData.level;
|
|
obj.key = cateData.key;
|
|
|
|
obj:SetScript("OnClick", CategoryButton_OnClick);
|
|
obj:SetScript("OnEnter", CategoryButton_OnEnter);
|
|
obj:SetScript("OnLeave", CategoryButton_OnLeave);
|
|
|
|
obj:SetWidth(DEFAULT_LEFT_WIDTH);
|
|
obj:SetHitRectInsets(0, 8, 0, 0);
|
|
obj.ButtonText:SetPoint("LEFT", obj, "LEFT", PADDING_H + CATE_LEVEL_OFFSET*cateData.level, 0);
|
|
|
|
SetTextColorByID(obj.ButtonText, 1);
|
|
|
|
CategoryTabs[p] = CreateFrame("Frame", nil, f.ScrollFrame.ScrollChild);
|
|
|
|
if cateData.isBottom then
|
|
bottomIndex = bottomIndex + 1;
|
|
obj:SetPoint("BOTTOMLEFT", f.CategoryFrame, "BOTTOMLEFT", 0, PADDING_V + (2 - bottomIndex) * cateButtonHeight);
|
|
if cateData.key == "about" then
|
|
--About Tab
|
|
else
|
|
--Credit List
|
|
totalScrollHeight = math.ceil(totalScrollHeight/frameHeight) * frameHeight;
|
|
totalScrollHeight = totalScrollHeight + WIDGET_GAP;
|
|
CategoryOffsets[p] = totalScrollHeight - PADDING_H;
|
|
|
|
height = CreditList:CreateList(CategoryTabs[p], f.ScrollFrame.ScrollChild, -totalScrollHeight);
|
|
totalScrollHeight = totalScrollHeight + height;
|
|
end
|
|
else
|
|
obj:SetPoint("TOPLEFT", f.CategoryFrame, "TOPLEFT", 0, -PADDING_V -totalCateHeight);
|
|
end
|
|
|
|
cateHeight = CategoryButton_SetLabel(obj, cateData.name);
|
|
totalCateHeight = totalCateHeight + cateHeight;
|
|
|
|
if cateData.widgets then
|
|
for j = 1, #cateData.widgets do
|
|
obj, height = CreateWidget(CategoryTabs[p], f.ScrollFrame.ScrollChild, PADDING_H, -totalScrollHeight, cateData.widgets[j]);
|
|
totalScrollHeight = totalScrollHeight + height;
|
|
if obj then
|
|
obj.categoryID = p;
|
|
end
|
|
end
|
|
end
|
|
|
|
if i == numCate then
|
|
--About List
|
|
AboutTab:CreateTab(CategoryTabs[p], f.ScrollFrame.ScrollChild, -totalScrollHeight);
|
|
end
|
|
|
|
totalScrollHeight = totalScrollHeight + CATE_OFFSET;
|
|
end
|
|
end
|
|
|
|
CREDIT_TAB_ID = p - 1;
|
|
|
|
--Close Button;
|
|
local CloseButton = CreateFrame("Button", nil, f.OverlayFrame);
|
|
f.CloseButton = CloseButton;
|
|
CloseButton:SetSize(36, 36);
|
|
CloseButton:SetPoint("TOPRIGHT", f, "TOPRIGHT", 0, 0);
|
|
|
|
CloseButton.Texture = CloseButton:CreateTexture(nil, "BACKGROUND");
|
|
CloseButton.Texture:SetSize(36, 36);
|
|
CloseButton.Texture:SetPoint("CENTER", CloseButton, "CENTER", 0, 0);
|
|
CloseButton.Texture:SetTexture(texPath.."CloseButton");
|
|
CloseButton.Texture:SetTexCoord(0, 0.375, 0, 0.75);
|
|
|
|
CloseButton.Cross = CloseButton:CreateTexture(nil, "OVERLAY");
|
|
CloseButton.Cross:SetSize(18, 18);
|
|
CloseButton.Cross:SetPoint("CENTER", CloseButton, "CENTER", 0, 0);
|
|
CloseButton.Cross:SetTexture(texPath.."CloseButton");
|
|
CloseButton.Cross:SetTexCoord(0.8125, 1, 0, 0.375);
|
|
|
|
CloseButton:SetScript("OnEnter", CloseButton_OnEnter);
|
|
CloseButton:SetScript("OnLeave", CloseButton_OnLeave);
|
|
CloseButton:SetScript("OnMouseDown", CloseButton_OnMouseDown);
|
|
CloseButton:SetScript("OnMouseUp", CloseButton_OnMouseUp);
|
|
CloseButton:SetScript("OnClick", CloseButton_OnClick);
|
|
CloseButton_OnLeave(CloseButton);
|
|
|
|
|
|
for _, button in pairs(OptionButtons) do
|
|
button:UpdateState();
|
|
end
|
|
|
|
local enableSwipe = true;
|
|
local useReachLimitAnimation = true;
|
|
NarciAPI.CreateSmoothScroll(f.ScrollFrame, enableSwipe, useReachLimitAnimation);
|
|
NUM_CATE = #CategoryOffsets;
|
|
local scrollRange = CategoryOffsets[ NUM_CATE ];
|
|
f.ScrollFrame:SetScrollRange(scrollRange);
|
|
f.ScrollFrame:SetStepSize(80);
|
|
f.ScrollFrame:SetSpeedMultiplier(0.2);
|
|
f.ScrollFrame:SetOnValueChangedFunc(FindCurrentCategory);
|
|
|
|
|
|
if not AlertMessageFrame then
|
|
AlertMessageFrame = CreateFrame("Frame", nil, f, "NarciSettingsAlertFrameTemplate");
|
|
end
|
|
AlertMessageFrame:Hide();
|
|
|
|
CategoryButtons[1]:Click();
|
|
|
|
--Pixel perfect?
|
|
local _, screenHeight = GetPhysicalScreenSize();
|
|
local scale = 768/screenHeight;
|
|
MainFrame:SetScale(scale / 0.75);
|
|
MainFrame:RegisterEvent("UI_SCALE_CHANGED");
|
|
|
|
wipe(Categories);
|
|
Categories = nil;
|
|
end
|
|
|
|
|
|
NarciSettingsFrameMixin = {};
|
|
|
|
function NarciSettingsFrameMixin:OnLoad()
|
|
MainFrame = self;
|
|
|
|
local panel = NarciInterfaceOptionsPanel;
|
|
panel:HookScript("OnShow", function(f)
|
|
if f:IsVisible() then
|
|
MainFrame:ShowUI("blizzard");
|
|
end
|
|
end);
|
|
panel:HookScript("OnHide", function(f)
|
|
MainFrame:CloseUI();
|
|
end);
|
|
|
|
if IS_DRAGONFLIGHT and SettingsPanel then
|
|
if false then
|
|
--don't create our tab on the SettingsPanel until the tain issue being resolved.
|
|
self.Background = self:CreateTexture(nil, "BACKGROUND", nil, -1);
|
|
self.Background:Hide();
|
|
return
|
|
end
|
|
|
|
self.Background = CreateFrame("Frame", nil, SettingsPanel);
|
|
self.Background:SetFrameStrata("LOW");
|
|
self.Background:SetFixedFrameStrata(true);
|
|
self.Background:SetPoint("TOPLEFT", self, "TOPLEFT", 0, 0);
|
|
self.Background:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", 0, 0);
|
|
local realTexture = self.Background:CreateTexture(nil, "BACKGROUND")
|
|
realTexture:SetPoint("TOPLEFT", self, "TOPLEFT", -58, 14); --30
|
|
realTexture:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", 32, -4); --8
|
|
realTexture:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\DispersiveBackground");
|
|
--realTexture:SetColorTexture(1, 0.05, 0.05, 0.8);
|
|
|
|
--local category = securecallfunction(Settings.RegisterCanvasLayoutCategory, panel, "Narcissus");
|
|
--securecallfunction(Settings.RegisterAddOnCategory, category);
|
|
local category = Settings.RegisterCanvasLayoutCategory(panel, "Narcissus");
|
|
Settings.RegisterAddOnCategory(category);
|
|
|
|
else
|
|
self.Background = self:CreateTexture(nil, "BACKGROUND", nil, -1);
|
|
self.Background:SetPoint("TOPLEFT", self, "TOPLEFT", 0, 0);
|
|
self.Background:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", 0, 0);
|
|
self.Background:SetColorTexture(0.05, 0.05, 0.05, 0.8);
|
|
|
|
--Create UI on Interface Options Panel (ESC-Interface)
|
|
panel.name = "Narcissus";
|
|
panel.Header:SetText("Narcissus");
|
|
InterfaceOptions_AddCategory(panel);
|
|
end
|
|
|
|
self.Background:Hide();
|
|
end
|
|
|
|
|
|
|
|
function NarciSettingsFrameMixin:ShowUI(mode, alignToCenter, navigateTo)
|
|
SetupFrame();
|
|
|
|
mode = mode or "default";
|
|
--if mode ~= self.mode then
|
|
self.mode = mode;
|
|
if mode == "blizzard" then
|
|
self:AnchorToInterfaceOptions();
|
|
else
|
|
self:AnchorToDefault(alignToCenter);
|
|
end
|
|
--end
|
|
|
|
CreditList:StopAnimation();
|
|
|
|
if mode == "blizzard" then
|
|
self.FlyIn:Stop();
|
|
self.Background:Show();
|
|
else
|
|
self.FlyIn:Play();
|
|
self:SetFrameStrata("DIALOG");
|
|
self.Background:Hide();
|
|
end
|
|
|
|
RENDER_RANGE = Round0(self.ScrollFrame:GetHeight() + 4 + CATE_OFFSET);
|
|
|
|
self:Show();
|
|
|
|
if navigateTo then
|
|
C_Timer.After(0, function()
|
|
self:NavigateToCategory(navigateTo);
|
|
end)
|
|
end
|
|
end
|
|
|
|
function NarciSettingsFrameMixin:CloseUI()
|
|
self:Hide();
|
|
end
|
|
|
|
function NarciSettingsFrameMixin:ToggleUI()
|
|
if self:IsShown() then
|
|
self:CloseUI();
|
|
else
|
|
self:ShowUI();
|
|
end
|
|
end
|
|
|
|
function NarciSettingsFrameMixin:OnHide()
|
|
self.FlyIn:Stop();
|
|
SliderUpdator:Stop();
|
|
SCROLL_LOCKED = false;
|
|
self:Hide();
|
|
self.Background:Hide();
|
|
end
|
|
|
|
function NarciSettingsFrameMixin:OnEvent(event, ...)
|
|
if event == "UI_SCALE_CHANGED" then
|
|
self.mode = nil; --to recalculate scale
|
|
end
|
|
end
|
|
|
|
function NarciSettingsFrameMixin:NavigateToCategory(categoryKey)
|
|
for i, b in ipairs(CategoryButtons) do
|
|
if b.key == categoryKey then
|
|
SetScrollByCategoryID(b.id, false);
|
|
return
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
local CollapsibleCategory = {
|
|
onUpdate = function(self, elapsed)
|
|
self.t = self.t + elapsed;
|
|
local w = inOutSine(self.t, self.fromW, self.toW, self.d);
|
|
if self.t >= self.d then
|
|
w = self.toW;
|
|
self:SetScript("OnUpdate", nil);
|
|
end
|
|
self.frame:SetWidth(w);
|
|
end
|
|
};
|
|
|
|
function CollapsibleCategory:Init()
|
|
if not self.f then
|
|
self.f = CreateFrame("Frame", nil, MainFrame);
|
|
self.f.frame = MainFrame.CategoryFrame;
|
|
end
|
|
self.f.fromW = self.f.frame:GetWidth();
|
|
self.f.t = 0;
|
|
self.f.d = 0.5;
|
|
end
|
|
|
|
function CollapsibleCategory:Collapse()
|
|
self:Init();
|
|
self.f.toW = self.collapsedWidth;
|
|
self.f:SetScript("OnUpdate", self.onUpdate);
|
|
end
|
|
|
|
function CollapsibleCategory:Expand()
|
|
self:Init();
|
|
self.f.toW = SHRIKNED_LEFT_WIDTH;
|
|
self.f:SetScript("OnUpdate", self.onUpdate);
|
|
end
|
|
|
|
function CollapsibleCategory:SetCollapsedWidth(width)
|
|
self.collapsedWidth = width;
|
|
end
|
|
|
|
|
|
|
|
local function MouseoverTracker_OnUpdate(self, elapsed)
|
|
self.t1 = self.t1 + elapsed;
|
|
if self.t1 > 0.1 then
|
|
self.t1 = 0;
|
|
else
|
|
return
|
|
end
|
|
|
|
if self.CategoryFrame:IsMouseOver() then
|
|
if not self.cursorInCategoryFrame then
|
|
self.cursorInCategoryFrame = true;
|
|
CollapsibleCategory:Expand();
|
|
end
|
|
else
|
|
if self.cursorInCategoryFrame then
|
|
self.cursorInCategoryFrame = nil;
|
|
CollapsibleCategory:Collapse();
|
|
end
|
|
end
|
|
end
|
|
|
|
function NarciSettingsFrameMixin:AnchorToInterfaceOptions()
|
|
local container = NarciInterfaceOptionsPanel;
|
|
if not container then return end;
|
|
|
|
self:ClearAllPoints();
|
|
self:SetParent(container);
|
|
|
|
local padding = 4;
|
|
self:SetPoint("TOPRIGHT", container, "TOPRIGHT", -padding, -padding);
|
|
|
|
local containerScale = container:GetEffectiveScale();
|
|
local containerHeight = container:GetHeight();
|
|
local containerWidth = container:GetWidth();
|
|
local scale = self:GetScale();
|
|
local effectiveSettingsFrameWidth = (MAX_SCROLLFRAME_WIDTH + SHRIKNED_LEFT_WIDTH) * scale;
|
|
local exceed = effectiveSettingsFrameWidth - containerWidth * containerScale;
|
|
|
|
if exceed > 0 then
|
|
local collapsedCateWidth = SHRIKNED_LEFT_WIDTH - exceed/containerScale;
|
|
if collapsedCateWidth < 36 then
|
|
collapsedCateWidth = 36;
|
|
end
|
|
CollapsibleCategory:SetCollapsedWidth(collapsedCateWidth);
|
|
self.CategoryFrame:SetWidth(collapsedCateWidth);
|
|
self.t1 = 0;
|
|
self:SetScript("OnUpdate", MouseoverTracker_OnUpdate);
|
|
else
|
|
self.CategoryFrame:SetWidth(SHRIKNED_LEFT_WIDTH);
|
|
self:SetScript("OnUpdate", nil);
|
|
end
|
|
|
|
|
|
self:SetSize( (containerWidth-2*padding) *containerScale/scale, (containerHeight - 2*padding) *containerScale/scale);
|
|
|
|
local scrollFrameWidth = self.ScrollFrame:GetWidth();
|
|
self.ScrollFrame.ScrollChild:SetWidth(scrollFrameWidth);
|
|
self.CloseButton:Hide();
|
|
self.BackgroundFrame:Hide();
|
|
self.BorderFrame:Hide();
|
|
|
|
if self.Background then
|
|
self.Background:Show();
|
|
end
|
|
|
|
UpdateAlignment();
|
|
end
|
|
|
|
function NarciSettingsFrameMixin:AnchorToDefault(alignToCenter)
|
|
self:ClearAllPoints();
|
|
self:SetParent(nil);
|
|
local x, y = Narci_VirtualLineCenter:GetCenter();
|
|
local scale = self:GetEffectiveScale();
|
|
if alignToCenter then
|
|
self:SetPoint("CENTER", UIParent, "CENTER", 0, 0);
|
|
else
|
|
self:SetPoint("CENTER", UIParent, "LEFT", x/scale, 0);
|
|
end
|
|
|
|
self:SetSize(DEFAULT_FRAME_WIDTH, DEFAULT_FRAME_HEIGHT);
|
|
self.CategoryFrame:SetWidth(DEFAULT_LEFT_WIDTH);
|
|
self.ScrollFrame.ScrollChild:SetWidth(DEFAULT_FRAME_WIDTH - DEFAULT_LEFT_WIDTH);
|
|
self.CloseButton:Show();
|
|
self.BackgroundFrame:Show();
|
|
self.BorderFrame:Show();
|
|
|
|
if self.Background then
|
|
self.Background:Hide();
|
|
end
|
|
|
|
UpdateAlignment();
|
|
end
|
|
|
|
|
|
---- Slider ----
|
|
function SliderUpdator:Stop()
|
|
self:SetScript("OnUpdate", nil);
|
|
self.cursorX = nil;
|
|
self.ratio = nil;
|
|
self.slider = nil;
|
|
self.left = nil;
|
|
self.t = nil;
|
|
self.delay = nil;
|
|
self.cursorScale = nil;
|
|
self.reciprocal = nil;
|
|
end
|
|
|
|
local function SliderUpdator_OnUpdate(self, elapsed)
|
|
self.t = self.t + elapsed;
|
|
if self.t > 0 then
|
|
self.t = self.delay;
|
|
else
|
|
return
|
|
end
|
|
|
|
local cursorX = GetCursorPosition();
|
|
cursorX = cursorX * self.cursorScale - self.cursorOffset;
|
|
if cursorX ~= self.cursorX then
|
|
self.cursorX = cursorX;
|
|
self.ratio = (self.cursorX - self.left) * self.reciprocal;
|
|
self.slider:SetValueByRatio(self.ratio, true);
|
|
end
|
|
end
|
|
|
|
|
|
function SliderUpdator:Start(slider)
|
|
self:SetScript("OnUpdate", nil);
|
|
self.left = slider:GetEffectiveLeft();
|
|
if not self.left then
|
|
return
|
|
end
|
|
self.width = slider:GetEffectiveWidth();
|
|
self.reciprocal = 1/self.width;
|
|
self.cursorX = GetCursorPosition();
|
|
self.t = 1;
|
|
self.slider = slider;
|
|
local scale = slider:GetEffectiveScale();
|
|
self.cursorScale = 1 / scale;
|
|
if slider.Thumb:IsMouseOver(0, 0, -2, 2) then
|
|
local centerX = slider.Thumb:GetCenter();
|
|
local cursorX = GetCursorPosition();
|
|
self.cursorOffset = cursorX/scale - centerX;
|
|
else
|
|
self.cursorOffset = 0;
|
|
end
|
|
if slider.obeyStep then
|
|
self.delay = -0.1;
|
|
else
|
|
self.delay = -0.016;
|
|
end
|
|
self:SetScript("OnUpdate", SliderUpdator_OnUpdate);
|
|
end
|
|
|
|
|
|
NarciSettingsFrameSliderMixin = {};
|
|
|
|
|
|
function NarciSettingsFrameSliderMixin:OnLoad()
|
|
self.BarTexture:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\Slider");
|
|
self.Thumb:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\Slider");
|
|
self.Selection:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\Slider");
|
|
self.Highlight:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\Slider");
|
|
self.BackgroundLeft:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\SliderBackground");
|
|
self.BackgroundCenter:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\SliderBackground");
|
|
self.BackgroundRight:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\SliderBackground");
|
|
|
|
self.valueOffsetRatio = 1;
|
|
self:SetSideOffset(4); --half of thumb size
|
|
self:SetMinMaxValues(0, 1);
|
|
self:SetValue(0);
|
|
|
|
|
|
SetTextureColorByID(self.Thumb, 2);
|
|
end
|
|
|
|
function NarciSettingsFrameSliderMixin:SetValue(value, userInput)
|
|
if self.maxVal and value > self.maxVal then
|
|
value = self.maxVal;
|
|
elseif self.minVal and value < self.minVal then
|
|
value = self.minVal;
|
|
end
|
|
|
|
self.value = value;
|
|
self.Thumb:SetPoint("CENTER", self.Bar, "LEFT", self.sideOffset + self.valueOffsetRatio * (value - self.minVal), 0);
|
|
|
|
if self.valueFormatFunc then
|
|
self.ValueText:SetText(self.valueFormatFunc(value));
|
|
else
|
|
self.ValueText:SetText(Round1(value));
|
|
end
|
|
|
|
if userInput and self.onValueChangedFunc then
|
|
if self.convertionFunc then
|
|
value = self.convertionFunc(value);
|
|
end
|
|
if value ~= self.lastValue then
|
|
self.lastValue = value;
|
|
if self.key then
|
|
DB[self.key] = value;
|
|
end
|
|
self.onValueChangedFunc(self, value);
|
|
end
|
|
end
|
|
end
|
|
|
|
function NarciSettingsFrameSliderMixin:SetValueByRatio(ratio, userInput)
|
|
if ratio < 0 then
|
|
self:SetValue(self.minVal, userInput);
|
|
elseif ratio > 1 then
|
|
self:SetValue(self.maxVal, userInput);
|
|
else
|
|
if self.obeyStep then
|
|
local rawValue = ratio * self.range;
|
|
local rawStep = math.floor(rawValue / self.valueStep);
|
|
local prev = rawStep * self.valueStep;
|
|
local next = prev + self.valueStep;
|
|
if rawValue > (next + prev) * 0.5 then
|
|
rawValue = next;
|
|
else
|
|
rawValue = prev;
|
|
end
|
|
self:SetValue(self.minVal + rawValue, userInput);
|
|
else
|
|
self:SetValue(self.minVal + ratio * self.range, userInput);
|
|
end
|
|
end
|
|
end
|
|
|
|
function NarciSettingsFrameSliderMixin:SetValueStep(valueStep)
|
|
self.valueStep = valueStep;
|
|
end
|
|
|
|
function NarciSettingsFrameSliderMixin:SetMinMaxValues(minVal, maxVal)
|
|
self.minVal = minVal;
|
|
self.maxVal = maxVal;
|
|
self.range = maxVal - minVal;
|
|
end
|
|
|
|
function NarciSettingsFrameSliderMixin:GetRange()
|
|
return self.range or 0
|
|
end
|
|
|
|
function NarciSettingsFrameSliderMixin:SetSideOffset(offset)
|
|
self.sideOffset = offset;
|
|
end
|
|
|
|
function NarciSettingsFrameSliderMixin:GetEffectiveLeft()
|
|
return self:GetLeft() + self.sideOffset;
|
|
end
|
|
|
|
function NarciSettingsFrameSliderMixin:GetEffectiveWidth()
|
|
return self:GetWidth() - 2 * self.sideOffset;
|
|
end
|
|
|
|
function NarciSettingsFrameSliderMixin:SetObeyStepOnDrag(state)
|
|
if not self.nodes then
|
|
self.nodes = {};
|
|
end
|
|
|
|
if state and self.valueStep and self.valueStep > 0 then
|
|
local numSteps = Round0( (self.maxVal - self.minVal) / self.valueStep + 1);
|
|
if numSteps < 2 then
|
|
self:SetObeyStepOnDrag(false);
|
|
return
|
|
end
|
|
|
|
self.obeyStep = true;
|
|
self.ratioStep = 0.5/numSteps;
|
|
|
|
for i = 1, numSteps do
|
|
if not self.nodes[i] then
|
|
self.nodes[i] = self:CreateTexture(nil, "ARTWORK");
|
|
self.nodes[i]:SetSize(24, 24);
|
|
self.nodes[i]:SetPoint("CENTER", self.Bar, "LEFT", 0, 0);
|
|
self.nodes[i]:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\Slider");
|
|
SetTextureColorByID(self.nodes[i], 1);
|
|
end
|
|
self.nodes[i]:SetTexCoord(0.125, 0.1875, 0, 0.5);
|
|
self.nodes[i]:Show();
|
|
end
|
|
|
|
for i = numSteps + 1, #self.nodes do
|
|
self.nodes[i]:Hide();
|
|
end
|
|
|
|
self.numSteps = numSteps;
|
|
--self.Bar:SetVertexColor(0.25, 0.25, 0.25);
|
|
SetTextureColorByID(self.BarTexture, 1);
|
|
else
|
|
self.obeyStep = nil;
|
|
self.numSteps = 2;
|
|
for i = 1, 2 do
|
|
if not self.nodes[i] then
|
|
self.nodes[i] = self:CreateTexture(nil, "ARTWORK");
|
|
self.nodes[i]:SetSize(24, 24);
|
|
self.nodes[i]:SetPoint("CENTER", self.Bar, "LEFT", 0, 0);
|
|
self.nodes[i]:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\Slider");
|
|
SetTextureColorByID(self.nodes[i], 1);
|
|
end
|
|
if i == 1 then
|
|
self.nodes[i]:SetTexCoord(0.25, 0.3125, 0, 0.5);
|
|
else
|
|
self.nodes[i]:SetTexCoord(0.3125, 0.375, 0, 0.5);
|
|
end
|
|
self.nodes[i]:Hide();
|
|
end
|
|
|
|
for i = 3, #self.nodes do
|
|
self.nodes[i]:Hide();
|
|
end
|
|
|
|
SetTextureColorByID(self.BarTexture, 1);
|
|
end
|
|
|
|
self:OnSizeChanged();
|
|
end
|
|
|
|
function NarciSettingsFrameSliderMixin:OnSizeChanged()
|
|
local width = self:GetWidth();
|
|
if width and self.numSteps then
|
|
if self.numSteps > 2 then
|
|
local effectiveWidth = width - self.sideOffset * 2;
|
|
local gap = effectiveWidth / (self.numSteps - 1);
|
|
for i = 1, self.numSteps do
|
|
self.nodes[i]:ClearAllPoints();
|
|
self.nodes[i]:SetPoint("CENTER", self.Bar, "LEFT", self.sideOffset + (i - 1) * gap, 0);
|
|
end
|
|
else
|
|
self.nodes[1]:ClearAllPoints();
|
|
self.nodes[1]:SetPoint("CENTER", self.Bar, "LEFT", self.sideOffset, 0);
|
|
self.nodes[2]:ClearAllPoints();
|
|
self.nodes[2]:SetPoint("CENTER", self.Bar, "RIGHT", -self.sideOffset, 0);
|
|
end
|
|
width = width - 4;
|
|
local pixelScale = 0.75;
|
|
local pixelWidth = width / pixelScale;
|
|
if pixelWidth > 512 then
|
|
pixelWidth = 512;
|
|
end
|
|
local coord = (pixelWidth / 512) * 0.5;
|
|
if self.obeyStep then
|
|
self.BarTexture:SetTexCoord(0.5 - coord, 0.5 + coord, 0.75, 1);
|
|
else
|
|
self.BarTexture:SetTexCoord(0.5 - coord, 0.5 + coord, 0.5, 0.75);
|
|
end
|
|
self.valueOffsetRatio = self:GetEffectiveWidth() / self:GetRange();
|
|
end
|
|
end
|
|
|
|
function NarciSettingsFrameSliderMixin:OnMouseDown()
|
|
SliderUpdator:Start(self);
|
|
self.isDragging = true;
|
|
end
|
|
|
|
function NarciSettingsFrameSliderMixin:OnMouseUp()
|
|
SliderUpdator:Stop();
|
|
self.isDragging = nil;
|
|
if not self:IsFocused() then
|
|
self:HighlightFrame(false);
|
|
end
|
|
end
|
|
|
|
function NarciSettingsFrameSliderMixin:IsFocused()
|
|
return (self:IsVisible() and self:IsMouseOver(0, 0, -12, 12))
|
|
end
|
|
|
|
function NarciSettingsFrameSliderMixin:SetSliderWidth(width, adjustOffsetByLabelWidth)
|
|
self:SetWidth(width);
|
|
if adjustOffsetByLabelWidth then
|
|
local labelWidth = self:GetParent().Label:GetWrappedWidth();
|
|
if labelWidth then
|
|
self:SetPoint("LEFT", self:GetParent(), "LEFT", labelWidth + 64, 0);
|
|
end
|
|
end
|
|
--local offsetX = 120 - 192 + width + 16;
|
|
--self:SetPoint("LEFT", self:GetParent(), "LEFT", offsetX, 0);
|
|
self:OnSizeChanged();
|
|
end
|
|
|
|
function NarciSettingsFrameSliderMixin:OnEnter()
|
|
self:HighlightFrame(true);
|
|
end
|
|
|
|
function NarciSettingsFrameSliderMixin:OnLeave()
|
|
if not self.isDragging then
|
|
self:HighlightFrame(false);
|
|
end
|
|
end
|
|
|
|
function NarciSettingsFrameSliderMixin:HighlightFrame(state)
|
|
if state then
|
|
SetTextColorByID(self:GetParent().Label, 3);
|
|
SetTextColorByID(self.ValueText, 3);
|
|
SetTextureColorByID(self.BarTexture, 2);
|
|
self.Highlight:Show();
|
|
else
|
|
SetTextColorByID(self:GetParent().Label, 2);
|
|
SetTextColorByID(self.ValueText, 2);
|
|
SetTextureColorByID(self.BarTexture, 1);
|
|
self.Highlight:Hide();
|
|
end
|
|
end
|
|
|
|
function NarciSettingsFrameSliderMixin:UpdateState()
|
|
if self.key and DB[self.key] then
|
|
if self.convertionFunc then
|
|
self:SetValue( self.convertionFunc(DB[self.key]) );
|
|
else
|
|
self:SetValue(DB[self.key]);
|
|
end
|
|
elseif self.getValueFunc then
|
|
self:SetValue( self.getValueFunc() );
|
|
else
|
|
if self.minVal then
|
|
self:SetValue(self.minVal);
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
---- Keybindings ----
|
|
|
|
local function KeybingdingButton_OnEvent(self, event, ...)
|
|
if event == "GLOBAL_MOUSE_DOWN" then
|
|
if not self:IsFocused() then
|
|
self:StopListening();
|
|
end
|
|
end
|
|
end
|
|
|
|
NarciSettingsKeybindingButton = {};
|
|
|
|
function NarciSettingsKeybindingButton:OnLoad()
|
|
self.Left:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\Keybinding");
|
|
self.Center:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\Keybinding");
|
|
self.Right:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\Keybinding");
|
|
|
|
self.BGLeft:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\KeybindingBackground");
|
|
self.BGCenter:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\KeybindingBackground");
|
|
self.BGRight:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\KeybindingBackground");
|
|
|
|
self.TextBackground:SetColorTexture(0.92, 0.92, 0.92);
|
|
self:OnLeave();
|
|
end
|
|
|
|
function NarciSettingsKeybindingButton:OnEnter()
|
|
self:HighlightFrame(true);
|
|
SetTextColorByID(self.Label, 3);
|
|
end
|
|
|
|
function NarciSettingsKeybindingButton:OnLeave()
|
|
if not self.active then
|
|
self:HighlightFrame(false);
|
|
end
|
|
SetTextColorByID(self.Label, 1);
|
|
end
|
|
|
|
function NarciSettingsKeybindingButton:UpdateState()
|
|
local key;
|
|
if self.actionName then
|
|
key = GetBindingKey(self.actionName);
|
|
end
|
|
if key then
|
|
self:SetText(key);
|
|
SetTextColorByID(self.ButtonText, 3);
|
|
else
|
|
self:SetText(NOT_BOUND);
|
|
SetTextColorByID(self.ButtonText, 1);
|
|
end
|
|
end
|
|
|
|
function NarciSettingsKeybindingButton:SetExternalAction(actionName)
|
|
--Processesd by WoWUI, globally
|
|
self.actionName = actionName;
|
|
end
|
|
|
|
function NarciSettingsKeybindingButton:SetInternalAction(actionName)
|
|
--Used and processed by Narcissus
|
|
self.actionName = actionName;
|
|
end
|
|
|
|
function NarciSettingsKeybindingButton:HighlightFrame(state)
|
|
if state then
|
|
SetTextureColorByID(self.Left, 2);
|
|
SetTextureColorByID(self.Center, 2);
|
|
SetTextureColorByID(self.Right, 2);
|
|
else
|
|
SetTextureColorByID(self.Left, 1);
|
|
SetTextureColorByID(self.Center, 1);
|
|
SetTextureColorByID(self.Right, 1);
|
|
end
|
|
end
|
|
|
|
function NarciSettingsKeybindingButton:OnClick(mouseButton)
|
|
if mouseButton == "RightButton" then
|
|
self:ClearBinding();
|
|
else
|
|
if self.active then
|
|
self:StopListening();
|
|
else
|
|
self:StartListening();
|
|
end
|
|
end
|
|
end
|
|
|
|
local RESERVED_KEYS = {
|
|
ESCAPE = true,
|
|
BACKSPACE = true,
|
|
SPACE = true,
|
|
ENTER = true,
|
|
TAB = true,
|
|
};
|
|
|
|
local function ClearBindingKey(actionName)
|
|
local key1, key2 = GetBindingKey(actionName);
|
|
if key1 then
|
|
SetBinding(key1, nil, 1);
|
|
end
|
|
if key2 then
|
|
SetBinding(key2, nil, 1);
|
|
end
|
|
SaveBindings(1);
|
|
end
|
|
|
|
local function ExternalAction_OnKeydown(self, key)
|
|
if key == "ESCAPE" then
|
|
self:StopListening();
|
|
return
|
|
end
|
|
|
|
if RESERVED_KEYS[key] then
|
|
self:ExitAndShowInvalidKey(key);
|
|
return
|
|
end
|
|
|
|
local keyString = CreateKeyChordStringUsingMetaKeyState(key);
|
|
self.newKey = keyString;
|
|
--self.ButtonText:SetText(keyString);
|
|
self:AnimateSetText(keyString);
|
|
|
|
if not IsKeyPressIgnoredForBinding(key) then
|
|
self:AttemptToBind();
|
|
end
|
|
end
|
|
|
|
local function ExternalAction_OnKeyUp(self, key)
|
|
self:AttemptToBind();
|
|
end
|
|
|
|
|
|
function NarciSettingsKeybindingButton:StartListening()
|
|
self.active = true;
|
|
|
|
self.ButtonText:SetTextColor(0, 0, 0);
|
|
self.ButtonText:SetShadowColor(1, 1, 1);
|
|
self.ButtonText:SetShadowOffset(0, 0);
|
|
self.ButtonText.AnimInput:Stop();
|
|
|
|
self.TextBackground.AnimFadeOut:Stop();
|
|
self.TextBackground:SetColorTexture(0.92, 0.92, 0.92);
|
|
self.TextBackground:Show();
|
|
|
|
self:SetScript("OnEvent", KeybingdingButton_OnEvent);
|
|
self:RegisterEvent("GLOBAL_MOUSE_DOWN");
|
|
|
|
SCROLL_LOCKED = true;
|
|
MainFrame.ScrollFrame:LockScroll(true);
|
|
MainFrame.ScrollFrame:ScrollToWidget(self, 24);
|
|
|
|
self:SetScript("OnKeyDown", ExternalAction_OnKeydown);
|
|
self:SetScript("OnKeyUp", ExternalAction_OnKeyUp);
|
|
self:SetPropagateKeyboardInput(false);
|
|
if GAMEPAD_ENABLED then
|
|
|
|
end
|
|
end
|
|
|
|
function NarciSettingsKeybindingButton:StopListening()
|
|
self.active = nil;
|
|
self:SetScript("OnKeyDown", nil);
|
|
self:SetScript("OnKeyUp", nil);
|
|
if GAMEPAD_ENABLED then
|
|
self:SetScript("OnGamePadButtonDown", nil);
|
|
self:SetScript("OnGamePadButtonUp", nil);
|
|
end
|
|
|
|
self:UnregisterEvent("GLOBAL_MOUSE_DOWN");
|
|
|
|
if not self:IsFocused() then
|
|
self:HighlightFrame(false);
|
|
end
|
|
|
|
if not self.TextBackground.AnimFadeOut:IsPlaying() then
|
|
self.TextBackground:Hide();
|
|
end
|
|
|
|
self.ButtonText:SetShadowColor(0, 0, 0);
|
|
self.ButtonText:SetShadowOffset(1, -1);
|
|
self:UpdateState();
|
|
|
|
SCROLL_LOCKED = false;
|
|
MainFrame.ScrollFrame:LockScroll(false);
|
|
|
|
AlertMessageFrame:Hide();
|
|
end
|
|
|
|
function NarciSettingsKeybindingButton:AnimateSetText(text)
|
|
self.ButtonText.AnimInput:Stop();
|
|
local width1 = self.ButtonText:GetWrappedWidth();
|
|
self.ButtonText:SetText(text);
|
|
local width2 = self.ButtonText:GetWrappedWidth();
|
|
local diff = 0.5*(width2 - width1);
|
|
if diff > 10 or diff <-10 then
|
|
diff = 0;
|
|
end
|
|
self.ButtonText.AnimInput.X1:SetOffset(diff, 0);
|
|
self.ButtonText.AnimInput.X2:SetOffset(-diff, 0);
|
|
self.ButtonText.AnimInput:Play();
|
|
end
|
|
|
|
function NarciSettingsKeybindingButton:ClearBinding()
|
|
ClearBindingKey(self.actionName);
|
|
self:StopListening();
|
|
end
|
|
|
|
function NarciSettingsKeybindingButton:OnHide()
|
|
if self.active then
|
|
self:StopListening();
|
|
end
|
|
end
|
|
|
|
function NarciSettingsKeybindingButton:IsFocused()
|
|
return (self:IsMouseOver() and self:IsVisible()) or (AlertMessageFrame:IsVisible() and AlertMessageFrame:IsMouseOver());
|
|
end
|
|
|
|
function NarciSettingsKeybindingButton:ExitAndShowInvalidKey(key)
|
|
self:StopListening();
|
|
AlertMessageFrame:ShowInvalidKey(self, key);
|
|
end
|
|
|
|
function NarciSettingsKeybindingButton:AttemptToBind(override)
|
|
self:SetScript("OnKeyDown", nil);
|
|
self:SetScript("OnKeyUp", nil);
|
|
if GAMEPAD_ENABLED then
|
|
self:SetScript("OnGamePadButtonDown", nil);
|
|
self:SetScript("OnGamePadButtonUp", nil);
|
|
end
|
|
|
|
if not self.newKey then
|
|
self:StopListening();
|
|
return
|
|
end
|
|
|
|
if IsKeyPressIgnoredForBinding(self.newKey) then
|
|
self:ExitAndShowInvalidKey(self.newKey);
|
|
return
|
|
end
|
|
|
|
local action = GetBindingAction(self.newKey);
|
|
if (action and action ~= "" and action ~= self.actionName) and not override then
|
|
AlertMessageFrame:ShowOverwriteConfirmation(self, action);
|
|
return
|
|
else
|
|
ClearBindingKey(self.actionName);
|
|
if SetBinding(self.newKey, self.actionName, 1) then
|
|
--Successful
|
|
self.TextBackground.AnimFadeOut:Stop();
|
|
self.TextBackground:SetColorTexture(0.35, 0.61, 0.38); --green
|
|
self.TextBackground.AnimFadeOut:Play();
|
|
self:StopListening();
|
|
SaveBindings(1); --account wide
|
|
return true
|
|
else
|
|
self:StopListening();
|
|
return
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
local ClipboardUtil = {};
|
|
ClipboardUtil.scripts = {};
|
|
|
|
function ClipboardUtil:CreateClipboard()
|
|
Clipboard = CreateFrame("EditBox", nil, MainFrame);
|
|
Clipboard:SetFontObject("NarciFontMedium13");
|
|
Clipboard:SetShadowOffset(0, 0);
|
|
Clipboard:SetTextInsets(6, 6, 0, 0);
|
|
Clipboard:SetAutoFocus(false);
|
|
Clipboard:SetHighlightColor(0, 0.35, 0.75);
|
|
Clipboard:SetJustifyH("CENTER");
|
|
Clipboard:SetPropagateKeyboardInput(false);
|
|
for name, method in pairs(self.scripts) do
|
|
Clipboard:SetScript(name, method);
|
|
end
|
|
SetTextColorByID(Clipboard, 3);
|
|
end
|
|
|
|
function ClipboardUtil:SetupFromWebsiteButton(websiteButton)
|
|
if not Clipboard then
|
|
self:CreateClipboard();
|
|
end
|
|
|
|
Clipboard:ClearAllPoints();
|
|
Clipboard:SetParent(websiteButton);
|
|
Clipboard:SetPoint("TOPLEFT", websiteButton, "TOPLEFT", 0, 0);
|
|
Clipboard:SetPoint("BOTTOMRIGHT", websiteButton, "BOTTOMRIGHT", 0, 0);
|
|
Clipboard:Show();
|
|
Clipboard:SetText(websiteButton.link);
|
|
Clipboard:SetCursorPosition(0);
|
|
Clipboard:SetFocus();
|
|
end
|
|
|
|
function ClipboardUtil.scripts.OnKeyDown(self, key)
|
|
local keys = CreateKeyChordStringUsingMetaKeyState(key);
|
|
if keys == "CTRL-C" or key == "COMMAND-C" then
|
|
AboutTab.projectHeader.animSuccess:Play();
|
|
AboutTab.projectHeader:SetText(L["Copied"]);
|
|
self:Hide();
|
|
end
|
|
end
|
|
|
|
function ClipboardUtil.scripts.OnEditFocusLost(self)
|
|
if self:IsShown() then
|
|
self:HighlightText(0, 0);
|
|
if IsMouseButtonDown() then
|
|
for _, button in ipairs(AboutTab.websiteButtons) do
|
|
if button:IsMouseOver() then
|
|
return
|
|
end
|
|
end
|
|
end
|
|
self:Hide();
|
|
end
|
|
end
|
|
|
|
function ClipboardUtil.scripts.OnEditFocusGained(self)
|
|
self:HighlightText();
|
|
end
|
|
|
|
function ClipboardUtil.scripts.OnHide(f)
|
|
AboutTab:UpdateWebsiteButtons();
|
|
f:Hide();
|
|
end
|
|
|
|
function ClipboardUtil.scripts.OnEscapePressed(self)
|
|
self:Hide();
|
|
end
|
|
|
|
function ClipboardUtil.scripts.OnEnterPressed(self)
|
|
self:Hide();
|
|
end
|
|
|
|
function ClipboardUtil.scripts.OnTextChanged(self, userInput)
|
|
if userInput then
|
|
self:Hide();
|
|
end
|
|
end
|
|
|
|
function ClipboardUtil.scripts.OnCursorChanged(self)
|
|
self:HighlightText();
|
|
end
|
|
|
|
|
|
|
|
NarciSettingsClipboardButtonMixin = {};
|
|
|
|
function NarciSettingsClipboardButtonMixin:OnLoad()
|
|
self.Left:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\EditBox");
|
|
self.Center:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\EditBox");
|
|
self.Right:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SettingsFrame\\EditBox");
|
|
|
|
self:HighlightFrame(false);
|
|
end
|
|
|
|
function NarciSettingsClipboardButtonMixin:OnClick()
|
|
if self.isActive then
|
|
self.isActive = nil;
|
|
AboutTab:UpdateWebsiteButtons();
|
|
else
|
|
self:PlaceClipboard();
|
|
end
|
|
end
|
|
|
|
function NarciSettingsClipboardButtonMixin:OnEnter()
|
|
self:HighlightFrame(true);
|
|
end
|
|
|
|
function NarciSettingsClipboardButtonMixin:OnLeave()
|
|
self:HighlightFrame(false);
|
|
end
|
|
|
|
function NarciSettingsClipboardButtonMixin:HighlightFrame(state)
|
|
if self.isActive then return end;
|
|
|
|
if state then
|
|
SetTextureColorByID(self.Left, 2);
|
|
SetTextureColorByID(self.Center, 2);
|
|
SetTextureColorByID(self.Right, 2);
|
|
SetTextureColorByID(self.Logo, 3);
|
|
SetTextColorByID(self.ButtonText, 3);
|
|
else
|
|
SetTextureColorByID(self.Left, 1);
|
|
SetTextureColorByID(self.Center, 1);
|
|
SetTextureColorByID(self.Right, 1);
|
|
SetTextureColorByID(self.Logo, 2);
|
|
SetTextColorByID(self.ButtonText, 2);
|
|
end
|
|
end
|
|
|
|
function NarciSettingsClipboardButtonMixin:OnMouseDown()
|
|
self.ButtonText:SetPoint("CENTER", self, "CENTER", 16, -0.8);
|
|
if self.logoMode then
|
|
self.Logo:SetPoint("CENTER", self, "CENTER", 0, -0.8);
|
|
end
|
|
end
|
|
|
|
function NarciSettingsClipboardButtonMixin:OnMouseUp()
|
|
self.ButtonText:SetPoint("CENTER", self, "CENTER", 16, 0);
|
|
if self.logoMode then
|
|
self.Logo:SetPoint("CENTER", self, "CENTER", 0, 0);
|
|
end
|
|
|
|
if Clipboard and Clipboard:IsShown() then
|
|
Clipboard:SetFocus();
|
|
end
|
|
end
|
|
|
|
function NarciSettingsClipboardButtonMixin:SetLogoOnlyMode(state)
|
|
self.Logo:ClearAllPoints();
|
|
if state then
|
|
self.ButtonText:Hide();
|
|
self.Logo:SetPoint("CENTER", self, "CENTER", 0, 0);
|
|
else
|
|
self.ButtonText:Show();
|
|
self.Logo:SetPoint("RIGHT", self.ButtonText, "LEFT", -4, 0);
|
|
end
|
|
self.Logo:Show();
|
|
self.logoMode = state;
|
|
end
|
|
|
|
function NarciSettingsClipboardButtonMixin:PlaceClipboard()
|
|
AboutTab:UpdateWebsiteButtons(self.id);
|
|
|
|
self.Logo:Hide();
|
|
self.ButtonText:Hide();
|
|
self.Left:SetVertexColor(0, 0.5, 0.83);
|
|
self.Center:SetVertexColor(0, 0.5, 0.83);
|
|
self.Right:SetVertexColor(0, 0.5, 0.83);
|
|
self.isActive = true;
|
|
|
|
ClipboardUtil:SetupFromWebsiteButton(self);
|
|
end
|
|
|
|
|
|
NarciSettingsAlertMessageFrameMixin = {};
|
|
|
|
function NarciSettingsAlertMessageFrameMixin:ShowInvalidKey(keybindingButton, key)
|
|
self:AnchorToButton(keybindingButton);
|
|
self.YesButton:Hide();
|
|
self.NoButton:Hide();
|
|
SetTextColorByID(self.Message, 3);
|
|
self.Stroke:SetColorTexture(0.75, 0.06, 0);
|
|
self.Background:SetColorTexture(0.35, 0.11, 0.11);
|
|
self:SetAlertMessage(key.." is invalid");
|
|
self:StopAnimating();
|
|
self.AnimFadeIn:Play();
|
|
self:Show();
|
|
end
|
|
|
|
function NarciSettingsAlertMessageFrameMixin:ShowOverwriteConfirmation(keybindingButton, conflictedAction)
|
|
self:AnchorToButton(keybindingButton);
|
|
local actionName = GetBindingName(conflictedAction);
|
|
SetTextColorByID(self.Message, 3);
|
|
self.Stroke:SetColorTexture(0.4, 0.4, 0.4);
|
|
self.Background:SetColorTexture(0.08, 0.08, 0.08);
|
|
self.YesButton:Show();
|
|
self.NoButton:Show();
|
|
self.NoButton.Countdown:SetCooldown(GetTime(), 8);
|
|
self:SetAlertMessage("Override "..actionName.." ?");
|
|
self:StopAnimating();
|
|
self.AnimShake:Play();
|
|
self:Show();
|
|
|
|
self.parentButton = keybindingButton;
|
|
keybindingButton.TextBackground:SetColorTexture(1, 0.82, 0);
|
|
end
|
|
|
|
function NarciSettingsAlertMessageFrameMixin:ShowRequiresReload()
|
|
self:StopAnimating();
|
|
self.YesButton:Hide();
|
|
self.NoButton:Hide();
|
|
self:ClearAllPoints();
|
|
self:SetParent(MainFrame.ScrollFrame);
|
|
self:SetPoint("TOP", MainFrame.ScrollFrame, "TOP", 0, -8);
|
|
self:SetAlertMessage(REQUIRES_RELOAD or "Requires Reload");
|
|
self.Message:SetTextColor(1, 0.93, 0);
|
|
self.Stroke:SetColorTexture(0.4, 0.4, 0.4);
|
|
self.Background:SetColorTexture(0.08, 0.08, 0.08);
|
|
self.AnimFadeIn:Play();
|
|
self:Show();
|
|
end
|
|
|
|
function NarciSettingsAlertMessageFrameMixin:AnchorToButton(keybindingButton)
|
|
self:ClearAllPoints()
|
|
--self:SetPoint("BOTTOM", keybindingButton, "TOP", 0, 4);
|
|
self:SetPoint("TOP", keybindingButton, "BOTTOM", 0, -8);
|
|
self:SetParent(keybindingButton);
|
|
end
|
|
|
|
function NarciSettingsAlertMessageFrameMixin:SetAlertMessage(msg)
|
|
self.Message:SetText(msg);
|
|
local width = self.Message:GetWrappedWidth();
|
|
local height = self.Message:GetHeight();
|
|
|
|
if self.YesButton:IsShown() then
|
|
self:SetSize(Round0(width + 32), Round0(height + 16 + 32 + 2));
|
|
else
|
|
self:SetSize(Round0(width + 20), Round0(height + 20));
|
|
end
|
|
|
|
--Update alignment
|
|
if self:GetBottom() < MainFrame.ScrollFrame:GetBottom() then
|
|
self:ClearAllPoints();
|
|
self:SetPoint("BOTTOM", self:GetParent(), "TOP", 0, 8);
|
|
end
|
|
end
|
|
|
|
function NarciSettingsAlertMessageFrameMixin:OnHide()
|
|
self:Hide();
|
|
self.NoButton.Countdown:Clear();
|
|
end
|
|
|
|
local function AlertFrameButton_OnEnter(self)
|
|
self.Texture:SetVertexColor(1, 1, 1);
|
|
if self.Countdown then
|
|
self.Countdown:Pause();
|
|
end
|
|
end
|
|
|
|
local function AlertFrameButton_OnLeave(self)
|
|
self.Texture:SetVertexColor(0.67, 0.67, 0.67);
|
|
if self.Countdown then
|
|
self.Countdown:Resume();
|
|
end
|
|
end
|
|
|
|
local function AlertFrameButton_OnMouseDown(self)
|
|
self.Texture:SetScale(0.8);
|
|
end
|
|
|
|
local function AlertFrameButton_OnMouseUp(self)
|
|
self.Texture:SetScale(1);
|
|
end
|
|
|
|
local function AlertFrameButton_Yes_OnClick(self)
|
|
self:GetParent():Hide();
|
|
self:GetParent().parentButton:AttemptToBind(true);
|
|
end
|
|
|
|
local function Countdown_OnFinished()
|
|
AlertMessageFrame:Hide();
|
|
local keybindingButton = AlertMessageFrame:GetParent();
|
|
if keybindingButton and keybindingButton.StopListening then
|
|
keybindingButton:StopListening();
|
|
end
|
|
end
|
|
|
|
local function AlertFrameButton_No_OnClick(self)
|
|
Countdown_OnFinished();
|
|
end
|
|
|
|
function NarciSettingsAlertMessageFrameMixin:OnLoad()
|
|
AlertMessageFrame = self;
|
|
|
|
self.YesButton:SetScript("OnEnter", AlertFrameButton_OnEnter);
|
|
self.YesButton:SetScript("OnLeave", AlertFrameButton_OnLeave);
|
|
self.YesButton:SetScript("OnMouseDown", AlertFrameButton_OnMouseDown);
|
|
self.YesButton:SetScript("OnMouseUp", AlertFrameButton_OnMouseUp);
|
|
self.YesButton:SetScript("OnClick", AlertFrameButton_Yes_OnClick);
|
|
|
|
self.NoButton:SetScript("OnEnter", AlertFrameButton_OnEnter);
|
|
self.NoButton:SetScript("OnLeave", AlertFrameButton_OnLeave);
|
|
self.NoButton:SetScript("OnMouseDown", AlertFrameButton_OnMouseDown);
|
|
self.NoButton:SetScript("OnMouseUp", AlertFrameButton_OnMouseUp);
|
|
self.NoButton:SetScript("OnClick", AlertFrameButton_No_OnClick);
|
|
self.NoButton.Countdown:SetScript("OnCooldownDone", Countdown_OnFinished);
|
|
|
|
self.Stroke:SetColorTexture(0.4, 0.4, 0.4);
|
|
self.Exclusion:SetTexture("Interface\\AddOns\\Narcissus\\Art\\Masks\\Exclusion", "CLAMPTOWHITE", "CLAMPTOWHITE", "LINEAR");
|
|
end
|
|
|
|
function NarciSettingsAlertMessageFrameMixin:OnShow()
|
|
local a = NarciAPI.GetPixelForWidget(self, 2);
|
|
self.Exclusion:ClearAllPoints();
|
|
self.Exclusion:SetPoint("TOPLEFT", self, "TOPLEFT", a, -a);
|
|
self.Exclusion:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", -a, a);
|
|
end
|
|
|
|
|
|
local function GetSettingsButtonByDBKey(dbKey)
|
|
for id, button in ipairs(OptionButtons) do
|
|
if button.key == dbKey then
|
|
return button
|
|
end
|
|
end
|
|
end
|
|
|
|
NarciAPI.GetSettingsButtonByDBKey = GetSettingsButtonByDBKey;
|
|
|
|
|
|
|
|
|
|
function Narci_PreferenceButton_OnClick(self)
|
|
MainFrame:ToggleUI();
|
|
end
|