mirror of
https://github.com/mr-rosh/ColorPickerPlus.git
synced 2026-11-10 20:17:38 +00:00
340 lines
12 KiB
Lua
340 lines
12 KiB
Lua
-- ColorPickerPlus hooks into the standard Color Picker to provide
|
|
-- 1. text entry for colors (RGB and hex values) and alpha (for opacity),
|
|
-- 2. copy to and paste from a dialog buffer,
|
|
-- 3. color swatches for the copied color and for the starting color.
|
|
--
|
|
-- Modified by SweedJesus (github.com/SweedJesus) to work with Ace2 for
|
|
-- 1.12 vanilla WoW servers (i.e. Nostalrius)
|
|
|
|
ColorPickerPlus = AceLibrary("AceAddon-2.0"):new(
|
|
"AceEvent-2.0",
|
|
"AceHook-2.1")
|
|
|
|
local ColorPickerPlus = ColorPickerPlus
|
|
local initialized = nil
|
|
local colorBuffer = {}
|
|
local editingText = nil
|
|
|
|
-- function ColorPickerPlus:OnInitialize()
|
|
-- self:RegisterChatCommand({ "/cpp" }, {
|
|
-- type = "group",
|
|
-- args = {
|
|
-- show = {
|
|
-- name = "Show frame",
|
|
-- desc = "Show the color picker frame",
|
|
-- type = "execute",
|
|
-- func = function()
|
|
-- ColorPickerFrame:Show()
|
|
-- end
|
|
-- }
|
|
-- }
|
|
-- })
|
|
-- end
|
|
|
|
function ColorPickerPlus:OnEnable()
|
|
-- Event received when starting, reloading or zoning
|
|
self:RegisterEvent("PLAYER_ENTERING_WORLD")
|
|
end
|
|
|
|
function ColorPickerPlus:PLAYER_ENTERING_WORLD()
|
|
if initialized then return end
|
|
initialized = true
|
|
|
|
-- hook the function to call when dialog first shows
|
|
ColorPickerPlus:HookScript(ColorPickerFrame, "OnShow", function(self)
|
|
ColorPickerPlus.hooks[ColorPickerFrame].OnShow(self)
|
|
local self = self
|
|
|
|
-- get color that will be replaced
|
|
local r, g, b = ColorPickerFrame:GetColorRGB()
|
|
ColorPPOldColorSwatch:SetTexture(r,g,b)
|
|
|
|
-- show/hide the alpha box
|
|
if ColorPickerFrame.hasOpacity then
|
|
ColorPPBoxA:Show()
|
|
ColorPPBoxLabelA:Show()
|
|
ColorPPBoxH:SetScript("OnTabPressed", function(self) ColorPPBoxA:SetFocus() end)
|
|
ColorPickerPlus:UpdateAlphaText()
|
|
|
|
else
|
|
ColorPPBoxA:Hide()
|
|
ColorPPBoxLabelA:Hide()
|
|
ColorPPBoxH:SetScript("OnTabPressed", function(self) ColorPPBoxR:SetFocus() end)
|
|
end
|
|
|
|
end)
|
|
|
|
-- hook the function to call on a change of color via ColorSelect
|
|
ColorPickerPlus:HookScript(ColorPickerFrame, "OnColorSelect", function(self)
|
|
ColorPickerPlus.hooks[ColorPickerFrame].OnColorSelect(self)
|
|
local self, arg1, arg2, arg3 = self;
|
|
if not editingText then
|
|
ColorPickerPlus:UpdateColorTexts()
|
|
end
|
|
end)
|
|
|
|
-- hook the function to call on a change of color via OpacitySlider
|
|
ColorPickerPlus:HookScript(OpacitySliderFrame, "OnValueChanged", function(self)
|
|
local self = self;
|
|
ColorPickerPlus.hooks[OpacitySliderFrame].OnValueChanged(self)
|
|
if not editingText then
|
|
ColorPickerPlus:UpdateAlphaText()
|
|
end
|
|
end)
|
|
|
|
-- make the Color Picker dialog a bit taller, to make room for edit boxes
|
|
local h = ColorPickerFrame:GetHeight()
|
|
ColorPickerFrame:SetHeight(h+40)
|
|
|
|
-- move the Color Swatch
|
|
ColorSwatch:ClearAllPoints()
|
|
ColorSwatch:SetPoint("TOPLEFT", ColorPickerFrame, "TOPLEFT", 230, -45)
|
|
|
|
-- add Color Swatch for original color
|
|
local t = ColorPickerFrame:CreateTexture("ColorPPOldColorSwatch")
|
|
local w, h = ColorSwatch:GetWidth(), ColorSwatch:GetHeight()
|
|
t:SetWidth(w*0.75)
|
|
t:SetHeight(h*0.75)
|
|
t:SetTexture(0,0,0)
|
|
-- OldColorSwatch to appear beneath ColorSwatch
|
|
t:SetDrawLayer("BORDER")
|
|
t:SetPoint("BOTTOMLEFT", "ColorSwatch", "TOPRIGHT", -(w/2), -(h/3))
|
|
|
|
-- add Color Swatch for the copied color
|
|
t = ColorPickerFrame:CreateTexture("ColorPPCopyColorSwatch")
|
|
t:SetWidth(w*0.75)
|
|
t:SetHeight(h*0.75)
|
|
t:SetTexture(0,0,0)
|
|
t:Show()
|
|
|
|
-- add copy button to the ColorPickerFrame
|
|
local b = CreateFrame("Button", "ColorPPCopy", ColorPickerFrame, "UIPanelButtonTemplate")
|
|
b:SetText("Copy")
|
|
b:SetWidth("70")
|
|
b:SetHeight("22")
|
|
b:SetScale(0.80)
|
|
b:SetPoint("TOPLEFT", "ColorSwatch", "BOTTOMLEFT", -15, -5)
|
|
|
|
-- copy color into buffer on button click
|
|
b:SetScript("OnClick", function(self)
|
|
|
|
if IsShiftKeyDown() == 1 then
|
|
-- this is a hidden utility for providing the WoW 0 to 1 based color numbers
|
|
local r, g, b = ColorPickerFrame:GetColorRGB()
|
|
print("ColorPickerPlus decimal -- r = "..string.format("%.3f", r).." g = "..string.format("%.3f", g).." b = "..string.format("%.3f",b))
|
|
return
|
|
end
|
|
|
|
-- copy current dialog colors into buffer
|
|
local c = colorBuffer
|
|
c.r, c.g, c.b = ColorPickerFrame:GetColorRGB()
|
|
|
|
-- enable Paste button and display copied color into swatch
|
|
ColorPPPaste:Enable()
|
|
local t = ColorPPCopyColorSwatch
|
|
t:SetTexture(c.r, c.g, c.b)
|
|
t:Show()
|
|
|
|
if ColorPickerFrame.hasOpacity then
|
|
c.a = OpacitySliderFrame:GetValue()
|
|
else
|
|
c.a = nil
|
|
end
|
|
end)
|
|
|
|
-- add paste button to the ColorPickerFrame
|
|
b = CreateFrame("Button", "ColorPPPaste", ColorPickerFrame, "UIPanelButtonTemplate")
|
|
b:SetText("Paste")
|
|
b:SetWidth("70")
|
|
b:SetHeight("22")
|
|
b:SetScale(0.8)
|
|
b:SetPoint("TOPLEFT", "ColorPPCopy", "BOTTOMLEFT", 0, -7)
|
|
b:Disable() -- enable when something has been copied
|
|
|
|
-- paste color on button click, updating frame components
|
|
b:SetScript("OnClick", function(self)
|
|
local c = colorBuffer
|
|
ColorPickerFrame:SetColorRGB(c.r, c.g, c.b)
|
|
ColorSwatch:SetTexture(c.r, c.g, c.b)
|
|
if ColorPickerFrame.hasOpacity then
|
|
if c.a then --color copied had an alpha value
|
|
OpacitySliderFrame:SetValue(c.a)
|
|
end
|
|
end
|
|
end)
|
|
|
|
-- locate Color Swatch for copy color
|
|
ColorPPCopyColorSwatch:SetPoint("LEFT", "ColorSwatch", "LEFT")
|
|
ColorPPCopyColorSwatch:SetPoint("TOP", "ColorPPPaste", "BOTTOM", 0, -5)
|
|
|
|
-- move the Opacity Slider Frame to align with bottom of Copy ColorSwatch
|
|
OpacitySliderFrame:ClearAllPoints()
|
|
OpacitySliderFrame:SetPoint("BOTTOM", "ColorPPCopyColorSwatch", "BOTTOM", 0, -3)
|
|
OpacitySliderFrame:SetPoint("RIGHT", "ColorPickerFrame", "RIGHT", -35, 0)
|
|
|
|
-- set up edit box frames and interior label and text areas
|
|
local boxes = { "R", "G", "B", "H", "A" }
|
|
for i = 1, table.getn(boxes) do
|
|
|
|
local rgb = boxes[i]
|
|
local box = CreateFrame("EditBox", "ColorPPBox"..rgb, ColorPickerFrame, "InputBoxTemplate")
|
|
box:SetID(i)
|
|
box:SetFrameStrata("DIALOG")
|
|
box:SetAutoFocus(false)
|
|
box:SetTextInsets(0,5,0,0)
|
|
box:SetJustifyH("RIGHT")
|
|
box:SetHeight(24)
|
|
|
|
if i == 4 then
|
|
-- Hex entry box
|
|
box:SetMaxLetters(6)
|
|
box:SetWidth(56)
|
|
box:SetNumeric(false)
|
|
else
|
|
box:SetMaxLetters(3)
|
|
box:SetWidth(32)
|
|
box:SetNumeric(true)
|
|
end
|
|
box:SetPoint("TOP", "ColorPickerWheel", "BOTTOM", 0, -15)
|
|
|
|
-- label
|
|
local label = box:CreateFontString("ColorPPBoxLabel"..rgb, "ARTWORK", "GameFontNormalSmall")
|
|
label:SetTextColor(1, 1, 1)
|
|
label:SetPoint("RIGHT", "ColorPPBox"..rgb, "LEFT", -5, 0)
|
|
if i == 4 then
|
|
-- Hex entry box
|
|
label:SetText("#")
|
|
else
|
|
label:SetText(rgb)
|
|
end
|
|
|
|
-- set up scripts to handle event appropriately
|
|
if i == 5 then
|
|
-- Alpha entry box
|
|
box:SetScript("OnEscapePressed", function() box:ClearFocus() ColorPickerPlus:UpdateAlphaText() end)
|
|
box:SetScript("OnEnterPressed", function() box:ClearFocus() ColorPickerPlus:UpdateAlphaText() end)
|
|
box:SetScript("OnTextChanged", function() ColorPickerPlus:UpdateAlpha(box) end)
|
|
else
|
|
box:SetScript("OnEscapePressed", function() box:ClearFocus() ColorPickerPlus:UpdateColorTexts() end)
|
|
box:SetScript("OnEnterPressed", function() box:ClearFocus() ColorPickerPlus:UpdateColorTexts() end)
|
|
box:SetScript("OnTextChanged", function() ColorPickerPlus:UpdateColor(box) end)
|
|
end
|
|
|
|
box:SetScript("OnEditFocusGained", function() --[[box:SetCursorPosition(0)]] box:HighlightText() end)
|
|
box:SetScript("OnEditFocusLost", function() box:HighlightText(0,0) end)
|
|
box:SetScript("OnTextSet", function() --[[self:ClearFocus()]] end)
|
|
--box:SetScript("OnChar", function(self, text) print(text) end)
|
|
box:Show()
|
|
end
|
|
|
|
-- finish up with placement
|
|
ColorPPBoxA:SetPoint("RIGHT", "OpacitySliderFrame", "RIGHT", 10, 0)
|
|
ColorPPBoxH:SetPoint("RIGHT", "ColorPPPaste", "RIGHT")
|
|
ColorPPBoxB:SetPoint("RIGHT", "ColorPPPaste", "LEFT", -40, 0)
|
|
ColorPPBoxG:SetPoint("RIGHT", "ColorPPBoxB", "LEFT", -25, 0)
|
|
ColorPPBoxR:SetPoint("RIGHT", "ColorPPBoxG", "LEFT", -25, 0)
|
|
|
|
-- define the order of tab cursor movement
|
|
ColorPPBoxR:SetScript("OnTabPressed", function(self) ColorPPBoxG:SetFocus() end)
|
|
ColorPPBoxG:SetScript("OnTabPressed", function(self) ColorPPBoxB:SetFocus() end)
|
|
ColorPPBoxB:SetScript("OnTabPressed", function(self) ColorPPBoxH:SetFocus() end)
|
|
ColorPPBoxA:SetScript("OnTabPressed", function(self) ColorPPBoxR:SetFocus() end)
|
|
-- tab cursor movement from Hex box depends on whether alpha field is visible, so set in OnShow
|
|
|
|
-- make the color picker movable.
|
|
local cpf = ColorPickerFrame
|
|
local mover = CreateFrame('Frame', nil, cpf)
|
|
mover:SetPoint('TOPLEFT', cpf, 'TOP', -60, 0)
|
|
mover:SetPoint('BOTTOMRIGHT', cpf, 'TOP', 60, -15)
|
|
mover:EnableMouse(true)
|
|
mover:SetScript('OnMouseDown', function() cpf:StartMoving() end)
|
|
mover:SetScript('OnMouseUp', function() cpf:StopMovingOrSizing() end)
|
|
mover:SetScript('OnHide', function() cpf:StopMovingOrSizing() end)
|
|
cpf:SetUserPlaced(true)
|
|
cpf:SetClampedToScreen(true) -- keep color picker frame on-screen
|
|
--cpf:SetClampRectInsets(120,-120,0,90) -- but allow for dragging partially off to sides and down
|
|
--local b = cfg:GetBackdrop()
|
|
--b.insets =
|
|
cpf:EnableKeyboard(false)
|
|
end
|
|
|
|
function ColorPickerPlus:UpdateColor(tbox)
|
|
|
|
local r, g, b = ColorPickerFrame:GetColorRGB()
|
|
|
|
local id = tbox:GetID()
|
|
|
|
if id == 1 then
|
|
r = string.format("%d", tbox:GetNumber())
|
|
if not r then r = 0 end
|
|
r = r/255
|
|
elseif id == 2 then
|
|
g = string.format("%d", tbox:GetNumber())
|
|
if not g then g = 0 end
|
|
g = g/255
|
|
elseif id == 3 then
|
|
b = string.format("%d", tbox:GetNumber())
|
|
if not b then b = 0 end
|
|
b = b/255
|
|
elseif id == 4 then
|
|
-- hex values
|
|
if tbox:GetNumLetters() == 6 then
|
|
local rgb = tbox:GetText()
|
|
|
|
r = tonumber(strsub(rgb, 0, 2), 16)
|
|
g = tonumber(strsub(rgb, 3, 4), 16)
|
|
b = tonumber(strsub(rgb, 5, 6), 16)
|
|
|
|
if not r then r = 0 else r = r/255 end
|
|
if not g then g = 0 else g = g/255 end
|
|
if not b then b = 0 else b = b/255 end
|
|
else return
|
|
end
|
|
end
|
|
|
|
-- This takes care of updating the hex entry when changing rgb fields and vice versa
|
|
ColorPickerPlus:UpdateColorTexts(r,g,b)
|
|
|
|
editingText = true
|
|
ColorPickerFrame:SetColorRGB(r, g, b)
|
|
ColorSwatch:SetTexture(r, g, b)
|
|
editingText = nil
|
|
|
|
end
|
|
|
|
|
|
function ColorPickerPlus:UpdateColorTexts(r, g, b)
|
|
if not r then r, g, b = ColorPickerFrame:GetColorRGB() end
|
|
|
|
r = math.floor (r*255 + 0.5)
|
|
g = math.floor (g*255 + 0.5)
|
|
b = math.floor (b*255 + 0.5)
|
|
|
|
ColorPPBoxR:SetText(string.format("%d", r))
|
|
ColorPPBoxG:SetText(string.format("%d", g))
|
|
ColorPPBoxB:SetText(string.format("%d", b))
|
|
ColorPPBoxH:SetText(string.format("%.2x", r)..string.format("%.2x",g)..string.format("%.2x", b))
|
|
end
|
|
|
|
function ColorPickerPlus:UpdateAlpha(tbox)
|
|
local a = tonumber(tbox:GetText())
|
|
if a > 100 then
|
|
a = 100
|
|
ColorPPBoxA:SetText(string.format("%d", a))
|
|
end
|
|
a = a/100
|
|
editingText = true
|
|
OpacitySliderFrame:SetValue(a)
|
|
editingText = nil
|
|
end
|
|
|
|
function ColorPickerPlus:UpdateAlphaText()
|
|
|
|
local a = OpacitySliderFrame:GetValue()
|
|
a = a * 100
|
|
a = math.floor(a +.05)
|
|
ColorPPBoxA:SetText(string.format("%d", a))
|
|
|
|
end
|
|
|