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.

1991 lines
58 KiB

local _, addon = ...
local SetGradient = addon.TransitionAPI.SetGradient;
local FadeFrame = NarciFadeUI.Fade;
local After = C_Timer.After;
local pi = math.pi;
local sqrt = math.sqrt;
local GetCursorPosition = GetCursorPosition;
local IsMouseButtonDown = IsMouseButtonDown;
local NarciAPI = NarciAPI;
local function EmptyFunc()
end
--TEMPS prefix: Deleted Later
local TEMPS = {};
local controllers = {};
local function AddControllerToWidget(widget)
if not widget.controller then
local controller = CreateFrame("Frame", nil, widget);
controller:Hide();
controller.t = 0;
controller:SetScript("OnHide", function(self)
self.t = 0;
--print("Hide Controller");
end);
widget.controller = controller;
tinsert(controllers, controller);
end
return widget.controller
end
--------------------------------------------------------------------------------------------------
--Name: Shimmer Button
--Type: Button
--Description: Shimmers slowly. Maintains highlight when moused-over
--Notes: starting Alpha is always "0"
TEMPS.totalDuration = 0;
local shimmerStyle = {
{toAlpha = 0.5, duration = 0.4}, --#1
{toAlpha = 0.5, duration = 0.25}, --#2
{toAlpha = 0, duration = 1.5}, --#3
{toAlpha = 0, duration = 0.35}, --#4
};
--time accumulation
local timeAlpha = {
--{totalDuration, toAlpha};
};
local TIER_SHIMMER = #shimmerStyle;
for i = 1, #shimmerStyle do
local cuurentT = TEMPS.totalDuration;
local duration = shimmerStyle[i].duration;
local nextT = cuurentT + duration;
TEMPS.totalDuration = nextT;
local fromAlpha;
if i > 1 then
fromAlpha = shimmerStyle[i - 1].toAlpha;
if fromAlpha < 0 then
fromAlpha = 0;
end
else
fromAlpha = 0;
end
local toAlpha = shimmerStyle[i].toAlpha;
if toAlpha < 0 then
toAlpha = 0;
end
local deltaAlpha = (toAlpha - fromAlpha)/duration
timeAlpha[i] = {cuurentT, nextT, fromAlpha, deltaAlpha};
end
shimmerStyle = nil;
local function UpdateObjectAlphaByTime(object, t)
local data;
local tR, fromAlpha, deltaAlpha;
for i = 1, TIER_SHIMMER do
data = timeAlpha[i];
if t >= data[1] and t <= data[2] then
fromAlpha, deltaAlpha = data[3], data[4];
tR = t - data[1];
break;
end
end
if tR then
object:SetAlpha(fromAlpha + deltaAlpha*tR);
return true
else
object:SetAlpha(0);
return false
end
end
NarciUIShimmerButtonMixin = {};
function NarciUIShimmerButtonMixin:Preload()
local controller = AddControllerToWidget(self);
controller:SetScript("OnUpdate", function(controller, elapsed)
if controller.isHolding then
local toAlpha = controller.toAlpha or 0;
local alpha;
if toAlpha == 0 then
alpha = self.Shimmer:GetAlpha() - 1 * elapsed;
else
alpha = self.Shimmer:GetAlpha() + 5 * elapsed;
end
if alpha >= 0.8 then
self.Shimmer:SetAlpha(0.8);
controller:Hide();
elseif alpha <= 0 then
self.Shimmer:SetAlpha(0);
if controller.pendingReset then
controller.pendingReset = nil;
controller.isHolding = nil;
end
else
self.Shimmer:SetAlpha(alpha);
end
else
local t = controller.t + elapsed;
if not UpdateObjectAlphaByTime(self.Shimmer, t) then
t = 0;
end
controller.t = t;
end
end);
self.Shimmer:SetAlpha(0);
self.Shimmer:Hide();
self.Preload = nil;
end
function NarciUIShimmerButtonMixin:PlayShimmer()
self.Shimmer:Show();
if self.controller.isHolding then
self.controller.toAlpha = 0;
self.controller.pendingReset = true;
end
self.controller:Show();
end
function NarciUIShimmerButtonMixin:StopShimmer()
self.Shimmer:Hide();
self.controller:Hide();
self.controller.toAlpha = 0;
self.controller.isHolding = true;
end
function NarciUIShimmerButtonMixin:HoldShimmer()
self.controller.toAlpha = 0.8;
self.controller.isHolding = true;
self.Shimmer:Show();
self.controller:Show();
end
--------------------------------------------------------------------------------------------------
--Type: Color Picker (HSV)
local ColorPicker;
local RGBRatio2HSV = NarciAPI.RGBRatio2HSV;
local HSV2RGB = NarciAPI.HSV2RGB;
NarciColorPickerSliderMixin = {};
function NarciColorPickerSliderMixin:SetBorderOffset(x)
self.Left:SetPoint("LEFT", self, "LEFT", x, 0);
self.Right:SetPoint("RIGHT", self, "RIGHT", -x, 0);
end
function NarciColorPickerSliderMixin:SetButtonSize(w, h)
self.Left:SetSize(h, h);
self.Right:SetSize(h, h);
self.Center:SetHeight(h);
self:SetSize(w, h);
end
function NarciColorPickerSliderMixin:SetHighlight(state)
local v;
if state then
v = 1;
else
v = 0.66;
end
for i = 1, #self.borderTextures do
self.borderTextures[i]:SetVertexColor(v, v, v);
end
end
function NarciColorPickerSliderMixin:OnEnter()
if not IsMouseButtonDown() then
self:SetHighlight(true);
end
end
function NarciColorPickerSliderMixin:OnLeave()
if not IsMouseButtonDown() then
self:SetHighlight(false);
end
end
function NarciColorPickerSliderMixin:OnMouseUp()
if not self:IsMouseOver() then
self:SetHighlight(false);
end
end
function NarciColorPickerSliderMixin:OnLoad()
local tex = "Interface\\AddOns\\Narcissus\\Art\\Widgets\\ColorPicker\\UI.tga";
self.borderTextures = {
self.Left, self.Center, self.Right, self.ThumbTexture
};
for i = 1, #self.borderTextures do
self.borderTextures[i]:SetTexture(tex);
end
self.Marker:SetTexture(tex);
self.Left:SetTexCoord(0, 0.125, 0, 0.125);
self.Center:SetTexCoord(0.125, 0.875, 0, 0.125);
self.Right:SetTexCoord(0.875, 1, 0, 0.125);
self.ThumbTexture:SetTexCoord(0, 0.0625, 0.875, 1);
self.Marker:SetTexCoord(0.125, 0.140625, 0.875, 1);
self:SetHighlight(false);
self:SetBorderOffset(2);
self.Marker:SetVertexColor(0.5, 0.5, 0.5);
end
function NarciColorPickerSliderMixin:OnValueChanged(value, isUserInput)
if value == self.value then
return
end
self.ThumbTexture:SetPoint("CENTER", self.Thumb, "CENTER", 0, 0);
--self.Marker:SetPoint("CENTER", self.Thumb, "CENTER", 0, 0);
self.value = value;
ColorPicker:Update();
end
--Confirm/Cancel New Color
NarciColorPickerActionButtonMixin = {};
function NarciColorPickerActionButtonMixin:OnLoad()
local tex = "Interface\\AddOns\\Narcissus\\Art\\Widgets\\ColorPicker\\UI.tga";
self.borderTextures = {
self.LeftEnd, self.Left, self.Center, self.Right, self.RightEnd
}
for i = 1, #self.borderTextures do
self.borderTextures[i]:SetTexture(tex);
end
self.LeftEnd:SetTexCoord(0, 0.125, 0.3750, 0.6250);
self.Left:SetTexCoord(0.125, 0.25, 0.3750, 0.6250);
if self.action == "Confirm" then
self.Center:SetTexCoord(0.505, 0.75, 0.3750, 0.6250);
else
self.Center:SetTexCoord(0.75, 1, 0.3750, 0.6250);
end
self.Right:SetTexCoord(0.125, 0.25, 0.3750, 0.6250);
self.RightEnd:SetTexCoord(0.375, 0.5, 0.3750, 0.6250);
self:SetHighlight(false);
end
function NarciColorPickerActionButtonMixin:SetButtonHeight(height)
self:SetHeight(height);
self.Reference:SetHeight(height - 3);
end
function NarciColorPickerActionButtonMixin:SetButtonWidth(width)
self:SetWidth(width);
self.Reference:SetWidth(width - 1);
end
function NarciColorPickerActionButtonMixin:SetButtonSize(w, h)
self.LeftEnd:SetSize(h, 2*h);
self.RightEnd:SetSize(h, 2*h);
self.Center:SetSize(2*h, 2*h);
self.Left:SetHeight(2*h);
self.Right:SetHeight(2*h);
self:SetButtonWidth(w);
self:SetButtonHeight(h);
end
function NarciColorPickerActionButtonMixin:SetHighlight(state)
local v;
if state then
v = 1;
else
v = 0.66;
end
for i = 1, #self.borderTextures do
self.borderTextures[i]:SetVertexColor(v, v, v);
end
end
function NarciColorPickerActionButtonMixin:OnEnter()
self:SetHighlight(true);
end
function NarciColorPickerActionButtonMixin:OnLeave()
self:SetHighlight(false);
end
function NarciColorPickerActionButtonMixin:OnMouseUp()
self.Reference:SetPoint("CENTER", self, "CENTER", 0, 0);
end
function NarciColorPickerActionButtonMixin:OnMouseDown()
self.Reference:SetPoint("CENTER", self, "CENTER", 0, -1);
end
function NarciColorPickerActionButtonMixin:OnClick()
ColorPicker[self.action](ColorPicker);
end
function NarciColorPickerActionButtonMixin:SetColor(r, g, b)
self.Reference:SetColorTexture(r, g, b);
self.color = {r, g, b};
end
function NarciColorPickerActionButtonMixin:GetColor()
if self.color then
return unpack(self.color)
else
return 0, 0, 0
end
end
NarciUIColorPickerMixin = {};
function NarciUIColorPickerMixin:Preload()
ColorPicker = self;
self:RegisterForDrag("LeftButton");
local sliderHeight = 12;
local sliderWidth = 160;
local thumbWidth = 6;
local HueSlider = self.HueSlider;
local colors = {
{1, 0, 0}, --Red
{1, 1, 0}, --Yellow
{0, 1, 0}, --Green
{0, 1, 1}, --Cyan
{0, 0, 1}, --Blue
{1, 0, 1}, --Pink
{1, 0, 0}, --Red
}
local gt;
local gradients = {};
local numBlocks = #colors - 1;
local blockWidth = (sliderWidth - thumbWidth) / numBlocks;
for i = 1, numBlocks do
gt = HueSlider:CreateTexture(nil, "ARTWORK");
gradients[i] = gt;
gt:SetSize(blockWidth, sliderHeight);
if i == 1 then
gt:SetPoint("LEFT", HueSlider, "LEFT", thumbWidth/2 + blockWidth * (i - 1), 0);
else
gt:SetPoint("LEFT", gradients[i - 1], "RIGHT", 0, 0);
end
gt:SetColorTexture(1, 1, 1, 1);
SetGradient(gt, "HORIZONTAL", colors[i][1], colors[i][2], colors[i][3], colors[i+1][1], colors[i+1][2], colors[i+1][3]);
end
HueSlider:SetMinMaxValues(0, 360);
HueSlider:SetValueStep(1);
HueSlider:SetWidth(sliderWidth);
HueSlider:SetValue(0);
HueSlider.value = 0;
local SatSlider = self.SaturationSlider;
local gt2 = SatSlider:CreateTexture(nil, "ARTWORK");
SatSlider.Gradient = gt2;
gt2:SetSize(sliderWidth - thumbWidth, sliderHeight);
gt2:SetPoint("LEFT", SatSlider, "LEFT", thumbWidth/2, 0);
gt2:SetColorTexture(1, 1, 1, 1);
SetGradient(gt2, "HORIZONTAL", 1, 1, 1, 1, 0, 0);
SatSlider:SetMinMaxValues(0, 100);
SatSlider:SetValueStep(1);
SatSlider:SetWidth(sliderWidth);
SatSlider:SetValue(100);
SatSlider.value = 100;
local BriSlider = self.BrightnessSlider;
local gt3 = SatSlider:CreateTexture(nil, "ARTWORK");
BriSlider.Gradient = gt3;
gt3:SetSize(sliderWidth - thumbWidth, sliderHeight);
gt3:SetPoint("LEFT", BriSlider, "LEFT", thumbWidth/2, 0);
gt3:SetColorTexture(1, 1, 1, 1);
SetGradient(gt3, "HORIZONTAL", 0, 0, 0, 1, 0, 0);
BriSlider:SetMinMaxValues(0, 100);
BriSlider:SetValueStep(1);
BriSlider:SetWidth(sliderWidth);
BriSlider:SetValue(100);
local ConfirmButton = self.ConfirmButton;
local CancelButton = self.CancelButton;
local padding = 4;
local sliders = {HueSlider, SatSlider, BriSlider};
for i = 1, #sliders do
sliders[i]:SetButtonSize(sliderWidth, sliderHeight);
sliders[i]:SetParent(self.FrameContainer);
end
HueSlider:SetPoint("TOP", self, "TOP", 0, -padding);
SatSlider:SetPoint("TOP", self, "TOP", 0, -2*padding - sliderHeight);
BriSlider:SetPoint("TOP", self, "TOP", 0, -3*padding - 2*sliderHeight);
ConfirmButton:SetPoint("TOPRIGHT", self, "TOP", -padding, -5*padding - 3*sliderHeight);
CancelButton:SetPoint("TOPLEFT", self, "TOP", padding, -5*padding - 3*sliderHeight);
ConfirmButton:SetButtonSize(sliderWidth/2 - padding - thumbWidth/4, sliderHeight);
CancelButton:SetButtonSize(sliderWidth/2 - padding - thumbWidth/4, sliderHeight);
CancelButton:SetColor(0, 0, 0);
self:SetSize(sliderWidth + 2*padding - 4, 4*sliderHeight + 6*padding + 1);
self.Preload = nil;
self:SetRGB(0, 0, 0);
self:Update();
end
function NarciUIColorPickerMixin:OnLoad()
self:Preload();
self:Hide();
end
function NarciUIColorPickerMixin:Update()
if self.Preload then return end;
local h, s, v = self:GetHSV();
local r, g, b = HSV2RGB(h, 1, v);
SetGradient(self.SaturationSlider.Gradient, "HORIZONTAL", v, v, v, r, g, b);
r, g, b = HSV2RGB(h, s, 1);
SetGradient(self.BrightnessSlider.Gradient, "HORIZONTAL", 0, 0, 0, r, g, b);
r, g, b = self:GetRGB();
self.ConfirmButton:SetColor(r, g, b);
if self.objects then
for i = 1, #self.objects do
self.objects[i]:SetVertexColor(r, g, b);
end
end
end
function NarciUIColorPickerMixin:SetRGB(r, g, b)
local h, s, v = RGBRatio2HSV(r, g, b);
self.HueSlider:SetValue(h);
self.SaturationSlider:SetValue(100*s);
self.BrightnessSlider:SetValue(100*v);
self.ConfirmButton:SetColor(r, g, b);
end
function NarciUIColorPickerMixin:GetHSV()
return self.HueSlider.value or 0, (self.SaturationSlider.value or 100)/100, (self.BrightnessSlider.value or 100)/100;
end
function NarciUIColorPickerMixin:GetRGB()
return HSV2RGB(self:GetHSV());
end
function NarciUIColorPickerMixin:OnDragStart()
self:StartMoving();
end
function NarciUIColorPickerMixin:OnDragStop()
self:StopMovingOrSizing();
end
function NarciUIColorPickerMixin:FadeButton(buttonIndex)
self.ConfirmButton:Disable();
self.CancelButton:Disable();
FadeFrame(self.FrameContainer, 0.2, 0);
if buttonIndex == 1 then
FadeFrame(self.CancelButton, 0.2, 0);
else
FadeFrame(self.ConfirmButton, 0.2, 0);
end
After(0.5, function()
FadeFrame(self, 0.25, 0);
end);
--After(3, function()
-- self:ShowPanel();
--end)
end
function NarciUIColorPickerMixin:Confirm()
self:FadeButton(1);
self:Update();
end
function NarciUIColorPickerMixin:Cancel()
self:FadeButton(2);
local r, g, b = self.CancelButton:GetColor();
ColorPicker:SetRGB(r, g, b);
end
function NarciUIColorPickerMixin:ShowPanel()
self.FrameContainer:Show();
self.FrameContainer:SetAlpha(1);
self.ConfirmButton:Show();
self.ConfirmButton:SetAlpha(1);
self.CancelButton:Show();
self.CancelButton:SetAlpha(1);
self.ConfirmButton:Enable();
self.CancelButton:Enable();
self:Show();
self:SetAlpha(1);
end
function NarciUIColorPickerMixin:SetObject(switch)
self.objects = switch.objects;
self:ClearAllPoints();
self:SetPoint("TOPLEFT", switch, "TOPRIGHT", 8, 0);
if self.objects and self.objects[1] then
--self:SetRGB(self.objects[1]:GetVertexColor());
self.CancelButton:SetColor(self.objects[1]:GetVertexColor());
end
self:ShowPanel();
end
--------------------------------------------------------------------------------------------------
--Name: Skewed Rectangular Button
--Notes: Clockwise 10 Degree
local MARGIN_X = 5;
NarciShewedRectButtonMixin = {};
function NarciShewedRectButtonMixin:SetButtonSize(width, height)
self:SetSize(width, height);
self.MaskLeft:SetSize(MARGIN_X, height);
self.MaskRight:SetSize(MARGIN_X, height);
local texOffset = 0.05;
local dy = (1 - 2*texOffset)*height/width/2;
self.Icon:SetTexCoord(texOffset, 1 - texOffset, 0.5 - dy, 0.5 + dy);
self.Icon:SetSize(width, height);
end
function NarciShewedRectButtonMixin:SetIcon(iconFile)
self.Icon:SetTexture(iconFile);
end
function NarciShewedRectButtonMixin:SetColorTexture(r, g, b)
self.Icon:SetColorTexture(r, g, b);
end
function NarciShewedRectButtonMixin:ShowAlert()
self:SetIcon("Interface\\AddOns\\Narcissus\\Art\\NavBar\\AlertMark");
self.Icon:Show();
end
function NarciShewedRectButtonMixin:SetHighlight(state)
if state then
self.Icon:SetDesaturation(0);
self.Icon:SetVertexColor(1, 1, 1);
else
self.Icon:SetDesaturation(0.2);
self.Icon:SetVertexColor(0.80, 0.80, 0.80);
end
end
function NarciShewedRectButtonMixin:UseFullMask(state, side)
local mode = "CLAMPTOWHITE"; --CLAMPTOBLACKADDITIVE
if state and (not side or side == 1) then
self.MaskLeft:SetTexture("Interface\\AddOns\\Narcissus\\Art\\Masks\\Full", mode, mode);
else
self.MaskLeft:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SkewdRect\\ReversedMask-Left", mode, mode);
end
if state and (not side or side == 2) then
self.MaskRight:SetTexture("Interface\\AddOns\\Narcissus\\Art\\Masks\\Full", mode, mode);
else
self.MaskRight:SetTexture("Interface\\AddOns\\Narcissus\\Art\\SkewdRect\\ReversedMask-Right", mode, mode);
end
end
--------------------------------------------------------------------------------------------------
--Name: Progress Timer
--Notes: Timer & Progress Bar
NarciProgressTimerMixin = {};
function NarciProgressTimerMixin:SetOnFinishedFunc(func1, func2)
self.Fluid.animFill.onFinishedFunc = func1;
self.Fluid.animFade.onFinishedFunc = func2;
end
function NarciProgressTimerMixin:SetTimer(duration, loopTimer)
self:StopAnimating();
local animFill = self.Fluid.animFill;
animFill.s1:SetDuration(duration);
if loopTimer then
self.isLoop = true;
else
self.isLoop = false;
end
animFill:Play();
end
function NarciProgressTimerMixin:Start()
self.Fluid.animFill:Play();
self:Show();
end
function NarciProgressTimerMixin:Stop()
self:StopAnimating();
self:Hide();
end
function NarciProgressTimerMixin:Pause()
if not self.isPaused then
self.isPaused = true;
self.Fluid.animFill:Pause();
end
end
function NarciProgressTimerMixin:Play()
if self.isPaused then
self.isPaused = nil;
if not self.Fluid.animFade:IsPlaying() then
self.Fluid.animFill:Play();
end
end
end
function NarciProgressTimerMixin:Resume()
if self:IsShown() then
self:Play();
end
end
function NarciProgressTimerMixin:SetAlign(widget, offsetY)
self:ClearAllPoints();
offsetY = offsetY or 0;
self:SetPoint("BOTTOMLEFT", widget, "BOTTOMLEFT", 1, offsetY);
self:SetPoint("BOTTOMRIGHT", widget, "BOTTOMRIGHT", -1, offsetY);
end
function NarciProgressTimerMixin:SetColor(r, g, b)
self.Fluid:SetColorTexture(r, g, b);
end
--------------------------------------------------------------------------------------------------
--Name: Custom Slider
--Notes:
--1. A frame with all slider's methods;
--2. Take into account the MouseDown Position
local offsetUpdater = CreateFrame("Frame");
offsetUpdater.t = 0;
offsetUpdater:Hide();
offsetUpdater:SetScript("OnUpdate", function(self)
self.x, self.y = GetCursorPosition();
self.ratio = (self.yTop - self.y + self.yOffset)/self.pixelRange;
self.scrollBar:SetValueByRatio(self.ratio);
end)
function offsetUpdater:Start(scrollBar)
local uiScale = scrollBar:GetEffectiveScale();
self.scrollBar = scrollBar;
self.yTop = scrollBar:GetTop() * uiScale;
self.pixelRange = scrollBar.thumbRange * uiScale;
local yoffset;
if scrollBar.ThumbTexture:IsMouseOver(0, 0, -2, 0) then
local _, thumbY, mouseY;
_, mouseY = GetCursorPosition();
thumbY = scrollBar.ThumbTexture:GetTop() * uiScale;
self.yOffset = -thumbY + mouseY;
else
self.yOffset = -0.5 * scrollBar.ThumbTexture:GetHeight() * uiScale;
end
self:Show();
end
function offsetUpdater:Stop()
self:Hide();
end
NarciCustomScrollBarMixin = {};
function NarciCustomScrollBarMixin:OnLoad()
self.thumbRange = 0;
self.value = 0;
self:SetMinMaxValues(0, 0);
self:SetThumbAlpha(0.25);
local parentScrollFrame = self:GetParent();
self.onValueChangedFunc = function(value)
parentScrollFrame:SetVerticalScroll(value);
end
end
function NarciCustomScrollBarMixin:SetMinMaxValues(minValue, maxValue)
if minValue > maxValue then
minValue = 0;
maxValue = 0;
end
self.minValue = minValue;
self.maxValue = maxValue;
self:SetShown(maxValue ~= 0)
end
function NarciCustomScrollBarMixin:SetValue(value)
if value < self.minValue then
value = self.minValue;
elseif value > self.maxValue then
value = self.maxValue;
end
self.value = value;
if self.maxValue ~= 0 then
self.ThumbTexture:SetPoint("TOPRIGHT", self, "TOPRIGHT", 0, -value / self.maxValue * self.thumbRange);
end
self.onValueChangedFunc(value);
end
function NarciCustomScrollBarMixin:SetValueByRatio(ratio)
if ratio < 0 then
ratio = 0;
elseif ratio > 1 then
ratio = 1;
end
self:SetValue( ratio * (self.maxValue - self.minValue) )
end
function NarciCustomScrollBarMixin:GetValue()
return self.value or 0;
end
function NarciCustomScrollBarMixin:OnEnter()
if IsMouseButtonDown() then
return
end
if self.ThumbTexture:IsMouseOver() then
self:SetThumbAlpha(1);
else
self:SetThumbAlpha(0.66);
end
end
function NarciCustomScrollBarMixin:OnLeave()
if not self.isDragging then
self:SetThumbAlpha();
end
end
function NarciCustomScrollBarMixin:OnMouseDown()
self.isDragging = true;
offsetUpdater:Start(self);
self:SetThumbAlpha(1);
if self.onMouseDownFunc then
self.onMouseDownFunc();
end
end
function NarciCustomScrollBarMixin:OnMouseUp()
self.isDragging = nil;
offsetUpdater:Stop();
if self:IsMouseOver() then
self:SetThumbAlpha(0.66);
else
self:SetThumbAlpha();
end
end
function NarciCustomScrollBarMixin:OnHide()
self:SetThumbAlpha();
end
function NarciCustomScrollBarMixin:SetThumbAlpha(alpha)
alpha = alpha or 0.4;
self.ThumbTexture:SetAlpha(alpha);
end
function NarciCustomScrollBarMixin:SetRange(fullRange, changeThumbHeight)
local ScrollFrame = self:GetParent();
local thumbHeight = 16;
local barHeight = self:GetHeight() or 0;
if not fullRange or fullRange <= 0.5 then
fullRange = 0;
self:Hide();
else
self:SetMinMaxValues(0, fullRange);
if changeThumbHeight then
thumbHeight = math.floor(barHeight^2 / fullRange);
if thumbHeight > barHeight - 24 then
thumbHeight = barHeight - 24;
end
if thumbHeight < 16 then
thumbHeight = 16;
end
end
self.ThumbTexture:SetHeight(thumbHeight);
end
self.thumbRange = barHeight - thumbHeight;
ScrollFrame.range = fullRange;
end
function NarciCustomScrollBarMixin:OnMinMaxChanged(min, max)
end
--------------------------------------------------------------------------------------------------
NarciInteractableModelMixin = {};
local function UpdateCameraPosition(model)
model:SetCameraPosition(model.cameraDistance * math.sin(model.cameraPitch), 0, model.cameraDistance * math.cos(model.cameraPitch) + 0.8);
end
local function UpdateCameraPitch(model, pitch)
model.cameraPitch = pitch;
UpdateCameraPosition(model);
end
function NarciInteractableModelMixin:OnLoad()
self.rotation = 0.61;
self:SetFacing(self.rotation);
self:MakeCurrentCameraCustom();
self:SetCameraTarget(0, 0, 0);
self.cameraPitch = self:GetPitch();
self.cameraDistance = self:GetCameraDistance()
end
function NarciInteractableModelMixin:StartPanning()
self.isAltDown = IsAltKeyDown();
self.panning = true;
local posX, posY, posZ = self:GetPosition();
self.posX = posX;
self.posY = posY;
self.posZ = posZ;
local cursorX, cursorY = GetCursorPosition();
self.cursorX = cursorX;
self.cursorY = cursorY;
self.zoomCursorStartX, self.zoomCursorStartY = cursorX, cursorY;
end
function NarciInteractableModelMixin:OnMouseWheel(delta)
if not self:HasCustomCamera() then return; end
self.cameraDistance = self.cameraDistance - delta * 0.25
UpdateCameraPosition(self);
end
function NarciInteractableModelMixin:OnMouseUp(button)
if ( button == "RightButton" and self.panning ) then
self.panning = false;
elseif ( self.mouseDown ) then
if ( not button or button == "LeftButton" ) then
self.mouseDown = false;
end
end
end
function NarciInteractableModelMixin:OnMouseDown(button)
if ( button == "RightButton" and not self.mouseDown ) then
self:StartPanning();
else
if ( not button or button == "LeftButton" ) then
self.mouseDown = true;
self.rotationCursorStart, self.cameraPitchCursorStart = GetCursorPosition();
end
end
end
function NarciInteractableModelMixin:OnModelLoaded()
self:MakeCurrentCameraCustom();
self:SetCameraTarget(0, 0, 0);
self.cameraDistance = self:GetCameraDistance();
end
function NarciInteractableModelMixin:OnHide()
if ( self.panning ) then
self.panning = false;
end
self.mouseDown = false;
end
function NarciInteractableModelMixin:OnUpdate()
-- Mouse drag rotation
if (self.mouseDown) then
if ( self.rotationCursorStart ) then
local x, y = GetCursorPosition();
local diffX = (x - self.rotationCursorStart) * 0.01; --MODELFRAME_DRAG_ROTATION_CONSTANT
local diffY = (y - self.cameraPitchCursorStart) * 0.02;
self.rotationCursorStart, self.cameraPitchCursorStart = GetCursorPosition();
if not IsAltKeyDown() then
--Rotate Character
self.rotation = self.rotation + diffX;
if ( self.rotation < 0 ) then
self.rotation = self.rotation + (2 * pi);
end
if ( self.rotation > (2 * pi) ) then
self.rotation = self.rotation - (2 * pi);
end
self:SetFacing(self.rotation, false);
else
--Rotate Camera (pitch)
self.cameraPitch = self.cameraPitch + diffY;
if ( self.cameraPitch <= (0 + 0.01)) then
self.cameraPitch = 0.01;
end
if ( self.cameraPitch >= ( pi - 0.01)) then
self.cameraPitch = pi - 0.01;
end
UpdateCameraPitch(self, self.cameraPitch);
end
end
elseif ( self.panning ) then
local isAltDown = IsAltKeyDown();
if isAltDown ~= self.isAltDown then
--Reset cursor positions
self:StartPanning();
end
local modelScale = self:GetModelScale();
local cursorX, cursorY = GetCursorPosition();
local scale = UIParent:GetEffectiveScale();
local diff = (cursorX - self.zoomCursorStartX) + (cursorY - self.zoomCursorStartY);
self.zoomCursorStartX, self.zoomCursorStartY = GetCursorPosition();
if not isAltDown then
local zoom = sqrt(sqrt(self.cameraDistance));
local transformationRatio = 0.00002* 40 * 2 ^ (zoom * 2) * scale / modelScale;
local dx = (cursorX - self.cursorX) * transformationRatio;
local dy = (cursorY - self.cursorY) * transformationRatio;
local posY = self.posY + dx;
local posZ = self.posZ + dy;
self:SetPosition(self.posX, posY, posZ);
--print("Y: "..posY.." Z: "..posZ.." Dis: "..self.cameraDistance)
else
self.cameraDistance = self.cameraDistance - diff * 0.01;
UpdateCameraPosition(self);
end
end
end
--------------------------------------------------------------------------------------------------
--Name: Search Box
local function OnDeletePressed(widget, key)
if key == "DELETE" then
widget:ClearText(true);
return true
end
end
NarciSearchBoxSharedMixin = {};
function NarciSearchBoxSharedMixin:OnLoad()
local delayedSearch = NarciAPI_CreateAnimationFrame(0.5);
self.delayedSearch = delayedSearch;
delayedSearch:SetScript("OnUpdate", function(frame, elapsed)
frame.total = frame.total + elapsed;
if frame.total >= frame.duration then
frame:Hide();
if self.onSearchFunc then
self.onSearchFunc( self:GetText() );
end
end
end)
self:OnLeave();
self.onDeletePressedFunc = OnDeletePressed;
self.onKeyDownFunc = OnDeletePressed;
end
function NarciSearchBoxSharedMixin:OnShow()
if self.noAutoFocus then return end;
self:SetFocus();
end
function NarciSearchBoxSharedMixin:OnHide()
self.delayedSearch:Hide();
end
function NarciSearchBoxSharedMixin:OnTextChanged(isUserInput)
local str = self:GetText();
if str and str ~= "" then
self.DefaultText:Hide();
self.EraseButton:Show();
else
self.DefaultText:Show();
self.EraseButton:Hide();
end
if isUserInput then
self:Search(true);
end
self.NoMatchText:Hide();
end
function NarciSearchBoxSharedMixin:QuitEdit()
self:ClearFocus();
end
function NarciSearchBoxSharedMixin:OnTabPressed()
self:HighlightText();
end
function NarciSearchBoxSharedMixin:OnEditFocusGained()
self:HighlightText();
self:SetScript("OnKeyDown", self.onKeyDownFunc);
end
function NarciSearchBoxSharedMixin:OnEditFocusLost()
self:HighlightText(0, 0);
self:OnLeave();
self:SetScript("OnKeyDown", nil);
if self:IsMouseOver() and IsMouseButtonDown("LeftButton") then
self.EraseButton.isEditing = true;
else
self.EraseButton.isEditing = false;
end
end
function NarciSearchBoxSharedMixin:Search(on)
self.delayedSearch:Hide();
if on then
self.delayedSearch:Show();
end
end
function NarciSearchBoxSharedMixin:ClearText(reset)
self:SetText("");
self.DefaultText:Show();
self.EraseButton:Hide();
end
function NarciSearchBoxSharedMixin:OnEnter()
self.DefaultText:SetTextColor(0.52, 0.52, 0.52);
end
function NarciSearchBoxSharedMixin:OnLeave()
if not self:IsMouseOver() then
self.DefaultText:SetTextColor(0.42, 0.42, 0.42);
end
end
function NarciSearchBoxSharedMixin:GetValidText()
local str = strtrim(self:GetText());
if str ~= "" then
return str
end
end
--------------------------------------------------------------------------------------------------
--Show a L/R mark next to the item border
NarciTransmogSlotDirectionMarkMixin = {};
function NarciTransmogSlotDirectionMarkMixin:SetDirection(direction)
if direction == 1 then
self.tooltip = LEFTSHOULDERSLOT or "Left Shoulder";
self.Letter:SetTexCoord(0, 0.5, 0, 0.5);
self.Triangle:SetTexCoord(0, 0.5, 0.5, 1);
else
self.tooltip = RIGHTSHOULDERSLOT or "Right Shoulder";
self.Letter:SetTexCoord(0.5, 1, 0, 0.5);
self.Triangle:SetTexCoord(0.5, 1, 0.5, 1);
end
end
function NarciTransmogSlotDirectionMarkMixin:SetColor(r, g, b)
self.Letter:SetVertexColor(r, g, b);
end
function NarciTransmogSlotDirectionMarkMixin:SetQualityColor(itemQuality)
self:SetColor(NarciAPI.GetItemQualityColor(itemQuality));
end
function NarciTransmogSlotDirectionMarkMixin:OnEnter()
end
function NarciTransmogSlotDirectionMarkMixin:OnLeave()
end
function NarciTransmogSlotDirectionMarkMixin:OnHide()
end
--------------------------------------------------------------------------------------------------
local CreateKeyChordStringUsingMetaKeyState = CreateKeyChordStringUsingMetaKeyState;
--Name: Clipboard
--Notes: Highlight the border when gaining focus. Show visual feedback (glow) after pressing Ctrl+C
local HotkeyListener = CreateFrame("Frame");
HotkeyListener:SetFrameStrata("TOOLTIP");
HotkeyListener:Hide();
HotkeyListener:SetPropagateKeyboardInput(true);
HotkeyListener:SetScript("OnKeyDown", function(self, key)
local keys = CreateKeyChordStringUsingMetaKeyState(key);
if keys == "CTRL-C" or key == "COMMAND-C" then
if self.parentEditBox then
self:Hide();
After(0, function()
--Texts won't be copied if the editbox hides immediately
self.parentEditBox:OnSuccess();
end);
end
end
end);
function HotkeyListener:SetParentObject(editbox)
self.parentEditBox = editbox;
self:Show();
end
function HotkeyListener:Stop(editbox)
if self.parentEditBox == editbox then
self:Hide();
end
end
NarciResponsiveEditBoxSharedMixin = {};
function NarciResponsiveEditBoxSharedMixin:OnEditFocusGained()
self:HighlightText();
if self.LockHighlight then
self:LockHighlight(true);
else
self:GetParent():GetParent():LockHighlight(true);
end
HotkeyListener:SetParentObject(self);
end
function NarciResponsiveEditBoxSharedMixin:OnEditFocusLost()
self:HighlightText(0, 0);
if self.LockHighlight then
self:LockHighlight(false);
else
self:GetParent():GetParent():LockHighlight(false);
end
HotkeyListener:Stop(self);
end
function NarciResponsiveEditBoxSharedMixin:OnSuccess()
if self.Glow then
self:Glow(false);
else
self:GetParent():GetParent():Glow();
end
self:QuitEdit();
if self.onCopiedCallback then
self.onCopiedCallback(self);
end
end
function NarciResponsiveEditBoxSharedMixin:QuitEdit()
self:ClearFocus();
end
function NarciResponsiveEditBoxSharedMixin:OnHide()
self:QuitEdit();
self.numInput = nil;
self:StopAnimating();
end
function NarciResponsiveEditBoxSharedMixin:OnTextChanged(userInput)
end
function NarciResponsiveEditBoxSharedMixin:SetDefaultCursorPosition(offset)
self:SetCursorPosition(offset);
self.defaultCursorPosition = offset;
end
--Subtype: The editbox itself has a border
NarciResponsiveClipboardMixin = CreateFromMixins(NarciFrameBorderMixin, NarciResponsiveEditBoxSharedMixin);
function NarciResponsiveClipboardMixin:OnTextChanged(userInput)
if userInput then
self:SetText(self.copiedText);
if self.defaultCursorPosition then
self:SetCursorPosition(self.defaultCursorPosition);
end
if not self.numInput then
self.numInput = 0;
end
self.numInput = self.numInput + 1;
if self.numInput > 3 then
self.numInput = nil;
self:QuitEdit();
end
else
self.copiedText = self:GetText();
end
end
function NarciResponsiveEditBoxSharedMixin:OnHide()
self:QuitEdit();
self.copiedText = nil;
end
--Subtype: Frame-ScrollFrame-EditBox
NarciScrollEditBoxMixin = CreateFromMixins(NarciFrameBorderMixin);
function NarciScrollEditBoxMixin:SetText(str)
self.ScrollFrame.EditBox:SetText(str);
After(0, function()
self:UpdateScrollRange(true);
end);
end
function NarciScrollEditBoxMixin:SetFocus()
self.ScrollFrame.EditBox:SetFocus();
end
function NarciScrollEditBoxMixin:ClearFocus()
self.ScrollFrame.EditBox:ClearFocus();
end
function NarciScrollEditBoxMixin:UpdateScrollRange(resetOffset)
if resetOffset then
self.ScrollFrame.scrollBar:SetValue(0);
end
local editBoxHeight = self.ScrollFrame.EditBox:GetHeight();
local scrollFrameHeight = self.ScrollFrame:GetHeight();
local range = math.floor(editBoxHeight - scrollFrameHeight + 0.5);
self.ScrollFrame.scrollBar:SetRange(range, true);
end
function NarciScrollEditBoxMixin:OnMouseDown()
self.ScrollFrame.EditBox:SetFocus();
end
function NarciScrollEditBoxMixin:PostLoad()
self:OnLoad();
self.ScrollFrame.scrollBar:OnLoad();
self.ScrollFrame.buttonHeight = 14;
self.ScrollFrame.scrollBar:SetRange(0, true);
NarciAPI_SmoothScroll_Initialization(self.ScrollFrame, nil, nil, 2, 0.14);
end
function NarciScrollEditBoxMixin:SetFontObject(fontObject)
self.ScrollFrame.EditBox:SetFontObject(fontObject);
end
function NarciScrollEditBoxMixin:SetFontColor(r, g, b)
self.ScrollFrame.EditBox:SetTextColor(r, g, b);
end
--------------------------------------------------------------------------------------------------
--Notes: Hide the frame if user clicks anywhere other than the frame itself or the switch used to open that frame.
NarciAutoCloseFrameMixin = {};
function NarciAutoCloseFrameMixin:OnShow()
if not self.setParentObjectManually then
self.parentObject = self:GetParent();
end
self:RegisterEvent("GLOBAL_MOUSE_DOWN");
if self.autoClose then
self.AutoCloseTimer:Play();
end
end
function NarciAutoCloseFrameMixin:OnHide()
self.parentObject = nil;
self:UnregisterEvent("GLOBAL_MOUSE_DOWN");
self.AutoCloseTimer:Stop();
self:Hide();
end
function NarciAutoCloseFrameMixin:OnEvent(event)
if self:IsMouseOver() then
self:RestartTimer();
else
if (not self.parentObject) or (self.parentObject and not self.parentObject:IsMouseOver()) then
self:Hide();
else
self:RestartTimer();
end
end
end
function NarciAutoCloseFrameMixin:RestartTimer()
self.AutoCloseTimer:Stop();
if self.autoClose then
self.AutoCloseTimer:Play();
end
end
function NarciAutoCloseFrameMixin:OnTimerFinished()
self:OnEvent("GLOBAL_MOUSE_DOWN");
end
function NarciAutoCloseFrameMixin:Toggle()
self:SetShown(not self:IsShown());
end
--------------------------------------------------------------------------------------------------
--Simple Line Slider
NarciVerticalLineSliderMixin = {};
function NarciVerticalLineSliderMixin:OnLoad()
self.Thumb:SetVertexColor(0.5, 0.5, 0.5);
self.Background:SetVertexColor(0.25, 0.25, 0.25);
self.Background:SetAlpha(0.4);
end
function NarciVerticalLineSliderMixin:OnEnter()
self:FadeIn();
self:RegisterEvent("GLOBAL_MOUSE_UP");
end
function NarciVerticalLineSliderMixin:OnLeave()
if not self:IsDraggingThumb() then
self:FadeOut();
self:UnregisterEvent("GLOBAL_MOUSE_UP");
end
end
function NarciVerticalLineSliderMixin:FadeIn()
FadeFrame(self.Background, 0.25, 1);
self.Thumb:SetVertexColor(0.8, 0.8, 0.8);
end
function NarciVerticalLineSliderMixin:FadeOut()
FadeFrame(self.Background, 0.25, 0.4);
self.Thumb:SetVertexColor(0.5, 0.5, 0.5);
end
function NarciVerticalLineSliderMixin:OnHide()
self:UnregisterEvent("GLOBAL_MOUSE_UP");
end
function NarciVerticalLineSliderMixin:OnEvent()
if (not self:IsMouseMotionFocus()) then
self:OnLeave();
end
end
--------------------------------------------------------------------------------------------------
local _, screenHeight = GetPhysicalScreenSize();
local PIXEL = (768/screenHeight);
screenHeight = nil;
NarciLineBorderMixin = {};
function NarciLineBorderMixin:SetWeight(weight)
self.weight = weight;
end
function NarciLineBorderMixin:SetColor(r, g, b)
self.Stroke:SetColorTexture(r, g, b); --default color is 0.25
end
function NarciLineBorderMixin:OnLoad()
self.Exclusion:SetTexture("Interface\\AddOns\\Narcissus\\Art\\Masks\\Exclusion", "CLAMPTOWHITE", "CLAMPTOWHITE", "NEAREST");
self:SetWeight(2);
self:UpdateStroke();
end
function NarciLineBorderMixin:OnShow()
self:UpdateStroke();
end
function NarciLineBorderMixin:UpdateStroke()
local scale = self:GetEffectiveScale();
if scale ~= self.scale then
self.scale = scale;
else
return
end
local a = (self.weight or 1) * PIXEL / scale;
self.Exclusion:ClearAllPoints();
self.Exclusion:SetPoint("TOPLEFT", self, "TOPLEFT", a, -a);
self.Exclusion:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", -a, a);
end
--------------------------------------------------------------------------------------------------
NarciChainAnimationMixin = {};
function NarciChainAnimationMixin:Initialize(size, isLinked)
local offset = 4;
local unchainedOffset = 8;
local side = 24;
local tex = "Interface\\AddOns\\Narcissus\\Art\\Widgets\\LightSetup\\Chain";
self:SetScale(size / side);
self.isLinked = isLinked;
self.chains = {
self.UpTop, self.DownTop, self.UpBottom, self.DownBottom,
};
self.unchains = {
self.ChainShardUp, self.ChainShardDown, self.UpBroken, self.DownBroken
};
for i = 1, #self.chains do
self.chains[i]:SetTexture(tex, nil, nil, "TRILINEAR");
self.chains[i]:SetSize(side, side);
if i % 2 == 1 then
self.chains[i]:SetPoint("CENTER", self, "CENTER", offset, offset);
else
self.chains[i]:SetPoint("CENTER", self, "CENTER", -offset, -offset);
end
end
self.UpBroken:SetSize(side, side);
self.UpBroken:SetTexture(tex, nil, nil, "TRILINEAR");
self.UpBroken:SetPoint("CENTER", self, "CENTER", unchainedOffset, unchainedOffset);
self.DownBroken:SetSize(side, side);
self.DownBroken:SetTexture(tex, nil, nil, "TRILINEAR");
self.DownBroken:SetPoint("CENTER", self, "CENTER", -unchainedOffset, -unchainedOffset);
local tex2 = "Interface\\AddOns\\Narcissus\\Art\\Widgets\\LightSetup\\ChainShard";
self.ChainShardUp:SetSize(side/2, side/2);
self.ChainShardUp:SetTexture(tex2, nil, nil, "TRILINEAR");
self.ChainShardDown:SetSize(side/2, side/2);
self.ChainShardDown:SetTexture(tex2, nil, nil, "TRILINEAR");
local tex3 = "Interface\\AddOns\\Narcissus\\Art\\Widgets\\LightSetup\\ChainWave";
self.WaveExpand:SetSize(side/2, side/2);
self.WaveExpand:SetTexture(tex3, nil, nil, "TRILINEAR");
for i = 1, #self.chains do
self.chains[i]:SetShown(isLinked);
end
for i = 1, #self.unchains do
self.unchains[i]:SetShown(not isLinked);
end
end
function NarciChainAnimationMixin:Switch()
self:StopAnimating();
local isLinked = not self.isLinked;
self.isLinked = isLinked;
if isLinked then
for i = 1, #self.unchains do
self.unchains[i]:Hide();
end
for i = 1, #self.chains do
self.chains[i]:Show();
self.chains[i].Link:Play();
end
else
for i = 1, #self.unchains do
self.unchains[i]:Show();
self.unchains[i].Unlink:Play();
end
for i = 1, #self.chains do
self.chains[i]:Hide();
end
self.WaveExpand.Unlink:Play();
end
--[[
if not self.isPlayingSound then
self.isPlayingSound = true;
After(0.5, function() self.isPlayingSound = nil end);
if isLinked then
PlaySound(1188, "SFX", false);
else
PlaySound(112052, "SFX", false);
end
end
--]]
end
---------------------------------------------------------------------
--Create a rectangle with stroke to indicate the area is interactable
NarciInteractableAreaIndicatorMixin = {};
function NarciInteractableAreaIndicatorMixin:OnLoad()
self.Exclusion:SetTexture("Interface\\AddOns\\Narcissus\\Art\\Masks\\Exclusion", "CLAMPTOWHITE", "CLAMPTOWHITE", "NEAREST");
self:UpdateStroke();
end
function NarciInteractableAreaIndicatorMixin:SetStrokeSize(pixel)
self.pixel = pixel;
self:UpdateStroke();
end
function NarciInteractableAreaIndicatorMixin:SetStrokeColor(r, g, b)
self.Stroke:SetColorTexture(r, g, b);
end
function NarciInteractableAreaIndicatorMixin:OnShow()
local scale = self:GetEffectiveScale();
if scale ~= self.scale then
self:UpdateStroke();
end
end
function NarciInteractableAreaIndicatorMixin:UpdateStroke()
local pixelSize = NarciAPI.GetPixelForWidget(self, self.pixel or 2);
self.Exclusion:SetPoint("TOPLEFT", self, "TOPLEFT", pixelSize, -pixelSize);
self.Exclusion:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", -pixelSize, pixelSize);
end
function NarciInteractableAreaIndicatorMixin:OnEnter()
self.Stroke:Show();
end
function NarciInteractableAreaIndicatorMixin:OnLeave()
self.Stroke:Hide();
end
---------------------------------------------------------------------
--Keybinding
--internalAction: hotkeys used within Narcissus
--externalAction: hotkeys used to open Narcissus panels
local KeyBindingButtonOverlay;
local function ReleaseOverlay()
if KeyBindingButtonOverlay then
KeyBindingButtonOverlay:Hide();
KeyBindingButtonOverlay:StopAnimating();
end
end
local function AnchorOverlayToBindingButton(button, colorType, descriptionText)
--colorType 1 red 2 yellow 3 green
local f = KeyBindingButtonOverlay;
if not f then
KeyBindingButtonOverlay = CreateFrame("Frame", "Test", button, "NarciLineBorderTemplate");
f = KeyBindingButtonOverlay;
f.Description = f:CreateFontString(nil, "OVERLAY", "NarciNonInteractiveFont");
f.Description:SetPoint("TOPLEFT", f, "BOTTOMLEFT", 0, -6);
f:SetScript("OnHide", ReleaseOverlay);
f.ConfirmButton = CreateFrame("Button", nil, f, "NarciConfirmButtonTemplate");
f.ConfirmButton:SetPoint("LEFT", f, "RIGHT", 6, 0);
local ag = f:CreateAnimationGroup();
f.FadeOut = ag;
ag:SetScript("OnFinished", function()
f:Hide();
end);
local a1 = ag:CreateAnimation("Alpha");
a1:SetDuration(0.5);
a1:SetFromAlpha(1);
a1:SetToAlpha(0);
a1:SetOrder(1);
a1:SetStartDelay(1.5);
end
f:Hide();
f:ClearAllPoints();
f:SetPoint("TOPLEFT", button, "TOPLEFT", 0, 0);
f:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", 0, 0);
f:SetParent(button);
f.ConfirmButton.parentObject = button;
f.Description:SetText(descriptionText);
if descriptionText then
f.Description:Show();
else
f.Description:Hide();
end
if colorType == 1 then
f:SetColor(0.9333, 0.1961, 0.1412);
f.Description:SetTextColor(0.9333, 0.1961, 0.1412);
f.FadeOut:Play();
f.ConfirmButton:Hide();
elseif colorType == 2 then
f:SetColor(0.9882, 0.9294, 0);
f.Description:SetTextColor(0.9882, 0.9294, 0);
f.ConfirmButton:Show();
elseif colorType == 3 then
f:SetColor(0.4862, 0.7725, 0.4627)
f.Description:SetTextColor(0.4862, 0.7725, 0.4627);
f.FadeOut:Play();
f.ConfirmButton:Hide();
end
f:SetAlpha(1);
f:Show();
end
local function GetInternalBindingKey(self)
if self.actionName then
return NarcissusDB[self.actionName] or NOT_BOUND
else
return "No Action"
end
end
local function GetExternalBindingKey(self)
if self.actionName then
return GetBindingKey(self.actionName) or NOT_BOUND
else
return "No Action"
end
end
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
NarciGenericKeyBindingButtonMixin = {};
local function IsExitKey(key)
return key == "ESCAPE" or key == "SPACE" or key == "ENTER" or key == "BACKSPACE"
end
local function InternalAction_OnKeydown(self, key)
if IsExitKey(key) then
self:ExitKeyBinding();
return
end
if self.actionName then
self:ExitKeyBinding(true);
NarcissusDB[self.actionName] = key;
end
end
local function ExternalAction_OnKeydown(self, key)
if IsExitKey(key) then
self:ExitKeyBinding();
return
end
local KeyText = CreateKeyChordStringUsingMetaKeyState(key);
self.ButtonText:SetText(KeyText);
self.key = KeyText;
if not IsKeyPressIgnoredForBinding(key) then
self:VerifyKey();
end
end
local function ExternalAction_OnKeyUp(self, key)
self:VerifyKey();
end
local function KeyBingdingButton_OnEvent(self, event)
if not (self:IsMouseOver() or ( KeyBindingButtonOverlay and KeyBindingButtonOverlay.ConfirmButton:IsMouseOver() )) then
self:ExitKeyBinding();
end
end
function NarciGenericKeyBindingButtonMixin:OnEnter()
self.Border:SetColor(0.8, 0.8, 0.8);
end
function NarciGenericKeyBindingButtonMixin:OnLeave()
if not self.isOn then
self.Border:SetColor(0.25, 0.25, 0.25);
end
end
function NarciGenericKeyBindingButtonMixin:OnLoad()
if self.internalActionName then
self:SetBindingActionInternal(self.internalActionName);
self.internalActionName = nil;
elseif self.externalActionName then
self:SetBindingActionExternal(self.externalActionName);
self.externalActionName = nil;
end
end
function NarciGenericKeyBindingButtonMixin:SetBindingActionInternal(actionName)
self.actionName = actionName;
self.onKeyDownFunc = InternalAction_OnKeydown;
self.onKeyUpFunc = EmptyFunc;
self.getBindingFunc = GetInternalBindingKey;
end
function NarciGenericKeyBindingButtonMixin:SetBindingActionExternal(actionName)
self.actionName = actionName;
self.onKeyDownFunc = ExternalAction_OnKeydown;
self.onKeyUpFunc = ExternalAction_OnKeyUp;
self.getBindingFunc = GetExternalBindingKey;
end
function NarciGenericKeyBindingButtonMixin:ResetVisualAndScript()
self.isOn = nil;
if not self:IsVisible() or not self:IsMouseOver() then
self.Border:SetColor(0.25, 0.25, 0.25);
end
self.ButtonText:SetTextColor(1, 1, 1);
self.ButtonText:SetShadowColor(0, 0, 0);
self.ButtonText:SetShadowOffset(0.6, -0.6);
self.Background:SetColorTexture(0, 0, 0);
self:SetPropagateKeyboardInput(true)
self:SetScript("OnKeyDown", nil);
self:SetScript("OnUpdate", nil);
self:UnregisterEvent("GLOBAL_MOUSE_DOWN");
end
function NarciGenericKeyBindingButtonMixin:ExitKeyBinding(success)
self.key = nil;
After(0, function()
self:ResetVisualAndScript();
self:GetBindingKey();
end)
if success then
AnchorOverlayToBindingButton(self, 3, KEY_BOUND);
else
ReleaseOverlay();
end
end
function NarciGenericKeyBindingButtonMixin:VerifyKey(override)
local key = self.key;
if not key then
return;
end
if key == "SHIFT" or key=="ALT" or key=="CTRL" then
self.key = nil;
self:ExitKeyBinding();
AnchorOverlayToBindingButton(self, 1, NARCI_INVALID_KEY);
return false
else
local action = GetBindingAction(key);
if (action and action ~= "" and action ~= self.actionName) and not override then
AnchorOverlayToBindingButton(self, 2, Narci.L["Override"].." "..GetBindingName(action).." ?");
return true
else
ClearBindingKey(self.actionName);
if SetBinding(key, self.actionName, 1) then
SaveBindings(1); --account wide
self:ExitKeyBinding(true);
else
self:ExitKeyBinding();
AnchorOverlayToBindingButton(self, 1, ERROR_CAPS);
end
return false;
end
end
end
function NarciGenericKeyBindingButtonMixin:GetBindingKey()
self.ButtonText:SetText( self.getBindingFunc(self) );
end
function NarciGenericKeyBindingButtonMixin:UnbindKey()
self:ResetVisualAndScript();
if self.defaultKey then
self.ButtonText:SetText(self.defaultKey or NOT_BOUND);
NarcissusDB[self.actionName] = self.defaultKey;
elseif self.actionName then
ClearBindingKey(self.actionName);
end
end
function NarciGenericKeyBindingButtonMixin:OnClick(button)
ReleaseOverlay();
self.isOn = not self.isOn;
if button == "LeftButton" then
if self.isOn then
self.ButtonText:SetTextColor(0, 0, 0);
self.ButtonText:SetShadowColor(1, 1, 1);
self.ButtonText:SetShadowOffset(0.6, -0.6);
self.Background:SetColorTexture(0.8, 0.8, 0.8);
self:SetScript("OnKeyDown", self.onKeyDownFunc);
self:SetScript("OnKeyUp", self.onKeyUpFunc);
self:SetScript("OnEvent", KeyBingdingButton_OnEvent);
self:RegisterEvent("GLOBAL_MOUSE_DOWN");
self:SetPropagateKeyboardInput(false);
else
self:ExitKeyBinding();
end
else
self:UnbindKey();
self:ExitKeyBinding();
end
end
function NarciGenericKeyBindingButtonMixin:OnHide()
if self.isOn then
self:ResetVisualAndScript();
end
end
function NarciGenericKeyBindingButtonMixin:OnShow()
self:GetBindingKey();
end
NarciQuickFavoriteButtonMixin = {};
function NarciQuickFavoriteButtonMixin:SetIconSize(size)
self.iconSize = size;
self.Icon:SetSize(size, size);
self.Bling:SetSize(size, size);
self.Icon:SetTexCoord(0.5, 0.75, 0.25, 0.5);
self.favTooltip = Narci.L["Favorites Add"];
self.unfavTooltip = Narci.L["Favorites Remove"];
self.isFav = false;
end
function NarciQuickFavoriteButtonMixin:SetFavorite(isFavorite)
if isFavorite then
self.isFav = true;
self.Icon:SetTexCoord(0.75, 1, 0.25, 0.5);
self.Icon:SetAlpha(1);
else
self.isFav = false;
self.Icon:SetTexCoord(0.5, 0.75, 0.25, 0.5);
self.Icon:SetAlpha(0.4);
end
end
function NarciQuickFavoriteButtonMixin:PlayVisual()
self:StopAnimating();
if self.isFav then
self.Icon:SetTexCoord(0.75, 1, 0.25, 0.5);
self.parent.Star:Show();
self.Bling.animIn:Play();
else
self.Icon:SetTexCoord(0.5, 0.75, 0.25, 0.5);
self.parent.Star:Hide();
end
end
function NarciQuickFavoriteButtonMixin:OnEnter()
self.Icon:SetAlpha(1);
if self.isFav then
NarciTooltip:NewText(self, self.unfavTooltip, nil, nil, 1);
else
NarciTooltip:NewText(self, self.favTooltip, nil, nil, 1);
end
end
function NarciQuickFavoriteButtonMixin:OnLeave()
NarciTooltip:HideTooltip();
if not self.isFav then
self.Icon:SetAlpha(0.6);
end
end
function NarciQuickFavoriteButtonMixin:OnHide()
self:StopAnimating();
end
function NarciQuickFavoriteButtonMixin:OnMouseDown()
self.Icon:SetSize(self.iconSize - 2, self.iconSize - 2);
NarciTooltip:HideTooltip();
end
function NarciQuickFavoriteButtonMixin:OnMouseUp()
self.Icon:SetSize(self.iconSize, self.iconSize);
end
function NarciQuickFavoriteButtonMixin:OnDoubleClick()
end
NarciGenericInfoButtonMixin = {}; --Question Mark Button that displays extra info when moused-over
function NarciGenericInfoButtonMixin:OnEnter()
local c = self.HighlightColor;
if c then
self.Icon:SetVertexColor(c[1], c[2], c[3]);
else
self.Icon:SetVertexColor(0.8, 0.8, 0.8);
end
SetCursor("Interface/CURSOR/"..(self.cursorFile or "UnableQuestTurnIn.blp"));
local tooltip = self:GetTooltip();
if self.usePrivateTooltip then
tooltip:ShowButtonTooltip(self);
else
if tooltip and self.tooltipText then
if tooltip.SetOwner then
tooltip:SetOwner(self, "ANCHOR_NONE");
end
tooltip:SetPoint("TOPLEFT", self, "TOPRIGHT", self.tooltipOffsetX or 4, 0);
if tooltip.SetPadding then
tooltip:SetPadding(5, 5, 5, 5);
end
if tooltip.AddLine then
tooltip:AddLine(self.tooltipText, 1, 1, 1, 1, true);
elseif tooltip.SetTooltipText then
tooltip:SetTooltipText(self.tooltipText, 1, 1, 1);
end
tooltip:Show();
--tooltip.TextLeft1:SetSpacing(2);
--tooltip:SetMinimumWidth(300);
end
end
end
function NarciGenericInfoButtonMixin:OnLeave()
local c = self.NormalColor;
if c then
self.Icon:SetVertexColor(c[1], c[2], c[3]);
else
self.Icon:SetVertexColor(0.4, 0.4, 0.4);
end
ResetCursor();
local tooltip = self:GetTooltip();
if tooltip then
tooltip:Hide();
end
end
function NarciGenericInfoButtonMixin:GetTooltip()
if self.usePrivateTooltip then
return _G["NarciTooltip"];
elseif self.tooltipName then
return _G[self.tooltipName]
else
return self.tooltip
end
end
function NarciGenericInfoButtonMixin:SetNormalColor(r, g, b)
self.NormalColor = {r, g, b};
self.Icon:SetVertexColor(r, g, b);
end
function NarciGenericInfoButtonMixin:SetHighlightColor(r, g, b)
self.HighlightColor = {r, g, b};
end
function NarciGenericInfoButtonMixin:SetVisualType(visualType)
--type: 1 (no shadow) 2 (shadow)
if visualType == 2 then
self.Icon:SetTexCoord(0.5, 1, 0, 1);
else
self.Icon:SetTexCoord(0, 0.5, 0, 1);
end
end
function NarciGenericInfoButtonMixin:SetCursorColor(colorType)
if colorType == 2 then
self.cursorFile = "questrepeatable.blp";
else
self.cursorFile = nil;
end
end
function NarciGenericInfoButtonMixin:SetUsePrivateTooltip(state, tooltipText)
self.usePrivateTooltip = state;
if tooltipText then
if state then
self.tooltipDescription = tooltipText;
else
self:SetTooltipText(tooltipText);
end
end
end
function NarciGenericInfoButtonMixin:SetTooltipText(tooltipText)
self.tooltipText = tooltipText;
end
TEMPS = nil;