mirror of
https://github.com/brues-code/pfUI.git
synced 2026-09-22 07:36:56 +00:00
0214eebf36
Due to crashes/freezes while moving some frames, one possible reason could be that pfUI was using OnMouseDown and OnMouseUp to run its frame-moving code. I have noticed better performance when using the intended functions, OnDragStart and OnDragStop to move frames. This commit changes every occurrence of such functions and splits drag and click into seperate functions where required.
450 lines
14 KiB
Lua
450 lines
14 KiB
Lua
pfUI:RegisterModule("share", "vanilla:tbc", function ()
|
|
local function serialize(tbl, comp, name, ignored, spacing)
|
|
local spacing = spacing or ""
|
|
local match = nil
|
|
local tname = ( spacing == "" and "" or "[\"" ) .. name .. ( spacing == "" and "" or "\"]" )
|
|
local str = spacing .. tname .. " = {\n"
|
|
|
|
for k, v in pairs(tbl) do
|
|
if not ( ignored[k] and spacing == "" ) and ( not comp or not comp[k] or comp[k] ~= tbl[k] ) then
|
|
if type(v) == "table" then
|
|
local result = serialize(tbl[k], comp and comp[k], k, ignored, spacing .. " ")
|
|
if result then
|
|
match = true
|
|
str = str .. result
|
|
end
|
|
elseif type(v) == "string" then
|
|
match = true
|
|
str = str .. spacing .. " [\""..k.."\"] = \"".. string.gsub(v, "\\", "\\\\") .."\",\n"
|
|
elseif type(v) == "number" then
|
|
match = true
|
|
str = str .. spacing .. " [\""..k.."\"] = ".. string.gsub(v, "\\", "\\\\") ..",\n"
|
|
end
|
|
end
|
|
end
|
|
|
|
str = str .. spacing .. "}" .. ( spacing == "" and "" or "," ) .. "\n"
|
|
return match and str or nil
|
|
end
|
|
|
|
local function compress(input)
|
|
-- based on Rochet2's lzw compression
|
|
if type(input) ~= "string" then
|
|
return nil
|
|
end
|
|
local len = strlen(input)
|
|
if len <= 1 then
|
|
return "u"..input
|
|
end
|
|
|
|
local dict = {}
|
|
for i = 0, 255 do
|
|
local ic, iic = strchar(i), strchar(i, 0)
|
|
dict[ic] = iic
|
|
end
|
|
local a, b = 0, 1
|
|
|
|
local result = {"c"}
|
|
local resultlen = 1
|
|
local n = 2
|
|
local word = ""
|
|
for i = 1, len do
|
|
local c = strsub(input, i, i)
|
|
local wc = word..c
|
|
if not dict[wc] then
|
|
local write = dict[word]
|
|
if not write then
|
|
return nil
|
|
end
|
|
result[n] = write
|
|
resultlen = resultlen + strlen(write)
|
|
n = n+1
|
|
if len <= resultlen then
|
|
return "u"..input
|
|
end
|
|
local str = wc
|
|
if a >= 256 then
|
|
a, b = 0, b+1
|
|
if b >= 256 then
|
|
dict = {}
|
|
b = 1
|
|
end
|
|
end
|
|
dict[str] = strchar(a,b)
|
|
a = a+1
|
|
word = c
|
|
else
|
|
word = wc
|
|
end
|
|
end
|
|
result[n] = dict[word]
|
|
resultlen = resultlen+strlen(result[n])
|
|
n = n+1
|
|
if len <= resultlen then
|
|
return "u"..input
|
|
end
|
|
return table.concat(result)
|
|
end
|
|
|
|
local function decompress(input)
|
|
-- based on Rochet2's lzw compression
|
|
if type(input) ~= "string" or strlen(input) < 1 then
|
|
return nil
|
|
end
|
|
|
|
local control = strsub(input, 1, 1)
|
|
if control == "u" then
|
|
return strsub(input, 2)
|
|
elseif control ~= "c" then
|
|
return nil
|
|
end
|
|
input = strsub(input, 2)
|
|
local len = strlen(input)
|
|
|
|
if len < 2 then
|
|
return nil
|
|
end
|
|
|
|
local dict = {}
|
|
for i = 0, 255 do
|
|
local ic, iic = strchar(i), strchar(i, 0)
|
|
dict[iic] = ic
|
|
end
|
|
|
|
local a, b = 0, 1
|
|
|
|
local result = {}
|
|
local n = 1
|
|
local last = strsub(input, 1, 2)
|
|
result[n] = dict[last]
|
|
n = n+1
|
|
for i = 3, len, 2 do
|
|
local code = strsub(input, i, i+1)
|
|
local lastStr = dict[last]
|
|
if not lastStr then
|
|
return nil
|
|
end
|
|
local toAdd = dict[code]
|
|
if toAdd then
|
|
result[n] = toAdd
|
|
n = n+1
|
|
local str = lastStr..strsub(toAdd, 1, 1)
|
|
if a >= 256 then
|
|
a, b = 0, b+1
|
|
if b >= 256 then
|
|
dict = {}
|
|
b = 1
|
|
end
|
|
end
|
|
dict[strchar(a,b)] = str
|
|
a = a+1
|
|
else
|
|
local str = lastStr..strsub(lastStr, 1, 1)
|
|
result[n] = str
|
|
n = n+1
|
|
if a >= 256 then
|
|
a, b = 0, b+1
|
|
if b >= 256 then
|
|
dict = {}
|
|
b = 1
|
|
end
|
|
end
|
|
dict[strchar(a,b)] = str
|
|
a = a+1
|
|
end
|
|
last = code
|
|
end
|
|
return table.concat(result)
|
|
end
|
|
|
|
local function enc(to_encode)
|
|
local index_table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
|
local bit_pattern = ''
|
|
local encoded = ''
|
|
local trailing = ''
|
|
|
|
for i = 1, string.len(to_encode) do
|
|
local remaining = tonumber(string.byte(string.sub(to_encode, i, i)))
|
|
local bin_bits = ''
|
|
for i = 7, 0, -1 do
|
|
local current_power = math.pow(2, i)
|
|
if remaining >= current_power then
|
|
bin_bits = bin_bits .. '1'
|
|
remaining = remaining - current_power
|
|
else
|
|
bin_bits = bin_bits .. '0'
|
|
end
|
|
end
|
|
bit_pattern = bit_pattern .. bin_bits
|
|
end
|
|
|
|
if mod(string.len(bit_pattern), 3) == 2 then
|
|
trailing = '=='
|
|
bit_pattern = bit_pattern .. '0000000000000000'
|
|
elseif mod(string.len(bit_pattern), 3) == 1 then
|
|
trailing = '='
|
|
bit_pattern = bit_pattern .. '00000000'
|
|
end
|
|
|
|
local count = 0
|
|
for i = 1, string.len(bit_pattern), 6 do
|
|
local byte = string.sub(bit_pattern, i, i+5)
|
|
local offset = tonumber(tonumber(byte, 2))
|
|
encoded = encoded .. string.sub(index_table, offset+1, offset+1)
|
|
count = count + 1
|
|
if count >= 92 then
|
|
encoded = encoded .. "\n"
|
|
count = 0
|
|
end
|
|
end
|
|
|
|
return string.sub(encoded, 1, -1 - string.len(trailing)) .. trailing
|
|
end
|
|
|
|
local function dec(to_decode)
|
|
local index_table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
|
local padded = gsub(to_decode,"%s", "")
|
|
local unpadded = gsub(padded,"=", "")
|
|
local bit_pattern = ''
|
|
local decoded = ''
|
|
|
|
to_decode = gsub(to_decode,"\n", "")
|
|
to_decode = gsub(to_decode," ", "")
|
|
|
|
for i = 1, string.len(unpadded) do
|
|
local char = string.sub(to_decode, i, i)
|
|
local offset, _ = string.find(index_table, char)
|
|
if offset == nil then return nil end
|
|
|
|
local remaining = tonumber(offset-1)
|
|
local bin_bits = ''
|
|
for i = 7, 0, -1 do
|
|
local current_power = math.pow(2, i)
|
|
if remaining >= current_power then
|
|
bin_bits = bin_bits .. '1'
|
|
remaining = remaining - current_power
|
|
else
|
|
bin_bits = bin_bits .. '0'
|
|
end
|
|
end
|
|
|
|
bit_pattern = bit_pattern .. string.sub(bin_bits, 3)
|
|
end
|
|
|
|
for i = 1, string.len(bit_pattern), 8 do
|
|
local byte = string.sub(bit_pattern, i, i+7)
|
|
decoded = decoded .. strchar(tonumber(byte, 2))
|
|
end
|
|
|
|
local padding_length = string.len(padded)-string.len(unpadded)
|
|
|
|
if (padding_length == 1 or padding_length == 2) then
|
|
decoded = string.sub(decoded,1,-2)
|
|
end
|
|
|
|
return decoded
|
|
end
|
|
|
|
do -- Window
|
|
local f = CreateFrame("Frame", "pfShare", UIParent)
|
|
f:Hide()
|
|
f:SetPoint("CENTER", 0, 0)
|
|
f:SetWidth(580)
|
|
f:SetHeight(420)
|
|
f:SetMovable(true)
|
|
f:EnableMouse(true)
|
|
f:RegisterForDrag("LeftButton")
|
|
f:SetScript("OnDragStart", function() f:StartMoving() end)
|
|
f:SetScript("OnDragStop", function() f:StopMovingOrSizing() end)
|
|
|
|
f:SetScript("OnShow", function()
|
|
if pfUI.gui and pfUI.gui:IsShown() then
|
|
f.hadGUI = true
|
|
pfUI.gui:Hide()
|
|
else
|
|
f.hadGUI = nil
|
|
end
|
|
end)
|
|
|
|
f:SetScript("OnHide", function()
|
|
if f.hadGUI then
|
|
pfUI.gui:Show()
|
|
end
|
|
end)
|
|
|
|
CreateBackdrop(f, nil, true, 0.8)
|
|
CreateBackdropShadow(f)
|
|
table.insert(UISpecialFrames, "pfShare")
|
|
|
|
do -- Edit Box
|
|
f.scroll = pfUI.api.CreateScrollFrame("pfShareScroll", f)
|
|
f.scroll:SetPoint("TOPLEFT", f, "TOPLEFT", 10, -30)
|
|
f.scroll:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -10, 50)
|
|
f.scroll:SetWidth(560)
|
|
f.scroll:SetHeight(400)
|
|
|
|
f.scroll.backdrop = CreateFrame("Frame", "pfShareScrollBackdrop", f.scroll)
|
|
f.scroll.backdrop:SetFrameLevel(1)
|
|
f.scroll.backdrop:SetPoint("TOPLEFT", f.scroll, "TOPLEFT", -5, 5)
|
|
f.scroll.backdrop:SetPoint("BOTTOMRIGHT", f.scroll, "BOTTOMRIGHT", 5, -5)
|
|
pfUI.api.CreateBackdrop(f.scroll.backdrop, nil, true)
|
|
|
|
f.scroll.text = CreateFrame("EditBox", "pfShareEditBox", f.scroll)
|
|
f.scroll.text.bg = f.scroll.text:CreateTexture(nil, "OVERLAY")
|
|
f.scroll.text.bg:SetAllPoints(f.scroll.text)
|
|
f.scroll.text.bg:SetTexture(1,1,1,.05)
|
|
f.scroll.text:SetMultiLine(true)
|
|
f.scroll.text:SetWidth(560)
|
|
f.scroll.text:SetHeight(400)
|
|
f.scroll.text:SetAllPoints(f.scroll)
|
|
f.scroll.text:SetTextInsets(15,15,15,15)
|
|
f.scroll.text:SetFont(pfUI.media["font:RobotoMono.ttf"], 9)
|
|
f.scroll.text:SetAutoFocus(false)
|
|
f.scroll.text:SetJustifyH("LEFT")
|
|
f.scroll.text:SetScript("OnEscapePressed", function() this:ClearFocus() end)
|
|
f.scroll.text:SetScript("OnTextChanged", function()
|
|
this:GetParent():UpdateScrollChildRect()
|
|
this:GetParent():UpdateScrollState()
|
|
|
|
local _, error = loadstring(f.scroll.text:GetText())
|
|
if error or string.gsub(this:GetText(), " ", "") == "" then
|
|
f.loadButton:Disable()
|
|
f.loadButton.text:SetTextColor(1,.5,.5,1)
|
|
else
|
|
f.loadButton:Enable()
|
|
f.loadButton.text:SetTextColor(.5,1,.5,1)
|
|
end
|
|
|
|
local trydec = dec(this:GetText())
|
|
if string.gsub(this:GetText(), " ", "") == "" then
|
|
f.readButton.text:SetText(T["N/A"])
|
|
f.readButton:Disable()
|
|
elseif not trydec or trydec == "" then
|
|
f.readButton:Enable()
|
|
f.readButton.text:SetText(T["Encode"])
|
|
f.readButton.func = function()
|
|
local compressed = enc(compress(f.scroll.text:GetText()))
|
|
f.scroll.text:SetText(compressed)
|
|
end
|
|
else
|
|
f.readButton:Enable()
|
|
f.readButton.text:SetText(T["Decode"])
|
|
f.readButton.func = function()
|
|
local uncompressed = decompress(dec(f.scroll.text:GetText()))
|
|
f.scroll.text:SetText(uncompressed)
|
|
end
|
|
end
|
|
end)
|
|
f.scroll:SetScrollChild(f.scroll.text)
|
|
end
|
|
|
|
do -- button: close
|
|
f.closeButton = CreateFrame("Button", "pfShareClose", f)
|
|
f.closeButton:SetPoint("TOPRIGHT", -5, -5)
|
|
f.closeButton:SetHeight(12)
|
|
f.closeButton:SetWidth(12)
|
|
f.closeButton.texture = f.closeButton:CreateTexture("pfQuestionDialogCloseTex")
|
|
f.closeButton.texture:SetTexture(pfUI.media["img:close"])
|
|
f.closeButton.texture:ClearAllPoints()
|
|
f.closeButton.texture:SetAllPoints(f.closeButton)
|
|
f.closeButton.texture:SetVertexColor(1,.25,.25,1)
|
|
pfUI.api.SkinButton(f.closeButton, 1, .5, .5)
|
|
f.closeButton:SetScript("OnClick", function()
|
|
this:GetParent():Hide()
|
|
end)
|
|
end
|
|
|
|
do -- checkbox: ignore positions
|
|
f.ignorePosition = CreateFrame("CheckButton", "pfShareIgnorePosition", f, "UICheckButtonTemplate")
|
|
f.ignorePosition:SetNormalTexture("")
|
|
f.ignorePosition:SetPushedTexture("")
|
|
f.ignorePosition:SetHighlightTexture("")
|
|
CreateBackdrop(f.ignorePosition, nil, true)
|
|
f.ignorePosition:SetWidth(14)
|
|
f.ignorePosition:SetHeight(14)
|
|
f.ignorePosition:SetPoint("BOTTOMLEFT", 10, 10)
|
|
f.ignorePosition:SetChecked()
|
|
|
|
f.ignorePositionCaption = f.ignorePosition:CreateFontString("Status", "LOW", "GameFontNormal")
|
|
f.ignorePositionCaption:SetFont(pfUI.font_default, C.global.font_size + 2, "OUTLINE")
|
|
f.ignorePositionCaption:SetPoint("LEFT", f.ignorePosition, "RIGHT", 5, 0)
|
|
f.ignorePositionCaption:SetFontObject(GameFontWhite)
|
|
f.ignorePositionCaption:SetJustifyH("LEFT")
|
|
f.ignorePositionCaption:SetText(T["Ignore Layout"])
|
|
end
|
|
|
|
|
|
do -- button: load
|
|
f.loadButton = CreateFrame("Button", "pfShareLoad", f)
|
|
pfUI.api.SkinButton(f.loadButton)
|
|
f.loadButton:SetPoint("BOTTOMRIGHT", -5, 5)
|
|
f.loadButton:SetWidth(75)
|
|
f.loadButton:SetHeight(25)
|
|
f.loadButton.text = f.loadButton:CreateFontString("Caption", "LOW", "GameFontWhite")
|
|
f.loadButton.text:SetAllPoints(f.loadButton)
|
|
f.loadButton.text:SetFont(pfUI.font_default, pfUI_config.global.font_size, "OUTLINE")
|
|
f.loadButton.text:SetText(T["Import"])
|
|
f.loadButton:SetScript("OnClick", function()
|
|
local ImportConfig, error = loadstring(f.scroll.text:GetText())
|
|
if not error and f.scroll.text:GetText() ~= "" then
|
|
ImportConfig()
|
|
pfUI:LoadConfig()
|
|
CreateQuestionDialog(T["Some settings need to reload the UI to take effect.\nDo you want to reloadUI now?"], ReloadUI)
|
|
end
|
|
end)
|
|
end
|
|
|
|
do -- button: read
|
|
f.readButton = CreateFrame("Button", "pfShareDecode", f)
|
|
pfUI.api.SkinButton(f.readButton)
|
|
f.readButton:SetPoint("RIGHT", f.loadButton, "LEFT", -10, 0)
|
|
f.readButton:SetWidth(75)
|
|
f.readButton:SetHeight(25)
|
|
f.readButton.text = f.readButton:CreateFontString("Caption", "LOW", "GameFontWhite")
|
|
f.readButton.text:SetAllPoints(f.readButton)
|
|
f.readButton.text:SetFont(pfUI.font_default, pfUI_config.global.font_size, "OUTLINE")
|
|
f.readButton.text:SetText(T["N/A"])
|
|
f.readButton:SetScript("OnClick", function()
|
|
this.func()
|
|
end)
|
|
end
|
|
|
|
do -- button: export
|
|
f.exportButton = CreateFrame("Button", "pfShareExport", f)
|
|
pfUI.api.SkinButton(f.exportButton)
|
|
f.exportButton:SetPoint("RIGHT", f.readButton, "LEFT", -10, 0)
|
|
f.exportButton:SetWidth(75)
|
|
f.exportButton:SetHeight(25)
|
|
f.exportButton.text = f.exportButton:CreateFontString("Caption", "LOW", "GameFontWhite")
|
|
f.exportButton.text:SetAllPoints(f.exportButton)
|
|
f.exportButton.text:SetFont(pfUI.font_default, pfUI_config.global.font_size, "OUTLINE")
|
|
f.exportButton.text:SetText(T["Export"])
|
|
f.exportButton:SetScript("OnClick", function()
|
|
-- generate a default config
|
|
local myconfig = CopyTable(pfUI_config)
|
|
_G.pfUI_config = {}
|
|
pfUI:LoadConfig()
|
|
local defconfig = CopyTable(pfUI_config)
|
|
|
|
-- restore config and references
|
|
_G.pfUI_config = CopyTable(myconfig)
|
|
C = _G.pfUI_config
|
|
|
|
local ignored = {}
|
|
ignored["position"] = f.ignorePosition:GetChecked()
|
|
ignored["disabled"] = f.ignorePosition:GetChecked()
|
|
|
|
local compressed = enc(compress(serialize(myconfig, defconfig, "pfUI_config", ignored)))
|
|
f.scroll.text:SetText(compressed)
|
|
f.scroll.text.value = compressed
|
|
f.scroll:SetVerticalScroll(0)
|
|
end)
|
|
end
|
|
|
|
_G.SLASH_PFEXPORT1, _G.SLASH_PFEXPORT2, _G.SLASH_PFEXPORT3 = "/export", "/import", "/share"
|
|
function SlashCmdList.PFEXPORT(msg, editbox)
|
|
f:Show()
|
|
end
|
|
end
|
|
end)
|