Files
Andrew6810 60ef8a38af init
2022-10-21 07:09:01 -07:00

388 lines
12 KiB
Lua

--[[
Credit to Jaslm, most of this code is his from the addon ColorPickerPlus
]]
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local B = E:GetModule("Blizzard")
local S = E:GetModule("Skins")
--Lua functions
local strlen, strjoin, gsub = strlen, strjoin, gsub
local tonumber, floor, strsub, wipe = tonumber, floor, strsub, wipe
--WoW API / Variables
local CreateFrame = CreateFrame
local IsAddOnLoaded = IsAddOnLoaded
local CALENDAR_COPY_EVENT, CALENDAR_PASTE_EVENT = CALENDAR_COPY_EVENT, CALENDAR_PASTE_EVENT
local CLASS, DEFAULT = CLASS, DEFAULT
local colorBuffer = {}
local function alphaValue(num)
return num and floor(((1 - num) * 100) + .05) or 0
end
local function UpdateAlphaText(alpha)
if not alpha then alpha = alphaValue(OpacitySliderFrame:GetValue()) end
ColorPPBoxA:SetText(alpha)
end
local function UpdateAlpha(tbox)
local num = tbox:GetNumber()
if num > 100 then
tbox:SetText(100)
num = 100
end
OpacitySliderFrame:SetValue(1 - (num / 100))
end
local function expandFromThree(r, g, b)
return strjoin("",r,r,g,g,b,b)
end
local function extendToSix(str)
for _=1, 6-strlen(str) do str=str..0 end
return str
end
local function GetHexColor(box)
local rgb, rgbSize = box:GetText(), box:GetNumLetters()
if rgbSize == 3 then
rgb = gsub(rgb, "(%x)(%x)(%x)$", expandFromThree)
elseif rgbSize < 6 then
rgb = gsub(rgb, "(.+)$", extendToSix)
end
local r, g, b = tonumber(strsub(rgb,0,2),16) or 0, tonumber(strsub(rgb,3,4),16) or 0, tonumber(strsub(rgb,5,6),16) or 0
return r/255, g/255, b/255
end
local function UpdateColorTexts(r, g, b, box)
if not (r and g and b) then
r, g, b = ColorPickerFrame:GetColorRGB()
if box then
if box == ColorPPBoxH then
r, g, b = GetHexColor(box)
else
local num = box:GetNumber()
if num > 255 then num = 255 end
local c = num/255
if box == ColorPPBoxR then
r = c
elseif box == ColorPPBoxG then
g = c
elseif box == ColorPPBoxB then
b = c
end
end
end
end
-- we want those /255 values
r, g, b = r*255, g*255, b*255
ColorPPBoxH:SetText(string.format("%.2x%.2x%.2x", r, g, b))
ColorPPBoxR:SetText(r)
ColorPPBoxG:SetText(g)
ColorPPBoxB:SetText(b)
end
local function UpdateColor(box)
if box:GetID() == 4 and box:GetNumLetters() ~= 6 then return else UpdateColorTexts(nil, nil, nil, box) end
local r, g, b = GetHexColor(ColorPPBoxH)
ColorPickerFrame:SetColorRGB(r, g, b)
ColorSwatch:SetTexture(r, g, b)
end
local function ColorPPBoxA_SetFocus()
ColorPPBoxA:SetFocus()
end
local function ColorPPBoxR_SetFocus()
ColorPPBoxR:SetFocus()
end
local delayWait, delayFunc = 0.15
local function delayCall()
if delayFunc then
delayFunc()
delayFunc = nil
end
end
local function onColorSelect(frame, r, g, b)
if frame.noColorCallback then return end
ColorSwatch:SetTexture(r, g, b)
UpdateColorTexts(r, g, b)
if not frame:IsVisible() then
delayCall()
elseif not delayFunc then
delayFunc = ColorPickerFrame.func
E:Delay(delayWait, delayCall)
end
end
local function onValueChanged(frame, value)
local alpha = alphaValue(value)
if frame.lastAlpha ~= alpha then
frame.lastAlpha = alpha
UpdateAlphaText(alpha)
if not ColorPickerFrame:IsVisible() then
delayCall()
else
local opacityFunc = ColorPickerFrame.opacityFunc
if delayFunc and (delayFunc ~= opacityFunc) then
delayFunc = opacityFunc
elseif not delayFunc then
delayFunc = opacityFunc
E:Delay(delayWait, delayCall)
end
end
end
end
function B:EnhanceColorPicker()
if IsAddOnLoaded("ColorPickerPlus") then return end
--Skin the default frame, move default buttons into place
ColorPickerFrame:SetClampedToScreen(true)
ColorPickerFrame:SetTemplate("Transparent")
ColorPickerFrameHeader:SetTexture()
ColorPickerFrameHeader:ClearAllPoints()
ColorPickerFrameHeader:Point("TOP", ColorPickerFrame, 0, 0)
ColorPickerCancelButton:ClearAllPoints()
ColorPickerOkayButton:ClearAllPoints()
ColorPickerCancelButton:Point("BOTTOMRIGHT", ColorPickerFrame, "BOTTOMRIGHT", -6, 6)
ColorPickerCancelButton:Point("BOTTOMLEFT", ColorPickerFrame, "BOTTOM", 0, 6)
ColorPickerOkayButton:Point("BOTTOMLEFT", ColorPickerFrame,"BOTTOMLEFT", 6,6)
ColorPickerOkayButton:Point("RIGHT", ColorPickerCancelButton,"LEFT", -4,0)
S:HandleSliderFrame(OpacitySliderFrame)
S:HandleButton(ColorPickerOkayButton)
S:HandleButton(ColorPickerCancelButton)
ColorPickerFrame:HookScript("OnShow", function(frame)
-- get color that will be replaced
local r, g, b = frame:GetColorRGB()
ColorPPOldColorSwatch:SetTexture(r,g,b)
-- show/hide the alpha box
if frame.hasOpacity then
ColorPPBoxA:Show()
ColorPPBoxLabelA:Show()
ColorPPBoxH:SetScript("OnTabPressed", ColorPPBoxA_SetFocus)
UpdateAlphaText()
UpdateColorTexts()
frame:Width(405)
else
ColorPPBoxA:Hide()
ColorPPBoxLabelA:Hide()
ColorPPBoxH:SetScript("OnTabPressed", ColorPPBoxR_SetFocus)
UpdateColorTexts()
frame:Width(345)
end
-- Memory Fix, Colorpicker will call the self.func() 100x per second, causing fps/memory issues,
-- We overwrite these two scripts and set a limit on how often we allow a call their update functions
OpacitySliderFrame:SetScript("OnValueChanged", onValueChanged)
frame:SetScript("OnColorSelect", onColorSelect)
end)
-- make the Color Picker dialog a bit taller, to make room for edit boxes
ColorPickerFrame:Height(ColorPickerFrame:GetHeight() + 40)
-- move the Color Swatch
ColorSwatch:ClearAllPoints()
ColorSwatch:Point("TOPLEFT", ColorPickerFrame, "TOPLEFT", 215, -45)
-- add Color Swatch for original color
local t = ColorPickerFrame:CreateTexture("ColorPPOldColorSwatch")
local w, h = ColorSwatch:GetSize()
t:Size(w*0.75,h*0.75)
t:SetTexture(0,0,0)
-- OldColorSwatch to appear beneath ColorSwatch
t:SetDrawLayer("BORDER")
t:Point("BOTTOMLEFT", ColorSwatch, "TOPRIGHT", -(w/2), -(h/3))
-- add Color Swatch for the copied color
t = ColorPickerFrame:CreateTexture("ColorPPCopyColorSwatch")
t:SetTexture(0,0,0)
t:Size(w,h)
t:Hide()
-- add copy button to the ColorPickerFrame
local b = CreateFrame("Button", "ColorPPCopy", ColorPickerFrame, "UIPanelButtonTemplate")
S:HandleButton(b)
b:SetText(CALENDAR_COPY_EVENT)
b:Width(60)
b:Height(22)
b:Point("TOPLEFT", ColorSwatch, "BOTTOMLEFT", 0, -5)
-- copy color into buffer on button click
b:SetScript("OnClick", function()
-- copy current dialog colors into buffer
colorBuffer.r, colorBuffer.g, colorBuffer.b = ColorPickerFrame:GetColorRGB()
-- enable Paste button and display copied color into swatch
ColorPPPaste:Enable()
ColorPPCopyColorSwatch:SetTexture(colorBuffer.r, colorBuffer.g, colorBuffer.b)
ColorPPCopyColorSwatch:Show()
colorBuffer.a = (ColorPickerFrame.hasOpacity and OpacitySliderFrame:GetValue()) or nil
end)
--class color button
b = CreateFrame("Button", "ColorPPClass", ColorPickerFrame, "UIPanelButtonTemplate")
b:SetText(CLASS)
S:HandleButton(b)
b:Width(80)
b:Height(22)
b:Point("TOP", ColorPPCopy, "BOTTOMRIGHT", 0, -7)
b:SetScript("OnClick", function()
local color = E.media.herocolor
ColorPickerFrame:SetColorRGB(color.r, color.g, color.b)
ColorSwatch:SetTexture(color.r, color.g, color.b)
if ColorPickerFrame.hasOpacity then
OpacitySliderFrame:SetValue(0)
end
end)
-- add paste button to the ColorPickerFrame
b = CreateFrame("Button", "ColorPPPaste", ColorPickerFrame, "UIPanelButtonTemplate")
b:SetText(CALENDAR_PASTE_EVENT)
S:HandleButton(b)
b:Width(60)
b:Height(22)
b:Point("TOPLEFT", ColorPPCopy, "TOPRIGHT", 2, 0)
b:Disable() -- enable when something has been copied
-- paste color on button click, updating frame components
b:SetScript("OnClick", function()
ColorPickerFrame:SetColorRGB(colorBuffer.r, colorBuffer.g, colorBuffer.b)
ColorSwatch:SetTexture(colorBuffer.r, colorBuffer.g, colorBuffer.b)
if ColorPickerFrame.hasOpacity then
if colorBuffer.a then --color copied had an alpha value
OpacitySliderFrame:SetValue(colorBuffer.a)
end
end
end)
-- add defaults button to the ColorPickerFrame
b = CreateFrame("Button", "ColorPPDefault", ColorPickerFrame, "UIPanelButtonTemplate")
b:SetText(DEFAULT)
S:HandleButton(b)
b:Width(80)
b:Height(22)
b:Point("TOPLEFT", ColorPPClass, "BOTTOMLEFT", 0, -7)
b:Disable() -- enable when something has been copied
b:SetScript("OnHide", function(btn)
if btn.colors then
wipe(btn.colors)
end
end)
b:SetScript("OnShow", function(btn)
if btn.colors then
btn:Enable()
else
btn:Disable()
end
end)
-- paste color on button click, updating frame components
b:SetScript("OnClick", function(btn)
local colors = btn.colors
ColorPickerFrame:SetColorRGB(colors.r, colors.g, colors.b)
ColorSwatch:SetTexture(colors.r, colors.g, colors.b)
if ColorPickerFrame.hasOpacity then
if colors.a then
OpacitySliderFrame:SetValue(colors.a)
end
end
end)
-- position Color Swatch for copy color
ColorPPCopyColorSwatch:Point("BOTTOM", ColorPPPaste, "TOP", 0, 10)
-- move the Opacity Slider Frame to align with bottom of Copy ColorSwatch
OpacitySliderFrame:ClearAllPoints()
OpacitySliderFrame:Point("BOTTOM", ColorPPDefault, "BOTTOM", 0, 0)
OpacitySliderFrame:Point("RIGHT", ColorPickerFrame, "RIGHT", -35, 18)
-- set up edit box frames and interior label and text areas
local boxes = {"R", "G", "B", "H", "A"}
for i = 1, #boxes do
local rgb = boxes[i]
local box = CreateFrame("EditBox", "ColorPPBox"..rgb, ColorPickerFrame, "InputBoxTemplate")
box:Point("TOP", ColorPickerWheel, "BOTTOM", 0, -15)
box:SetFrameStrata("DIALOG")
box:SetAutoFocus(false)
box:SetTextInsets(0,7,0,0)
box:SetJustifyH("RIGHT")
box:Height(24)
box:SetID(i)
S:HandleEditBox(box)
-- hex entry box
if i == 4 then
box:SetMaxLetters(6)
box:Width(56)
box:SetNumeric(false)
else
box:SetMaxLetters(3)
box:Width(40)
box:SetNumeric(true)
end
-- label
local label = box:CreateFontString("ColorPPBoxLabel"..rgb, "ARTWORK", "GameFontNormalSmall")
label:Point("RIGHT", box, "LEFT", -5, 0)
label:SetText(i == 4 and "#" or rgb)
label:SetTextColor(1, 1, 1)
-- set up scripts to handle event appropriately
if i == 5 then
box:SetScript("OnEscapePressed", function(self) self:ClearFocus() UpdateAlphaText() end)
box:SetScript("OnEnterPressed", function(self) self:ClearFocus() UpdateAlphaText() end)
box:SetScript("OnTextChanged", UpdateAlpha)
else
box:SetScript("OnEscapePressed", function(self) self:ClearFocus() UpdateColorTexts() end)
box:SetScript("OnEnterPressed", function(self) self:ClearFocus() UpdateColorTexts() end)
box:SetScript("OnTextChanged", UpdateColor)
end
box:SetScript("OnEditFocusGained", function(eb) eb:SetCursorPosition(0) eb:HighlightText() end)
box:SetScript("OnEditFocusLost", function(eb) eb:HighlightText(0,0) end)
box:SetScript("OnTextSet", box.ClearFocus)
box:Show()
end
-- finish up with placement
ColorPPBoxA:Point("RIGHT", OpacitySliderFrame, "RIGHT", 10, 0)
ColorPPBoxH:Point("RIGHT", ColorPPDefault, "RIGHT", -10, 0)
ColorPPBoxB:Point("RIGHT", ColorPPDefault, "LEFT", -40, 0)
ColorPPBoxG:Point("RIGHT", ColorPPBoxB, "LEFT", -25, 0)
ColorPPBoxR:Point("RIGHT", ColorPPBoxG, "LEFT", -25, 0)
-- define the order of tab cursor movement
ColorPPBoxR:SetScript("OnTabPressed", function() ColorPPBoxG:SetFocus() end)
ColorPPBoxG:SetScript("OnTabPressed", function() ColorPPBoxB:SetFocus() end)
ColorPPBoxB:SetScript("OnTabPressed", function() ColorPPBoxH:SetFocus() end)
ColorPPBoxA:SetScript("OnTabPressed", function() ColorPPBoxR:SetFocus() end)
-- make the color picker movable.
local mover = CreateFrame("Frame", nil, ColorPickerFrame)
mover:Point("TOPLEFT", ColorPickerFrame, "TOP", -60, 0)
mover:Point("BOTTOMRIGHT", ColorPickerFrame, "TOP", 60, -15)
mover:SetScript("OnMouseDown", function() ColorPickerFrame:StartMoving() end)
mover:SetScript("OnMouseUp", function() ColorPickerFrame:StopMovingOrSizing() end)
mover:EnableMouse(true)
ColorPickerFrame:SetUserPlaced(true)
ColorPickerFrame:EnableKeyboard(false)
end