mirror of
https://github.com/Lacustat/Freewood-OctoWoW-Core.git
synced 2026-11-04 06:56:55 +00:00
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016onJCSHLwhs9udhC9ZLzk9
227 lines
7.9 KiB
Lua
227 lines
7.9 KiB
Lua
-- Freewood-OctoWoW-Core: Reiter "Kanaele" (Chat-Kanaele und ihre Mitglieder). UNGEPRUEFT im Spiel.
|
|
-- Links die Kanaele, rechts die Mitglieder des gewaehlten Kanals oder die Suchtreffer ueber alle Kanaele.
|
|
|
|
local ADDON, FW = ...
|
|
|
|
local UI = FW.UI
|
|
local Ch = FW.Channels
|
|
|
|
local ROW = 20
|
|
local MAX_ROWS = 300
|
|
|
|
local function MakeRows(holder)
|
|
local rows = {}
|
|
function rows.Get(i)
|
|
local r = rows[i]
|
|
if not r then
|
|
r = CreateFrame("Button", nil, holder.child)
|
|
r:SetHeight(ROW)
|
|
r:SetPoint("TOPLEFT", holder.child, "TOPLEFT", 0, -(i - 1) * ROW)
|
|
r:SetPoint("TOPRIGHT", holder.child, "TOPRIGHT", 0, -(i - 1) * ROW)
|
|
r.sel = r:CreateTexture(nil, "BACKGROUND")
|
|
r.sel:SetAllPoints()
|
|
r.sel:SetColorTexture(UI.Color("bronze", 0.35))
|
|
r.sel:Hide()
|
|
r.hl = r:CreateTexture(nil, "HIGHLIGHT")
|
|
r.hl:SetAllPoints()
|
|
r.hl:SetColorTexture(UI.Color("gold", 0.15))
|
|
r.text = UI.CreateLabel(r, "", { size = 12, justify = "LEFT" })
|
|
r.text:SetPoint("LEFT", r, "LEFT", 6, 0)
|
|
r.text:SetPoint("RIGHT", r, "RIGHT", -4, 0)
|
|
rows[i] = r
|
|
end
|
|
return r
|
|
end
|
|
function rows.HideFrom(i)
|
|
local k = i
|
|
while rows[k] do rows[k]:Hide(); k = k + 1 end
|
|
end
|
|
return rows
|
|
end
|
|
|
|
local function BuildChannels(content)
|
|
local L = FW.L
|
|
local f = CreateFrame("Frame", nil, content)
|
|
f:SetAllPoints(content)
|
|
|
|
local selNum, selPlayer, seenVersion = nil, nil, -1
|
|
local search = ""
|
|
local lastAuto = 0
|
|
|
|
-- links: Kanalliste
|
|
local title = UI.CreateLabel(f, L.TAB_CHANNELS, { font = "heading", size = 15, color = "gold" })
|
|
title:SetPoint("TOPLEFT", f, "TOPLEFT", 0, 0)
|
|
local refresh = UI.CreateButton(f, L.CHAN_REFRESH, 110, 24, function()
|
|
Ch.RefreshAll()
|
|
end)
|
|
refresh:SetPoint("TOPLEFT", f, "TOPLEFT", 100, 2)
|
|
local left = UI.CreateScrollFrame(f)
|
|
left:SetPoint("TOPLEFT", f, "TOPLEFT", 0, -34)
|
|
left:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", 0, 0)
|
|
left:SetWidth(220)
|
|
local lrows = MakeRows(left)
|
|
|
|
-- rechts: Suche, Status, Mitglieder, Aktionsleiste
|
|
local box = UI.CreatePanel(f, "bgDeep", "bronze")
|
|
box:SetHeight(26)
|
|
box:SetPoint("TOPLEFT", f, "TOPLEFT", 236, -2)
|
|
box:SetPoint("TOPRIGHT", f, "TOPRIGHT", 0, -2)
|
|
local edit = CreateFrame("EditBox", nil, box)
|
|
edit:SetAutoFocus(false)
|
|
edit:SetPoint("TOPLEFT", box, "TOPLEFT", 8, -2)
|
|
edit:SetPoint("BOTTOMRIGHT", box, "BOTTOMRIGHT", -8, 2)
|
|
edit:SetMaxLetters(40)
|
|
if not edit:SetFont(UI.GetFontPath("body"), 12, "") then
|
|
edit:SetFont("Fonts\\FRIZQT__.TTF", 12, "")
|
|
end
|
|
edit:SetTextColor(UI.Color("text"))
|
|
edit:SetScript("OnEscapePressed", function(self) self:ClearFocus() end)
|
|
local hint = UI.CreateLabel(box, L.CHAN_SEARCH, { size = 12, color = "textDim" })
|
|
hint:SetPoint("LEFT", box, "LEFT", 10, 0)
|
|
|
|
local status = UI.CreateLabel(f, "", { size = 11, color = "textDim", justify = "LEFT" })
|
|
status:SetPoint("TOPLEFT", f, "TOPLEFT", 236, -34)
|
|
status:SetPoint("TOPRIGHT", f, "TOPRIGHT", 0, -34)
|
|
|
|
local right = UI.CreateScrollFrame(f)
|
|
right:SetPoint("TOPLEFT", f, "TOPLEFT", 236, -54)
|
|
right:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", 0, 36)
|
|
local rrows = MakeRows(right)
|
|
|
|
local selLabel = UI.CreateLabel(f, L.CHAN_SELECT, { size = 12, color = "textDim", justify = "LEFT" })
|
|
selLabel:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", 236, 10)
|
|
selLabel:SetWidth(200)
|
|
local function Act(fn)
|
|
return function() if selPlayer then fn(selPlayer) end end
|
|
end
|
|
local bW = UI.CreateButton(f, L.CHAN_WHISPER, 90, 24, Act(Ch.Whisper))
|
|
local bI = UI.CreateButton(f, L.CHAN_INVITE, 90, 24, Act(Ch.Invite))
|
|
local bG = UI.CreateButton(f, L.CHAN_IGNORE, 90, 24, Act(Ch.Ignore))
|
|
bG:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", 0, 4)
|
|
bI:SetPoint("RIGHT", bG, "LEFT", -6, 0)
|
|
bW:SetPoint("RIGHT", bI, "LEFT", -6, 0)
|
|
|
|
local function Redraw()
|
|
seenVersion = Ch.version
|
|
-- Kanalliste
|
|
local n = table.getn(Ch.list)
|
|
local k = 1
|
|
while k <= n do
|
|
local e = Ch.list[k]
|
|
local r = lrows.Get(k)
|
|
local num = e.num
|
|
r.text:SetText(e.num .. ". " .. e.name .. " |cff8c8a84(" .. (e.stamp and e.count or "?") .. ")|r")
|
|
if num == selNum then r.sel:Show() else r.sel:Hide() end
|
|
r:SetScript("OnClick", function()
|
|
selNum = num
|
|
selPlayer = nil
|
|
Redraw()
|
|
end)
|
|
r:Show()
|
|
k = k + 1
|
|
end
|
|
lrows.HideFrom(n + 1)
|
|
left:SetContentHeight(math.max(1, n * ROW))
|
|
|
|
-- rechts
|
|
local items = {} -- { name=, extra= }
|
|
if search ~= "" then
|
|
local hits = Ch.Find(search, MAX_ROWS)
|
|
local h = 1
|
|
while h <= table.getn(hits) do
|
|
items[h] = { name = hits[h].name, extra = table.concat(hits[h].chans, ", ") }
|
|
h = h + 1
|
|
end
|
|
if table.getn(items) == 0 then
|
|
status:SetText(L.CHAN_NO_HITS)
|
|
elseif Ch.moreFound then
|
|
status:SetText(L.CHAN_MORE)
|
|
else
|
|
status:SetText("")
|
|
end
|
|
Ch.moreFound = nil
|
|
else
|
|
local e = selNum and Ch.byNum[selNum]
|
|
if n == 0 then
|
|
status:SetText(L.CHAN_NONE)
|
|
elseif not e then
|
|
status:SetText(L.CHAN_SELECT)
|
|
else
|
|
local txt = e.num .. ". " .. e.name
|
|
if e.stamp then
|
|
txt = txt .. " - " .. string.format(L.CHAN_MEMBERS, tostring(e.count))
|
|
else
|
|
txt = txt .. " - " .. L.CHAN_NOT_QUERIED
|
|
end
|
|
if string.find(e.name, "^Freewood") then txt = txt .. " (" .. L.CHAN_HIDDEN .. ")" end
|
|
local pend = Ch.Pending()
|
|
if pend > 0 then txt = txt .. " - " .. string.format(L.CHAN_PENDING, tostring(pend)) end
|
|
status:SetText(txt)
|
|
local m = 1
|
|
while m <= table.getn(e.members) and m <= MAX_ROWS do
|
|
items[m] = { name = e.members[m] }
|
|
m = m + 1
|
|
end
|
|
end
|
|
end
|
|
local cnt = table.getn(items)
|
|
local i = 1
|
|
while i <= cnt do
|
|
local it = items[i]
|
|
local r = rrows.Get(i)
|
|
local nm = it.name
|
|
if it.extra then
|
|
r.text:SetText(nm .. " |cff8c8a84" .. it.extra .. "|r")
|
|
else
|
|
r.text:SetText(nm)
|
|
end
|
|
if nm == selPlayer then r.sel:Show() else r.sel:Hide() end
|
|
r:SetScript("OnClick", function()
|
|
selPlayer = nm
|
|
selLabel:SetText(nm)
|
|
Redraw()
|
|
end)
|
|
r:Show()
|
|
i = i + 1
|
|
end
|
|
rrows.HideFrom(cnt + 1)
|
|
right:SetContentHeight(math.max(1, cnt * ROW))
|
|
end
|
|
|
|
edit:SetScript("OnTextChanged", function(self)
|
|
search = self:GetText() or ""
|
|
if search == "" then hint:Show() else hint:Hide() end
|
|
right:ScrollToTop()
|
|
Redraw()
|
|
end)
|
|
|
|
f.Refresh = function()
|
|
if Ch.dirty or table.getn(Ch.list) == 0 then
|
|
Ch.dirty = nil
|
|
Ch.RefreshAll()
|
|
else
|
|
Ch.Rescan()
|
|
end
|
|
if not selNum and Ch.list[1] then selNum = Ch.list[1].num end
|
|
Redraw()
|
|
end
|
|
|
|
-- Aenderungen der Datenschicht nachziehen (hoechstens 2x pro Sekunde)
|
|
local acc = 0
|
|
f:SetScript("OnUpdate", function(_, el)
|
|
acc = acc + (el or arg1 or 0)
|
|
if acc < 0.5 then return end
|
|
acc = 0
|
|
if f:IsShown() and seenVersion ~= Ch.version then Redraw() end
|
|
end)
|
|
|
|
return f
|
|
end
|
|
|
|
UI:RegisterTab("channels", {
|
|
label = function() return FW.L.TAB_CHANNELS end,
|
|
order = 115,
|
|
build = BuildChannels,
|
|
onShow = function(f) f.Refresh() end,
|
|
})
|