mirror of
https://github.com/Lacustat/Freewood-OctoWoW-Core.git
synced 2026-11-04 09:57:03 +00:00
0.1.233: Kanaele: breitere/einklappbare Seitenleiste, eigene Kategorien (anlegen, umbenennen, loeschen, verschieben), Kanal beitreten/verlassen, Kanaele verschieben, Datum und Tagestrenner im Chat [ungeprueft]
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016onJCSHLwhs9udhC9ZLzk9
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
33388f80d6
commit
c3f7db4d45
+538
-72
@@ -7,7 +7,7 @@ local UI = FW.UI
|
||||
local Ch = FW.Channels
|
||||
local CL = FW.ChatLog
|
||||
|
||||
local LEFT_W, RIGHT_W = 220, 220
|
||||
local WIDE_W, NARROW_W, RIGHT_W = 270, 56, 220
|
||||
local ROW = 24
|
||||
local MAX_BUBBLES = 60
|
||||
local LOG_LINES = 200
|
||||
@@ -58,10 +58,60 @@ end
|
||||
local G_date = _G.date
|
||||
local function TimeText(t)
|
||||
if not (t and G_date) then return "" end
|
||||
local ok, s = pcall(G_date, "%H:%M", t)
|
||||
local ok, s = pcall(G_date, "%d.%m. %H:%M", t)
|
||||
return ok and s or ""
|
||||
end
|
||||
|
||||
-- "Mo 02.11. 00:08"
|
||||
local function Stamp(t, L)
|
||||
if not (t and G_date) then return "" end
|
||||
local ok, tb = pcall(G_date, "*t", t)
|
||||
local wd = (ok and type(tb) == "table" and tb.wday and L["CHAT_WD" .. tb.wday]) or ""
|
||||
local ok2, s = pcall(G_date, "%d.%m. %H:%M", t)
|
||||
return wd .. " " .. (ok2 and s or "")
|
||||
end
|
||||
|
||||
local function DayKey(t)
|
||||
if not (t and G_date) then return "" end
|
||||
local ok, s = pcall(G_date, "%Y%m%d", t)
|
||||
return ok and s or ""
|
||||
end
|
||||
|
||||
local function DayText(t, L)
|
||||
if not (t and G_date) then return "" end
|
||||
local ok, tb = pcall(G_date, "*t", t)
|
||||
local wd = (ok and type(tb) == "table" and tb.wday and L["CHAT_WD" .. tb.wday]) or ""
|
||||
local ok2, s = pcall(G_date, "%d.%m.%Y", t)
|
||||
return wd .. " " .. (ok2 and s or "")
|
||||
end
|
||||
|
||||
-- Seitenleisten-Aufteilung (gespeichert im Konto)
|
||||
local BUILTIN = { "std", "other", "guild", "group", "whisper", "service" }
|
||||
local CHANNEL_CATS = { std = true, other = true, service = true }
|
||||
local tmpLayout = { order = {}, cats = {}, assign = {} }
|
||||
|
||||
local function Layout()
|
||||
local d = _G.FreewoodDB
|
||||
local l
|
||||
if type(d) == "table" then
|
||||
if type(d.chatLayout) ~= "table" then d.chatLayout = {} end
|
||||
l = d.chatLayout
|
||||
else
|
||||
l = tmpLayout
|
||||
end
|
||||
if type(l.order) ~= "table" then l.order = {} end
|
||||
if type(l.cats) ~= "table" then l.cats = {} end
|
||||
if type(l.assign) ~= "table" then l.assign = {} end
|
||||
local have = {}
|
||||
local k = 1
|
||||
while k <= table.getn(l.order) do have[l.order[k]] = true; k = k + 1 end
|
||||
k = 1
|
||||
while k <= table.getn(BUILTIN) do
|
||||
if not have[BUILTIN[k]] then l.order[table.getn(l.order) + 1] = BUILTIN[k] end
|
||||
k = k + 1
|
||||
end
|
||||
return l
|
||||
end
|
||||
|
||||
local function Build(content)
|
||||
local L = FW.L
|
||||
@@ -177,15 +227,258 @@ local function Build(content)
|
||||
menu:Show()
|
||||
end
|
||||
|
||||
------------------------------------------------------------------
|
||||
-- Kleine Bausteine: Listenmenue und Eingabefenster
|
||||
------------------------------------------------------------------
|
||||
local lmenu, lcatcher, ltitle, lbtns
|
||||
local function HideList()
|
||||
if lmenu then lmenu:Hide() end
|
||||
if lcatcher then lcatcher:Hide() end
|
||||
end
|
||||
local function ShowList(title, items)
|
||||
if not lmenu then
|
||||
lcatcher = CreateFrame("Button", nil, UIParent)
|
||||
lcatcher:SetAllPoints(UIParent)
|
||||
lcatcher:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
lcatcher:RegisterForClicks("LeftButtonUp", "RightButtonUp")
|
||||
lcatcher:SetScript("OnClick", HideList)
|
||||
lcatcher:Hide()
|
||||
lmenu = UI.CreatePanel(UIParent, "bgDeep", "gold")
|
||||
lmenu:SetWidth(280)
|
||||
lmenu:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
lmenu:SetFrameLevel(lcatcher:GetFrameLevel() + 5)
|
||||
lmenu:Hide()
|
||||
ltitle = UI.CreateLabel(lmenu, "", { size = 12, color = "gold" })
|
||||
ltitle:SetPoint("TOPLEFT", lmenu, "TOPLEFT", 10, -8)
|
||||
lbtns = {}
|
||||
end
|
||||
ltitle:SetText(title or "")
|
||||
local n = table.getn(items)
|
||||
local i = 1
|
||||
while i <= n do
|
||||
local b = lbtns[i]
|
||||
if not b then
|
||||
b = UI.CreateButton(lmenu, "", 264, 22, nil)
|
||||
b:SetPoint("TOPLEFT", lmenu, "TOPLEFT", 8, -28 - (i - 1) * 24)
|
||||
lbtns[i] = b
|
||||
end
|
||||
local it = items[i]
|
||||
b:SetLabel(it[1])
|
||||
b:SetScript("OnClick", function()
|
||||
HideList()
|
||||
it[2]()
|
||||
end)
|
||||
b:Show()
|
||||
i = i + 1
|
||||
end
|
||||
while lbtns[i] do lbtns[i]:Hide(); i = i + 1 end
|
||||
local h = 28 + n * 24 + 8
|
||||
lmenu:SetHeight(h)
|
||||
local x, y = GetCursorPosition()
|
||||
local sc = UIParent:GetEffectiveScale()
|
||||
lmenu:ClearAllPoints()
|
||||
if y / sc - h < 0 then
|
||||
lmenu:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", x / sc, y / sc)
|
||||
else
|
||||
lmenu:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", x / sc, y / sc)
|
||||
end
|
||||
lcatcher:Show()
|
||||
lmenu:Show()
|
||||
end
|
||||
|
||||
local dlg, dlgTitle, dlgL1, dlgL2, dlgE1, dlgE2, dlgOk
|
||||
local function ShowDialog(title, label1, label2, preset, onOk)
|
||||
if not dlg then
|
||||
dlg = UI.CreatePanel(UIParent, "bgDeep", "gold")
|
||||
dlg:SetSize(360, 190)
|
||||
dlg:SetPoint("CENTER", UIParent, "CENTER", 0, 100)
|
||||
dlg:SetFrameStrata("FULLSCREEN_DIALOG")
|
||||
dlg:Hide()
|
||||
dlgTitle = UI.CreateLabel(dlg, "", { font = "heading", size = 14, color = "gold" })
|
||||
dlgTitle:SetPoint("TOPLEFT", dlg, "TOPLEFT", 14, -12)
|
||||
local function MakeEdit(y)
|
||||
local lab = UI.CreateLabel(dlg, "", { size = 11, color = "textDim" })
|
||||
lab:SetPoint("TOPLEFT", dlg, "TOPLEFT", 14, y)
|
||||
local bx = UI.CreatePanel(dlg, "bg", "bronze")
|
||||
bx:SetPoint("TOPLEFT", dlg, "TOPLEFT", 12, y - 16)
|
||||
bx:SetPoint("TOPRIGHT", dlg, "TOPRIGHT", -12, y - 16)
|
||||
bx:SetHeight(26)
|
||||
local e = CreateFrame("EditBox", nil, bx)
|
||||
e:SetAutoFocus(false)
|
||||
e:SetPoint("TOPLEFT", bx, "TOPLEFT", 6, -3)
|
||||
e:SetPoint("BOTTOMRIGHT", bx, "BOTTOMRIGHT", -6, 3)
|
||||
e:SetMaxLetters(40)
|
||||
if not e:SetFont(UI.GetFontPath("body"), 12, "") then e:SetFont("Fonts\\FRIZQT__.TTF", 12, "") end
|
||||
e:SetTextColor(UI.Color("text"))
|
||||
e:SetScript("OnEscapePressed", function() dlg:Hide() end)
|
||||
return lab, bx, e
|
||||
end
|
||||
local bx1, bx2
|
||||
dlgL1, bx1, dlgE1 = MakeEdit(-42)
|
||||
dlgL2, bx2, dlgE2 = MakeEdit(-90)
|
||||
dlg.bx2 = bx2
|
||||
local function Ok()
|
||||
local fn = dlg.onOk
|
||||
local v1 = dlgE1:GetText() or ""
|
||||
local v2 = dlgE2:GetText() or ""
|
||||
dlg:Hide()
|
||||
if fn then fn(v1, v2) end
|
||||
end
|
||||
dlgE1:SetScript("OnEnterPressed", Ok)
|
||||
dlgE2:SetScript("OnEnterPressed", Ok)
|
||||
dlgOk = UI.CreateButton(dlg, L.CHAT_OK, 100, 26, Ok, "primary")
|
||||
dlgOk:SetPoint("BOTTOMRIGHT", dlg, "BOTTOMRIGHT", -12, 12)
|
||||
local cancel = UI.CreateButton(dlg, L.CHAT_CANCEL, 100, 26, function() dlg:Hide() end)
|
||||
cancel:SetPoint("RIGHT", dlgOk, "LEFT", -8, 0)
|
||||
end
|
||||
dlg.onOk = onOk
|
||||
dlgTitle:SetText(title)
|
||||
dlgL1:SetText(label1 or "")
|
||||
dlgE1:SetText(preset or "")
|
||||
if label2 then
|
||||
dlgL2:SetText(label2); dlgL2:Show(); dlg.bx2:Show(); dlgE2:Show()
|
||||
else
|
||||
dlgL2:Hide(); dlg.bx2:Hide(); dlgE2:Hide()
|
||||
end
|
||||
dlgE2:SetText("")
|
||||
dlg:Show()
|
||||
dlgE1:SetFocus()
|
||||
end
|
||||
|
||||
------------------------------------------------------------------
|
||||
-- Linke Spalte: Kategorien und Chats
|
||||
------------------------------------------------------------------
|
||||
local leftW = WIDE_W
|
||||
local narrow = false
|
||||
local visCats = {}
|
||||
local ApplyLayout
|
||||
|
||||
local left = UI.CreateScrollFrame(f)
|
||||
left:SetPoint("TOPLEFT", f, "TOPLEFT", 0, 0)
|
||||
left:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", 0, 0)
|
||||
left:SetWidth(LEFT_W)
|
||||
left:SetPoint("TOPLEFT", f, "TOPLEFT", 0, -26)
|
||||
left:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", 0, 40)
|
||||
left:SetWidth(leftW)
|
||||
local lrows = {}
|
||||
|
||||
local tog = UI.CreateButton(f, "<", 24, 20, function()
|
||||
narrow = not narrow
|
||||
Layout().narrow = narrow or nil
|
||||
ApplyLayout()
|
||||
Redraw()
|
||||
end)
|
||||
local addBtn
|
||||
|
||||
local function CatName(id)
|
||||
local l = Layout()
|
||||
if l.cats[id] then return l.cats[id].name end
|
||||
if id == "std" then return L.CHAT_CAT_STD end
|
||||
if id == "other" then return L.CHAT_CAT_OTHER end
|
||||
if id == "guild" then return L.CHAT_CAT_GUILD end
|
||||
if id == "group" then return L.CHAT_CAT_GROUP end
|
||||
if id == "whisper" then return L.CHAT_CAT_WHISPER end
|
||||
if id == "service" then return L.CHAT_CAT_SERVICE end
|
||||
return tostring(id)
|
||||
end
|
||||
|
||||
local function CatValid(id)
|
||||
local l = Layout()
|
||||
return id and (CHANNEL_CATS[id] or l.cats[id]) and true or false
|
||||
end
|
||||
|
||||
local function MoveCat(id, dir)
|
||||
local l = Layout()
|
||||
local at
|
||||
local k = 1
|
||||
while k <= table.getn(visCats) do
|
||||
if visCats[k] == id then at = k end
|
||||
k = k + 1
|
||||
end
|
||||
local other = at and visCats[at + dir]
|
||||
if not other then return end
|
||||
local ia, ib
|
||||
k = 1
|
||||
while k <= table.getn(l.order) do
|
||||
if l.order[k] == id then ia = k end
|
||||
if l.order[k] == other then ib = k end
|
||||
k = k + 1
|
||||
end
|
||||
if ia and ib then l.order[ia], l.order[ib] = l.order[ib], l.order[ia] end
|
||||
Redraw()
|
||||
end
|
||||
|
||||
local function DeleteCat(id)
|
||||
local l = Layout()
|
||||
l.cats[id] = nil
|
||||
local new, k = {}, 1
|
||||
while k <= table.getn(l.order) do
|
||||
if l.order[k] ~= id then new[table.getn(new) + 1] = l.order[k] end
|
||||
k = k + 1
|
||||
end
|
||||
l.order = new
|
||||
Redraw()
|
||||
end
|
||||
|
||||
local function NewCat(name)
|
||||
name = string.gsub(name or "", "^%s+", "")
|
||||
name = string.gsub(name, "%s+$", "")
|
||||
if name == "" then return end
|
||||
local l = Layout()
|
||||
l.seq = (l.seq or 0) + 1
|
||||
local id = "u" .. l.seq
|
||||
l.cats[id] = { name = name }
|
||||
l.order[table.getn(l.order) + 1] = id
|
||||
Redraw()
|
||||
end
|
||||
|
||||
local function JoinDialog(catId)
|
||||
local title = L.CHAT_DLG_JOIN .. " (" .. L.CHAT_SLOTS .. Ch.FreeSlots() .. ")"
|
||||
ShowDialog(title, L.CHAT_DLG_NAME, L.CHAT_DLG_PW, "", function(name, pw)
|
||||
name = string.gsub(name or "", "^%s+", "")
|
||||
name = string.gsub(name, "%s+$", "")
|
||||
if name == "" then return end
|
||||
local ok, why = Ch.Join(name, pw, catId)
|
||||
if not ok and why == "full" then FW:Print(L.CHAT_FULL) end
|
||||
end)
|
||||
end
|
||||
|
||||
local function AddMenu()
|
||||
ShowList(L.CHAT_SLOTS .. Ch.FreeSlots(), {
|
||||
{ L.CHAT_MENU_JOIN, function() JoinDialog(nil) end },
|
||||
{ L.CHAT_MENU_NEWCAT, function()
|
||||
ShowDialog(L.CHAT_DLG_NEWCAT, L.CHAT_DLG_CATNAME, nil, L.CHAT_NEWCAT_DEFAULT, NewCat)
|
||||
end },
|
||||
})
|
||||
end
|
||||
|
||||
addBtn = UI.CreateButton(f, L.CHAT_ADD, WIDE_W - 6, 30, AddMenu, "primary")
|
||||
|
||||
local function ChannelMenu(en)
|
||||
local l = Layout()
|
||||
local items = {}
|
||||
local k = 1
|
||||
while k <= table.getn(l.order) do
|
||||
local id = l.order[k]
|
||||
if CatValid(id) and id ~= en.cat then
|
||||
local target = id
|
||||
items[table.getn(items) + 1] = { L.CHAT_MOVE_TO .. CatName(id), function()
|
||||
l.assign[en.key] = target
|
||||
Redraw()
|
||||
end }
|
||||
end
|
||||
k = k + 1
|
||||
end
|
||||
if l.assign[en.key] then
|
||||
items[table.getn(items) + 1] = { L.CHAT_MOVE_RESET, function()
|
||||
l.assign[en.key] = nil
|
||||
Redraw()
|
||||
end }
|
||||
end
|
||||
if en.e and not string.find(en.e.name, "^Freewood") then
|
||||
local nm = en.e.name
|
||||
items[table.getn(items) + 1] = { L.CHAT_LEAVE, function() Ch.Leave(nm) end }
|
||||
end
|
||||
if table.getn(items) > 0 then ShowList(en.label, items) end
|
||||
end
|
||||
|
||||
local function LeftRow(i)
|
||||
local r = lrows[i]
|
||||
if not r then
|
||||
@@ -193,19 +486,19 @@ local function Build(content)
|
||||
r:SetHeight(ROW)
|
||||
r:SetPoint("TOPLEFT", left.child, "TOPLEFT", 0, -(i - 1) * ROW)
|
||||
r:SetPoint("TOPRIGHT", left.child, "TOPRIGHT", 0, -(i - 1) * ROW)
|
||||
r:RegisterForClicks("LeftButtonUp")
|
||||
r:RegisterForClicks("LeftButtonUp", "RightButtonUp")
|
||||
r.sel = r:CreateTexture(nil, "BACKGROUND")
|
||||
r.sel:SetAllPoints()
|
||||
r.sel:SetColorTexture(UI.Color("bronze", 0.35))
|
||||
r.hl = r:CreateTexture(nil, "HIGHLIGHT")
|
||||
r.hl:SetAllPoints()
|
||||
r.hl:SetColorTexture(UI.Color("gold", 0.15))
|
||||
r.line = r:CreateTexture(nil, "ARTWORK")
|
||||
r.line:SetColorTexture(UI.Color("bronze", 0.6))
|
||||
r.line:SetHeight(1)
|
||||
r.icon = r:CreateTexture(nil, "ARTWORK")
|
||||
r.icon:SetSize(18, 18)
|
||||
r.icon:SetPoint("LEFT", r, "LEFT", 8, 0)
|
||||
r.icon:SetSize(20, 20)
|
||||
r.text = UI.CreateLabel(r, "", { size = 12, justify = "LEFT" })
|
||||
r.text:SetPoint("LEFT", r.icon, "RIGHT", 6, 0)
|
||||
r.text:SetPoint("RIGHT", r, "RIGHT", -26, 0)
|
||||
r.x = CreateFrame("Button", nil, r)
|
||||
r.x:SetSize(18, 18)
|
||||
r.x:SetPoint("RIGHT", r, "RIGHT", -4, 0)
|
||||
@@ -213,62 +506,100 @@ local function Build(content)
|
||||
r.xt:SetPoint("CENTER", r.x, "CENTER", 0, 0)
|
||||
r.x:SetScript("OnEnter", function() r.xt:SetTextColor(UI.Color("danger")) end)
|
||||
r.x:SetScript("OnLeave", function() r.xt:SetTextColor(UI.Color("textDim")) end)
|
||||
r.hb = {}
|
||||
local labels = { "+", "^", "v", "x" }
|
||||
local j = 1
|
||||
while j <= 4 do
|
||||
local b = CreateFrame("Button", nil, r)
|
||||
b:SetSize(18, 18)
|
||||
b.t = UI.CreateLabel(b, labels[j], { size = 13, color = "textDim" })
|
||||
b.t:SetPoint("CENTER", b, "CENTER", 0, 0)
|
||||
b:SetScript("OnEnter", function() b.t:SetTextColor(UI.Color("gold")) end)
|
||||
b:SetScript("OnLeave", function() b.t:SetTextColor(UI.Color("textDim")) end)
|
||||
b:Hide()
|
||||
r.hb[j] = b
|
||||
j = j + 1
|
||||
end
|
||||
lrows[i] = r
|
||||
end
|
||||
return r
|
||||
end
|
||||
|
||||
local function BuildEntries()
|
||||
local std, other, service = {}, {}, {}
|
||||
local l = Layout()
|
||||
-- neu beigetretene Kanaele ihrer gewuenschten Kategorie zuordnen
|
||||
local k = 1
|
||||
while k <= table.getn(Ch.list) do
|
||||
local lowName = string.lower(Ch.list[k].name)
|
||||
local pc = Ch.pendingCat[lowName]
|
||||
if pc then
|
||||
l.assign["c:" .. Ch.list[k].name] = pc
|
||||
Ch.pendingCat[lowName] = nil
|
||||
end
|
||||
k = k + 1
|
||||
end
|
||||
local items = {}
|
||||
local function Put(cat, en)
|
||||
if not items[cat] then items[cat] = {} end
|
||||
en.cat = cat
|
||||
items[cat][table.getn(items[cat]) + 1] = en
|
||||
end
|
||||
k = 1
|
||||
while k <= table.getn(Ch.list) do
|
||||
local e = Ch.list[k]
|
||||
local low = string.lower(e.name)
|
||||
local en = { key = "c:" .. e.name, kind = "channel", num = e.num, label = e.num .. ". " .. e.name,
|
||||
count = e.stamp and e.count or nil, e = e }
|
||||
count = e.stamp and e.count or nil, e = e, mode = "bubble", icon = ICONS[low] or ICONS.general }
|
||||
local def
|
||||
if string.find(e.name, "^Freewood") then
|
||||
en.mode = "data"; en.logo = true
|
||||
service[table.getn(service) + 1] = en
|
||||
en.mode = "data"; en.logo = true; def = "service"
|
||||
elseif low == "lft" then
|
||||
en.mode = "log"; en.icon = ICONS.lft
|
||||
service[table.getn(service) + 1] = en
|
||||
en.mode = "log"; en.icon = ICONS.lft; def = "service"
|
||||
elseif STD[low] then
|
||||
en.mode = "bubble"; en.icon = ICONS[low] or ICONS.general
|
||||
std[table.getn(std) + 1] = en
|
||||
def = "std"
|
||||
else
|
||||
en.mode = "bubble"; en.icon = ICONS[low] or ICONS.general
|
||||
other[table.getn(other) + 1] = en
|
||||
def = "other"
|
||||
end
|
||||
local cat = l.assign[en.key]
|
||||
if not CatValid(cat) then cat = def end
|
||||
Put(cat, en)
|
||||
k = k + 1
|
||||
end
|
||||
local out = {}
|
||||
local function Head(t) out[table.getn(out) + 1] = { head = t } end
|
||||
local function Add(en) out[table.getn(out) + 1] = en end
|
||||
if table.getn(std) > 0 then
|
||||
Head(L.CHAT_CAT_STD)
|
||||
k = 1; while k <= table.getn(std) do Add(std[k]); k = k + 1 end
|
||||
end
|
||||
if table.getn(other) > 0 then
|
||||
Head(L.CHAT_CAT_OTHER)
|
||||
k = 1; while k <= table.getn(other) do Add(other[k]); k = k + 1 end
|
||||
end
|
||||
Head(L.CHAT_CAT_GUILD)
|
||||
Add({ key = "guild", kind = "guild", mode = "bubble", label = L.CHAT_GUILD, icon = ICON_GUILD,
|
||||
Put("guild", { key = "guild", kind = "guild", mode = "bubble", label = L.CHAT_GUILD, icon = ICON_GUILD,
|
||||
count = table.getn(CL.guild) })
|
||||
Head(L.CHAT_CAT_GROUP)
|
||||
Add({ key = "group", kind = "group", mode = "bubble", label = L.CHAT_GROUP, icon = ICON_GROUP })
|
||||
Head(L.CHAT_CAT_WHISPER)
|
||||
Put("group", { key = "group", kind = "group", mode = "bubble", label = L.CHAT_GROUP, icon = ICON_GROUP })
|
||||
local ws = CL.OpenWhispers()
|
||||
k = 1
|
||||
while k <= table.getn(ws) do
|
||||
Add({ key = "w:" .. ws[k].name, kind = "whisper", mode = "bubble", label = ws[k].name,
|
||||
Put("whisper", { key = "w:" .. ws[k].name, kind = "whisper", mode = "bubble", label = ws[k].name,
|
||||
icon = ICON_WHISPER, closable = true, name = ws[k].name })
|
||||
k = k + 1
|
||||
end
|
||||
if table.getn(ws) == 0 then out[table.getn(out) + 1] = { note = L.CHAT_NOWHISPER } end
|
||||
if table.getn(service) > 0 then
|
||||
Head(L.CHAT_CAT_SERVICE)
|
||||
k = 1; while k <= table.getn(service) do Add(service[k]); k = k + 1 end
|
||||
|
||||
local out = {}
|
||||
visCats = {}
|
||||
k = 1
|
||||
while k <= table.getn(l.order) do
|
||||
local id = l.order[k]
|
||||
local custom = l.cats[id] ~= nil
|
||||
local known = custom or id == "std" or id == "other" or id == "guild" or id == "group"
|
||||
or id == "whisper" or id == "service"
|
||||
local list = items[id]
|
||||
local cnt = list and table.getn(list) or 0
|
||||
if known and (custom or cnt > 0 or id == "whisper") then
|
||||
visCats[table.getn(visCats) + 1] = id
|
||||
out[table.getn(out) + 1] = { head = CatName(id), cat = id, custom = custom }
|
||||
local m = 1
|
||||
while m <= cnt do out[table.getn(out) + 1] = list[m]; m = m + 1 end
|
||||
if cnt == 0 then
|
||||
if id == "whisper" then
|
||||
out[table.getn(out) + 1] = { note = L.CHAT_NOWHISPER }
|
||||
else
|
||||
out[table.getn(out) + 1] = { note = L.CHAT_EMPTY_CAT }
|
||||
end
|
||||
end
|
||||
end
|
||||
k = k + 1
|
||||
end
|
||||
return out
|
||||
end
|
||||
@@ -291,6 +622,19 @@ local function Build(content)
|
||||
return nil
|
||||
end
|
||||
|
||||
local function Tip(r, text)
|
||||
r:SetScript("OnEnter", function()
|
||||
if GameTooltip then
|
||||
pcall(GameTooltip.SetOwner, GameTooltip, r, "ANCHOR_RIGHT")
|
||||
pcall(GameTooltip.SetText, GameTooltip, text)
|
||||
pcall(GameTooltip.Show, GameTooltip)
|
||||
end
|
||||
end)
|
||||
r:SetScript("OnLeave", function()
|
||||
if GameTooltip then pcall(GameTooltip.Hide, GameTooltip) end
|
||||
end)
|
||||
end
|
||||
|
||||
local function DrawLeft()
|
||||
entries = BuildEntries()
|
||||
if not selKey or not EntryByKey(selKey) then
|
||||
@@ -308,44 +652,105 @@ local function Build(content)
|
||||
r:SetPoint("TOPLEFT", left.child, "TOPLEFT", 0, -y)
|
||||
r:SetPoint("TOPRIGHT", left.child, "TOPRIGHT", 0, -y)
|
||||
r.x:Hide()
|
||||
r.line:Hide()
|
||||
r:SetScript("OnEnter", nil)
|
||||
r:SetScript("OnLeave", nil)
|
||||
local j = 1
|
||||
while j <= 4 do r.hb[j]:Hide(); j = j + 1 end
|
||||
r.text:ClearAllPoints()
|
||||
r.icon:ClearAllPoints()
|
||||
if en.head then
|
||||
r:SetHeight(26)
|
||||
r.sel:Hide(); r.hl:Hide(); r.icon:Hide()
|
||||
r.text:ClearAllPoints()
|
||||
r.text:SetPoint("LEFT", r, "LEFT", 8, -4)
|
||||
r.text:SetPoint("RIGHT", r, "RIGHT", -4, -4)
|
||||
r.text:SetText(Hex(UI.Color("gold")) .. string.upper(en.head) .. "|r")
|
||||
r:SetScript("OnClick", nil)
|
||||
y = y + 26
|
||||
if narrow then
|
||||
r:SetHeight(14)
|
||||
r.text:SetText("")
|
||||
r.line:ClearAllPoints()
|
||||
r.line:SetPoint("LEFT", r, "LEFT", 8, -2)
|
||||
r.line:SetPoint("RIGHT", r, "RIGHT", -8, -2)
|
||||
r.line:Show()
|
||||
Tip(r, en.head)
|
||||
y = y + 14
|
||||
else
|
||||
r:SetHeight(26)
|
||||
r.text:SetText(Hex(UI.Color("gold")) .. string.upper(en.head) .. "|r")
|
||||
local cat = en.cat
|
||||
local btns = en.custom and { r.hb[4], r.hb[3], r.hb[2], r.hb[1] } or { r.hb[3], r.hb[2] }
|
||||
local x = -4
|
||||
j = 1
|
||||
while j <= table.getn(btns) do
|
||||
btns[j]:ClearAllPoints()
|
||||
btns[j]:SetPoint("RIGHT", r, "RIGHT", x, -4)
|
||||
btns[j]:Show()
|
||||
x = x - 18
|
||||
j = j + 1
|
||||
end
|
||||
r.text:SetPoint("LEFT", r, "LEFT", 8, -4)
|
||||
r.text:SetPoint("RIGHT", r, "RIGHT", x - 2, -4)
|
||||
r.hb[3]:SetScript("OnClick", function() MoveCat(cat, 1) end)
|
||||
r.hb[2]:SetScript("OnClick", function() MoveCat(cat, -1) end)
|
||||
if en.custom then
|
||||
r.hb[1]:SetScript("OnClick", function() JoinDialog(cat) end)
|
||||
r.hb[4]:SetScript("OnClick", function() DeleteCat(cat) end)
|
||||
r:SetScript("OnClick", function()
|
||||
ShowDialog(L.CHAT_DLG_RENAME, L.CHAT_DLG_CATNAME, nil, CatName(cat), function(v)
|
||||
v = string.gsub(v or "", "^%s+", "")
|
||||
v = string.gsub(v, "%s+$", "")
|
||||
if v ~= "" then Layout().cats[cat].name = v; Redraw() end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
y = y + 26
|
||||
end
|
||||
elseif en.note then
|
||||
r:SetHeight(44)
|
||||
r.sel:Hide(); r.hl:Hide(); r.icon:Hide()
|
||||
r.text:ClearAllPoints()
|
||||
r.text:SetPoint("LEFT", r, "LEFT", 8, 0)
|
||||
r.text:SetPoint("RIGHT", r, "RIGHT", -8, 0)
|
||||
r.text:SetText("|cff9a978c" .. en.note .. "|r")
|
||||
r:SetScript("OnClick", nil)
|
||||
y = y + 44
|
||||
if narrow then
|
||||
r:SetHeight(4)
|
||||
r.text:SetText("")
|
||||
y = y + 4
|
||||
else
|
||||
r:SetHeight(46)
|
||||
r.text:SetPoint("LEFT", r, "LEFT", 10, 0)
|
||||
r.text:SetPoint("RIGHT", r, "RIGHT", -8, 0)
|
||||
r.text:SetText("|cff9a978c" .. en.note .. "|r")
|
||||
y = y + 46
|
||||
end
|
||||
else
|
||||
r:SetHeight(ROW)
|
||||
r.hl:Show(); r.icon:Show()
|
||||
r.text:ClearAllPoints()
|
||||
r.text:SetPoint("LEFT", r.icon, "RIGHT", 6, 0)
|
||||
r.text:SetPoint("RIGHT", r, "RIGHT", en.closable and -26 or -6, 0)
|
||||
if en.logo then
|
||||
r.icon:SetTexture(LOGO); r.icon:SetTexCoord(0, 1, 0, 1)
|
||||
else
|
||||
SetIcon(r.icon, en.icon)
|
||||
end
|
||||
local txt = en.label
|
||||
if en.count then txt = txt .. " |cff9a978c(" .. en.count .. ")|r" end
|
||||
local un = CL.unread[en.key]
|
||||
if un and un > 0 and en.key ~= selKey then txt = txt .. " |cffc89b3c+" .. un .. "|r" end
|
||||
r.text:SetText(txt)
|
||||
if narrow then
|
||||
r.icon:SetPoint("CENTER", r, "CENTER", 0, 0)
|
||||
r.text:SetText("")
|
||||
local txt = en.label
|
||||
Tip(r, txt)
|
||||
else
|
||||
r.icon:SetPoint("LEFT", r, "LEFT", 10, 0)
|
||||
r.text:SetPoint("LEFT", r.icon, "RIGHT", 8, 0)
|
||||
r.text:SetPoint("RIGHT", r, "RIGHT", en.closable and -26 or -6, 0)
|
||||
local txt = en.label
|
||||
if en.count then txt = txt .. " |cff9a978c(" .. en.count .. ")|r" end
|
||||
local un = CL.unread[en.key]
|
||||
if un and un > 0 and en.key ~= selKey then txt = txt .. " |cffc89b3c+" .. un .. "|r" end
|
||||
r.text:SetText(txt)
|
||||
end
|
||||
if en.key == selKey then r.sel:Show() else r.sel:Hide() end
|
||||
local key = en.key
|
||||
r:SetScript("OnClick", function() selectKey(key) end)
|
||||
if en.closable then
|
||||
local ent = en
|
||||
r:SetScript("OnClick", function(_, btn)
|
||||
btn = btn or arg1
|
||||
if btn == "RightButton" and ent.kind == "channel" then
|
||||
ChannelMenu(ent)
|
||||
else
|
||||
selectKey(key)
|
||||
end
|
||||
end)
|
||||
if en.closable and not narrow then
|
||||
local nm = en.name
|
||||
r.x:Show()
|
||||
r.x:SetScript("OnClick", function()
|
||||
@@ -367,23 +772,23 @@ local function Build(content)
|
||||
-- Mitte: Kopf, Chat (Blasen / Log), Eingabe
|
||||
------------------------------------------------------------------
|
||||
local head = UI.CreateLabel(f, "", { font = "heading", size = 15, color = "gold", justify = "LEFT" })
|
||||
head:SetPoint("TOPLEFT", f, "TOPLEFT", LEFT_W + 14, -2)
|
||||
head:SetPoint("TOPLEFT", f, "TOPLEFT", leftW + 14, -2)
|
||||
head:SetPoint("TOPRIGHT", f, "TOPRIGHT", -(RIGHT_W + 14), -2)
|
||||
local sub = UI.CreateLabel(f, "", { size = 11, color = "textDim", justify = "LEFT" })
|
||||
sub:SetPoint("TOPLEFT", f, "TOPLEFT", LEFT_W + 14, -24)
|
||||
sub:SetPoint("TOPLEFT", f, "TOPLEFT", leftW + 14, -24)
|
||||
sub:SetPoint("TOPRIGHT", f, "TOPRIGHT", -(RIGHT_W + 14), -24)
|
||||
|
||||
local chat = UI.CreateScrollFrame(f)
|
||||
chat:SetPoint("TOPLEFT", f, "TOPLEFT", LEFT_W + 14, -44)
|
||||
chat:SetPoint("TOPLEFT", f, "TOPLEFT", leftW + 14, -44)
|
||||
chat:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -(RIGHT_W + 14), 40)
|
||||
|
||||
local logArea = UI.CreateTextArea(f)
|
||||
logArea:SetPoint("TOPLEFT", f, "TOPLEFT", LEFT_W + 14, -44)
|
||||
logArea:SetPoint("TOPLEFT", f, "TOPLEFT", leftW + 14, -44)
|
||||
logArea:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -(RIGHT_W + 14), 40)
|
||||
logArea:Hide()
|
||||
|
||||
local empty = UI.CreateLabel(f, "", { size = 12, color = "textDim", justify = "LEFT", justifyV = "TOP" })
|
||||
empty:SetPoint("TOPLEFT", f, "TOPLEFT", LEFT_W + 24, -56)
|
||||
empty:SetPoint("TOPLEFT", f, "TOPLEFT", leftW + 24, -56)
|
||||
empty:SetPoint("TOPRIGHT", f, "TOPRIGHT", -(RIGHT_W + 24), -56)
|
||||
empty:SetHeight(60)
|
||||
|
||||
@@ -393,7 +798,7 @@ local function Build(content)
|
||||
|
||||
local ibox = UI.CreatePanel(f, "bgDeep", "bronze")
|
||||
ibox:SetHeight(28)
|
||||
ibox:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", LEFT_W + 14, 6)
|
||||
ibox:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", leftW + 14, 6)
|
||||
ibox:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -(RIGHT_W + 14 + 96), 6)
|
||||
input = CreateFrame("EditBox", nil, ibox)
|
||||
input:SetAutoFocus(false)
|
||||
@@ -424,6 +829,7 @@ local function Build(content)
|
||||
|
||||
-- Blasen-Pool
|
||||
local bubbles = {}
|
||||
local seps = {}
|
||||
local function Bubble(i)
|
||||
local b = bubbles[i]
|
||||
if b then return b end
|
||||
@@ -465,9 +871,30 @@ local function Build(content)
|
||||
local atBottom = stick or (chat.scroll:GetVerticalScroll() >= lastH - lastViewH - 8)
|
||||
local y = 6
|
||||
local idx = 0
|
||||
local sidx = 0
|
||||
local prevDay = nil
|
||||
local i = first
|
||||
while i <= n do
|
||||
local ln = lines[i]
|
||||
local dk = DayKey(ln.t)
|
||||
if dk ~= prevDay then
|
||||
prevDay = dk
|
||||
sidx = sidx + 1
|
||||
local sp = seps[sidx]
|
||||
if not sp then
|
||||
sp = CreateFrame("Frame", nil, chat.child)
|
||||
sp:SetHeight(20)
|
||||
sp.t = UI.CreateLabel(sp, "", { size = 11, color = "textDim", justify = "CENTER" })
|
||||
sp.t:SetPoint("CENTER", sp, "CENTER", 0, 0)
|
||||
seps[sidx] = sp
|
||||
end
|
||||
sp:SetWidth(areaW - 8)
|
||||
sp:ClearAllPoints()
|
||||
sp:SetPoint("TOPLEFT", chat.child, "TOPLEFT", 0, -y)
|
||||
sp.t:SetText("- " .. DayText(ln.t, L) .. " -")
|
||||
sp:Show()
|
||||
y = y + 24
|
||||
end
|
||||
idx = idx + 1
|
||||
local b = Bubble(idx)
|
||||
local own = ln.o ~= nil
|
||||
@@ -478,12 +905,12 @@ local function Build(content)
|
||||
local r, g, bl = CL.ClassColor(cls)
|
||||
b.name:SetTextColor(r, g, bl)
|
||||
b.name:SetText(who)
|
||||
b.time:SetText(TimeText(ln.t))
|
||||
b.time:SetText(Stamp(ln.t, L))
|
||||
local txt = ln.m or ""
|
||||
measure:SetText(Plain(txt))
|
||||
local tw = measure:GetStringWidth() or 0
|
||||
if tw <= 0 then tw = maxBub end
|
||||
local nameW = (b.name:GetStringWidth() or 60) + 50
|
||||
local nameW = (b.name:GetStringWidth() or 60) + (b.time:GetStringWidth() or 80) + 40
|
||||
local pw = math.floor(math.max(math.min(math.max(tw, nameW) + 22, maxBub), 110))
|
||||
b.text:SetWidth(pw - 20)
|
||||
b.text:SetText(txt)
|
||||
@@ -519,6 +946,8 @@ local function Build(content)
|
||||
end
|
||||
idx = idx + 1
|
||||
while bubbles[idx] do bubbles[idx]:Hide(); idx = idx + 1 end
|
||||
sidx = sidx + 1
|
||||
while seps[sidx] do seps[sidx]:Hide(); sidx = sidx + 1 end
|
||||
local viewH = chat.scroll:GetHeight() or 300
|
||||
chat:SetContentHeight(math.max(1, y))
|
||||
lastH, lastViewH = y, viewH
|
||||
@@ -538,7 +967,7 @@ local function Build(content)
|
||||
local i = first
|
||||
while i <= n do
|
||||
local ln = lines[i]
|
||||
parts[table.getn(parts) + 1] = "[" .. TimeText(ln.t) .. "] " .. (ln.s or "?") .. ": " .. Plain(ln.m or "")
|
||||
parts[table.getn(parts) + 1] = "[" .. Stamp(ln.t, L) .. "] " .. (ln.s or "?") .. ": " .. Plain(ln.m or "")
|
||||
i = i + 1
|
||||
end
|
||||
if not logArea.edit:HasFocus() then
|
||||
@@ -722,6 +1151,41 @@ local function Build(content)
|
||||
DrawRight()
|
||||
end)
|
||||
|
||||
ApplyLayout = function()
|
||||
leftW = narrow and NARROW_W or WIDE_W
|
||||
left:SetWidth(leftW)
|
||||
tog:ClearAllPoints()
|
||||
tog:SetPoint("TOPLEFT", f, "TOPLEFT", leftW - 28, 0)
|
||||
tog:SetLabel(narrow and ">" or "<")
|
||||
Tip(tog, narrow and L.CHAT_EXPAND or L.CHAT_COLLAPSE)
|
||||
addBtn:ClearAllPoints()
|
||||
addBtn:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", 0, 4)
|
||||
addBtn:SetWidth(leftW - 6)
|
||||
addBtn:SetLabel(narrow and "+" or L.CHAT_ADD)
|
||||
local lx = leftW + 14
|
||||
head:ClearAllPoints()
|
||||
head:SetPoint("TOPLEFT", f, "TOPLEFT", lx, -2)
|
||||
head:SetPoint("TOPRIGHT", f, "TOPRIGHT", -(RIGHT_W + 14), -2)
|
||||
sub:ClearAllPoints()
|
||||
sub:SetPoint("TOPLEFT", f, "TOPLEFT", lx, -24)
|
||||
sub:SetPoint("TOPRIGHT", f, "TOPRIGHT", -(RIGHT_W + 14), -24)
|
||||
chat:ClearAllPoints()
|
||||
chat:SetPoint("TOPLEFT", f, "TOPLEFT", lx, -44)
|
||||
chat:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -(RIGHT_W + 14), 40)
|
||||
logArea:ClearAllPoints()
|
||||
logArea:SetPoint("TOPLEFT", f, "TOPLEFT", lx, -44)
|
||||
logArea:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -(RIGHT_W + 14), 40)
|
||||
empty:ClearAllPoints()
|
||||
empty:SetPoint("TOPLEFT", f, "TOPLEFT", lx + 10, -56)
|
||||
empty:SetPoint("TOPRIGHT", f, "TOPRIGHT", -(RIGHT_W + 24), -56)
|
||||
ibox:ClearAllPoints()
|
||||
ibox:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", lx, 6)
|
||||
ibox:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -(RIGHT_W + 14 + 96), 6)
|
||||
stick = true
|
||||
end
|
||||
narrow = Layout().narrow and true or false
|
||||
ApplyLayout()
|
||||
|
||||
------------------------------------------------------------------
|
||||
-- Zusammenspiel
|
||||
------------------------------------------------------------------
|
||||
@@ -758,6 +1222,7 @@ local function Build(content)
|
||||
CL.viewVisible = false
|
||||
CL.ClearMemberQueue()
|
||||
HideMenu()
|
||||
HideList()
|
||||
copy:Hide()
|
||||
end)
|
||||
|
||||
@@ -767,6 +1232,7 @@ local function Build(content)
|
||||
if acc < 0.4 then return end
|
||||
acc = 0
|
||||
if not f:IsShown() then return end
|
||||
if Ch.dirty then Ch.dirty = nil; Ch.RefreshAll() end
|
||||
local w = chat.child:GetWidth()
|
||||
if seen.cl ~= CL.version or seen.ch ~= Ch.version or (w and math.abs(w - seen.w) > 4) then
|
||||
Redraw()
|
||||
|
||||
Reference in New Issue
Block a user