-- Freewood-OctoWoW-Core: Reiter "Kanaele" als Chatfenster (Kategorien links, Chat Mitte, Mitglieder rechts). -- ALLES UNGEPRUEFT im Spiel. Datenschicht: Core/Channels.lua (Mitglieder) und Core/ChatLog.lua (Verlauf). local ADDON, FW = ... local UI = FW.UI local Ch = FW.Channels local CL = FW.ChatLog local LEFT_W, RIGHT_W = 220, 220 local ROW = 24 local MAX_BUBBLES = 60 local LOG_LINES = 200 local LOGO = "Interface\\AddOns\\Freewood-OctoWoW-Core\\Media\\FreeWood_Logo.tga" local QMARK = "Interface\\Icons\\INV_Misc_QuestionMark" local ICONS = { general = "Interface\\Icons\\INV_Misc_Note_01", localdefense = "Interface\\Icons\\INV_Shield_06", world = "Interface\\Icons\\INV_Misc_Map_01", lookingforgroup = "Interface\\Icons\\INV_Misc_Eye_01", lft = "Interface\\Icons\\INV_Misc_Bell_01", } local ICON_GUILD = "Interface\\Icons\\INV_Shirt_GuildTabard_01" local ICON_GROUP = "Interface\\Icons\\Spell_Holy_PrayerOfHealing" local ICON_WHISPER = "Interface\\Icons\\INV_Letter_02" local STD = { general = true, localdefense = true, world = true, lookingforgroup = true, allgemein = true, lokaleverteidigung = true } local function Hex(r, g, b) return string.format("|cff%02x%02x%02x", math.floor(r * 255 + 0.5), math.floor(g * 255 + 0.5), math.floor(b * 255 + 0.5)) end -- Klassenbilder: normale Zaubersymbole (die Klassen-Bildtafel des Clients ist hier nicht brauchbar) local CLASS_ICONS = { WARRIOR = "Interface\\Icons\\Ability_Warrior_OffensiveStance", MAGE = "Interface\\Icons\\Spell_Frost_FrostBolt02", ROGUE = "Interface\\Icons\\Ability_Stealth", DRUID = "Interface\\Icons\\Spell_Nature_HealingTouch", HUNTER = "Interface\\Icons\\Ability_Marksmanship", SHAMAN = "Interface\\Icons\\Spell_Nature_BloodLust", PRIEST = "Interface\\Icons\\Spell_Holy_PowerWordShield", WARLOCK = "Interface\\Icons\\Spell_Shadow_ShadowBolt", PALADIN = "Interface\\Icons\\Spell_Holy_HolyBolt", } local function SetClassIcon(tex, token) tex:SetTexture((token and CLASS_ICONS[token]) or QMARK) tex:SetTexCoord(0.08, 0.92, 0.08, 0.92) end local function SetIcon(tex, path) tex:SetTexture(path or QMARK) tex:SetTexCoord(0.08, 0.92, 0.08, 0.92) 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) return ok and s or "" end local function Build(content) local L = FW.L local f = CreateFrame("Frame", nil, content) f:SetAllPoints(content) local selKey = nil local entries = {} local search = "" local seen = { cl = -1, ch = -1, w = 0 } local stick = true local lastH, lastViewH = 0, 0 ------------------------------------------------------------------ -- Kopierfeld und Menue (gemeinsam) ------------------------------------------------------------------ local copy = UI.CreatePanel(UIParent, "bgDeep", "gold") copy:SetSize(560, 96) copy:SetPoint("CENTER", UIParent, "CENTER", 0, 120) copy:SetFrameStrata("FULLSCREEN_DIALOG") copy:Hide() local copyHint = UI.CreateLabel(copy, L.CHAT_COPY_HINT, { size = 11, color = "textDim" }) copyHint:SetPoint("TOPLEFT", copy, "TOPLEFT", 12, -8) local cbox = UI.CreatePanel(copy, "bg", "bronze") cbox:SetPoint("TOPLEFT", copy, "TOPLEFT", 10, -28) cbox:SetPoint("TOPRIGHT", copy, "TOPRIGHT", -10, -28) cbox:SetHeight(26) local cedit = CreateFrame("EditBox", nil, cbox) cedit:SetAutoFocus(false) cedit:SetPoint("TOPLEFT", cbox, "TOPLEFT", 6, -3) cedit:SetPoint("BOTTOMRIGHT", cbox, "BOTTOMRIGHT", -6, 3) cedit:SetMaxLetters(600) if not cedit:SetFont(UI.GetFontPath("body"), 12, "") then cedit:SetFont("Fonts\\FRIZQT__.TTF", 12, "") end cedit:SetTextColor(UI.Color("text")) cedit:SetScript("OnEscapePressed", function() copy:Hide() end) local copyMsg, copyUrl local bMsg = UI.CreateButton(copy, L.CHAT_COPY_MSG, 100, 24, function() if copyMsg then cedit:SetText(copyMsg); cedit:SetFocus(); cedit:HighlightText() end end) bMsg:SetPoint("BOTTOMLEFT", copy, "BOTTOMLEFT", 10, 8) local bUrl = UI.CreateButton(copy, L.CHAT_COPY_LINK, 100, 24, function() if copyUrl then cedit:SetText(copyUrl); cedit:SetFocus(); cedit:HighlightText() end end) bUrl:SetPoint("LEFT", bMsg, "RIGHT", 6, 0) local bX = UI.CreateButton(copy, "X", 30, 24, function() copy:Hide() end) bX:SetPoint("BOTTOMRIGHT", copy, "BOTTOMRIGHT", -10, 8) local function ShowCopy(text, url) copyMsg, copyUrl = text, url cedit:SetText(text or "") if url then bUrl:Show() else bUrl:Hide() end copy:Show() cedit:SetFocus() cedit:HighlightText() end local menu, menuCatcher, menuTitle local menuName local selectKey, Redraw local input local function HideMenu() if menu then menu:Hide() end if menuCatcher then menuCatcher:Hide() end end local function BuildMenu() menuCatcher = CreateFrame("Button", nil, UIParent) menuCatcher:SetAllPoints(UIParent) menuCatcher:SetFrameStrata("FULLSCREEN_DIALOG") menuCatcher:RegisterForClicks("LeftButtonUp", "RightButtonUp") menuCatcher:SetScript("OnClick", HideMenu) menuCatcher:Hide() menu = UI.CreatePanel(UIParent, "bgDeep", "gold") menu:SetSize(180, 28 + 6 * 24 + 8) menu:SetFrameStrata("FULLSCREEN_DIALOG") menu:SetFrameLevel(menuCatcher:GetFrameLevel() + 5) menu:Hide() menuTitle = UI.CreateLabel(menu, "", { size = 12, color = "gold" }) menuTitle:SetPoint("TOPLEFT", menu, "TOPLEFT", 10, -8) local acts = { { L.CHAN_WHISPER, function(n) CL.OpenWhisper(n) if selectKey then selectKey("w:" .. n) end if input then input:SetFocus() end end }, { L.CHAN_INVITE, function(n) Ch.Invite(n) end }, { L.CHAN_IGNORE, function(n) Ch.Ignore(n) end }, { L.CHAT_MENU_FRIEND, function(n) if _G.AddFriend then pcall(_G.AddFriend, n) end end }, { L.CHAT_MENU_WHO, function(n) CL.Ask(n, true) end }, { L.CHAT_MENU_COPY, function(n) ShowCopy(n, nil) end }, } local i = 1 while i <= 6 do local a = acts[i] local b = UI.CreateButton(menu, a[1], 164, 22, function() local n = menuName HideMenu() if n then a[2](n) end end) b:SetPoint("TOPLEFT", menu, "TOPLEFT", 8, -28 - (i - 1) * 24) i = i + 1 end end local function ShowMenu(name) if not name or name == "" then return end if not menu then BuildMenu() end menuName = name menuTitle:SetText(name) local x, y = GetCursorPosition() local sc = UIParent:GetEffectiveScale() menu:ClearAllPoints() menu:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", x / sc, y / sc) menuCatcher:Show() menu:Show() end ------------------------------------------------------------------ -- Linke Spalte: Kategorien und Chats ------------------------------------------------------------------ local left = UI.CreateScrollFrame(f) left:SetPoint("TOPLEFT", f, "TOPLEFT", 0, 0) left:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", 0, 0) left:SetWidth(LEFT_W) local lrows = {} local function LeftRow(i) local r = lrows[i] if not r then r = CreateFrame("Button", nil, left.child) 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.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.icon = r:CreateTexture(nil, "ARTWORK") r.icon:SetSize(18, 18) r.icon:SetPoint("LEFT", r, "LEFT", 8, 0) 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) r.xt = UI.CreateLabel(r.x, "x", { size = 13, color = "textDim" }) 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) lrows[i] = r end return r end local function BuildEntries() local std, other, service = {}, {}, {} local 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 } if string.find(e.name, "^Freewood") then en.mode = "data"; en.logo = true service[table.getn(service) + 1] = en elseif low == "lft" then en.mode = "log"; en.icon = ICONS.lft service[table.getn(service) + 1] = en elseif STD[low] then en.mode = "bubble"; en.icon = ICONS[low] or ICONS.general std[table.getn(std) + 1] = en else en.mode = "bubble"; en.icon = ICONS[low] or ICONS.general other[table.getn(other) + 1] = en end 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, 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) 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, 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 end return out end local function EntryByKey(key) local k = 1 while k <= table.getn(entries) do if entries[k].key == key then return entries[k] end k = k + 1 end return nil end local function FirstEntry() local k = 1 while k <= table.getn(entries) do if entries[k].key then return entries[k] end k = k + 1 end return nil end local function DrawLeft() entries = BuildEntries() if not selKey or not EntryByKey(selKey) then local fe = FirstEntry() selKey = fe and fe.key or nil stick = true end local n = table.getn(entries) local i = 1 local y = 0 while i <= n do local en = entries[i] local r = LeftRow(i) r:ClearAllPoints() r:SetPoint("TOPLEFT", left.child, "TOPLEFT", 0, -y) r:SetPoint("TOPRIGHT", left.child, "TOPRIGHT", 0, -y) r.x:Hide() 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 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 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 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 nm = en.name r.x:Show() r.x:SetScript("OnClick", function() CL.CloseWhisper(nm) if selKey == "w:" .. nm then selKey = nil end Redraw() end) end y = y + ROW end r:Show() i = i + 1 end while lrows[i] do lrows[i]:Hide(); i = i + 1 end left:SetContentHeight(math.max(1, y)) end ------------------------------------------------------------------ -- 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("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("TOPRIGHT", f, "TOPRIGHT", -(RIGHT_W + 14), -24) local chat = UI.CreateScrollFrame(f) chat:SetPoint("TOPLEFT", f, "TOPLEFT", LEFT_W + 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("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("TOPRIGHT", f, "TOPRIGHT", -(RIGHT_W + 24), -56) empty:SetHeight(60) local measure = f:CreateFontString(nil, "OVERLAY") UI.SetFont(measure, "body", 12) measure:Hide() local ibox = UI.CreatePanel(f, "bgDeep", "bronze") ibox:SetHeight(28) ibox:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", LEFT_W + 14, 6) ibox:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -(RIGHT_W + 14 + 96), 6) input = CreateFrame("EditBox", nil, ibox) input:SetAutoFocus(false) input:SetPoint("TOPLEFT", ibox, "TOPLEFT", 8, -3) input:SetPoint("BOTTOMRIGHT", ibox, "BOTTOMRIGHT", -8, 3) input:SetMaxLetters(255) if not input:SetFont(UI.GetFontPath("body"), 12, "") then input:SetFont("Fonts\\FRIZQT__.TTF", 12, "") end input:SetTextColor(UI.Color("text")) local ihint = UI.CreateLabel(ibox, L.CHAT_INPUT, { size = 12, color = "textDim" }) ihint:SetPoint("LEFT", ibox, "LEFT", 10, 0) local function DoSend() local txt = input:GetText() or "" local en = selKey and EntryByKey(selKey) if txt == "" or not en then return end if en.kind == "channel" then CL.Send("channel", en.num, txt) elseif en.kind == "guild" then CL.Send("guild", nil, txt) elseif en.kind == "group" then CL.Send("group", nil, txt) elseif en.kind == "whisper" then CL.Send("whisper", en.name, txt) end input:SetText("") end input:SetScript("OnEnterPressed", function() DoSend(); input:SetFocus() end) input:SetScript("OnEscapePressed", function(self) self:ClearFocus() end) input:SetScript("OnTextChanged", function(self) if (self:GetText() or "") == "" then ihint:Show() else ihint:Hide() end end) local sendBtn = UI.CreateButton(f, L.CHAT_SEND, 88, 28, DoSend) sendBtn:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -(RIGHT_W + 14), 6) -- Blasen-Pool local bubbles = {} local function Bubble(i) local b = bubbles[i] if b then return b end b = CreateFrame("Frame", nil, chat.child) b:SetHeight(60) b.avBtn = CreateFrame("Button", nil, b) b.avBtn:SetSize(36, 36) b.avBtn:RegisterForClicks("LeftButtonUp", "RightButtonUp") b.av = b.avBtn:CreateTexture(nil, "ARTWORK") b.av:SetAllPoints() b.lvl = UI.CreateLabel(b, "", { size = 11, color = "textDim" }) b.panel = CreateFrame("Button", nil, b) b.panel:RegisterForClicks("LeftButtonUp", "RightButtonUp") b.bg = b.panel:CreateTexture(nil, "BACKGROUND") b.bg:SetAllPoints() b.hl = b.panel:CreateTexture(nil, "HIGHLIGHT") b.hl:SetAllPoints() b.hl:SetColorTexture(1, 1, 1, 0.05) b.name = UI.CreateLabel(b.panel, "", { size = 12, justify = "LEFT" }) b.name:SetPoint("TOPLEFT", b.panel, "TOPLEFT", 10, -7) b.time = UI.CreateLabel(b.panel, "", { size = 10, color = "textDim", justify = "RIGHT" }) b.time:SetPoint("TOPRIGHT", b.panel, "TOPRIGHT", -8, -8) b.text = UI.CreateLabel(b.panel, "", { size = 12, justify = "LEFT", justifyV = "TOP" }) b.text:SetPoint("TOPLEFT", b.panel, "TOPLEFT", 10, -24) bubbles[i] = b return b end local function Plain(t) return CL.Plain(t) end local function DrawBubbles(key) local lines = CL.Lines(key) or {} local n = table.getn(lines) local first = math.max(1, n - MAX_BUBBLES + 1) local areaW = chat.child:GetWidth() if not areaW or areaW < 200 then areaW = 560 end seen.w = areaW local maxBub = math.floor(areaW * 0.68) local atBottom = stick or (chat.scroll:GetVerticalScroll() >= lastH - lastViewH - 8) local y = 6 local idx = 0 local i = first while i <= n do local ln = lines[i] idx = idx + 1 local b = Bubble(idx) local own = ln.o ~= nil local who = ln.s or "?" local cls, lv = CL.Info(who) SetClassIcon(b.av, cls) b.lvl:SetText(lv and tostring(lv) or "?") local r, g, bl = CL.ClassColor(cls) b.name:SetTextColor(r, g, bl) b.name:SetText(who) b.time:SetText(TimeText(ln.t)) 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 pw = math.floor(math.max(math.min(math.max(tw, nameW) + 22, maxBub), 110)) b.text:SetWidth(pw - 20) b.text:SetText(txt) local th = (b.text.GetStringHeight and b.text:GetStringHeight()) or b.text:GetHeight() or 14 if not th or th < 14 then th = 14 end local ph = math.floor(th + 38) b.panel:SetSize(pw, ph) if own then b.bg:SetColorTexture(0.13, 0.27, 0.46, 0.95) else b.bg:SetColorTexture(UI.Color("card", 0.95)) end local rowH = math.max(ph, 56) b:SetSize(areaW - 8, rowH) b:ClearAllPoints() b:SetPoint("TOPLEFT", chat.child, "TOPLEFT", 0, -y) b.avBtn:ClearAllPoints(); b.lvl:ClearAllPoints(); b.panel:ClearAllPoints() if own then b.avBtn:SetPoint("TOPRIGHT", b, "TOPRIGHT", -6, 0) b.lvl:SetPoint("TOP", b.avBtn, "BOTTOM", 0, -1) b.panel:SetPoint("TOPRIGHT", b.avBtn, "TOPLEFT", -8, 0) else b.avBtn:SetPoint("TOPLEFT", b, "TOPLEFT", 6, 0) b.lvl:SetPoint("TOP", b.avBtn, "BOTTOM", 0, -1) b.panel:SetPoint("TOPLEFT", b.avBtn, "TOPRIGHT", 8, 0) end local msg, sender = Plain(txt), who local url = CL.FirstUrl(txt) b.avBtn:SetScript("OnClick", function() ShowMenu(sender) end) b.panel:SetScript("OnClick", function(_, btn) btn = btn or arg1 if btn == "RightButton" then ShowMenu(sender) else ShowCopy(msg, url) end end) b:Show() y = y + rowH + 8 i = i + 1 end idx = idx + 1 while bubbles[idx] do bubbles[idx]:Hide(); idx = idx + 1 end local viewH = chat.scroll:GetHeight() or 300 chat:SetContentHeight(math.max(1, y)) lastH, lastViewH = y, viewH if atBottom then chat.scroll:SetVerticalScroll(math.max(0, y - viewH)) chat.UpdateScroll() stick = false end return n end local function DrawLog(key) local lines = CL.Lines(key) or {} local n = table.getn(lines) local first = math.max(1, n - LOG_LINES + 1) local parts = {} 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 "") i = i + 1 end if not logArea.edit:HasFocus() then local text = table.concat(parts, "\n") if logArea.lastText ~= text then logArea.lastText = text logArea:SetText(text) if C_Timer and C_Timer.After then C_Timer.After(0.15, function() local h = logArea.child:GetHeight() or 0 local v = logArea.scroll:GetHeight() or 0 logArea.scroll:SetVerticalScroll(math.max(0, h - v)) logArea.UpdateScroll() end) end end end return n end local function DrawCenter() local en = selKey and EntryByKey(selKey) if not en then head:SetText(""); sub:SetText(""); empty:SetText("") chat:Hide(); logArea:Hide(); ibox:Hide(); sendBtn:Hide() return end local title = en.label if en.kind == "whisper" then local c, lv = CL.Info(en.name) title = en.name sub:SetText((lv and (tostring(lv)) or "?") .. " - " .. L.CHAT_KEPT) else sub:SetText(L.CHAT_KEPT) end head:SetText(title) local canWrite = en.mode ~= "data" if canWrite then ibox:Show(); sendBtn:Show() else ibox:Hide(); sendBtn:Hide() end if en.mode == "data" then chat:Hide(); logArea:Hide() empty:SetText(L.CHAT_DATA) elseif en.mode == "log" then chat:Hide(); logArea:Show() local n = DrawLog(en.key) if n == 0 then empty:SetText(L.CHAT_EMPTY) else empty:SetText("") end else logArea:Hide(); chat:Show() local n = DrawBubbles(en.key) if n == 0 then empty:SetText(L.CHAT_EMPTY) else empty:SetText("") end end if en.kind == "guild" and not (IsInGuild and IsInGuild()) then empty:SetText(L.CHAT_NOGUILD) end end ------------------------------------------------------------------ -- Rechte Spalte: Suche und Mitglieder ------------------------------------------------------------------ local box = UI.CreatePanel(f, "bgDeep", "bronze") box:SetHeight(26) box:SetPoint("TOPRIGHT", f, "TOPRIGHT", 0, -2) box:SetWidth(RIGHT_W) 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 = 11, color = "textDim" }) hint:SetPoint("LEFT", box, "LEFT", 8, 0) hint:SetPoint("RIGHT", box, "RIGHT", -4, 0) local rhead = UI.CreateLabel(f, "", { size = 11, color = "textDim", justify = "LEFT" }) rhead:SetPoint("TOPRIGHT", f, "TOPRIGHT", 0, -34) rhead:SetWidth(RIGHT_W) local refresh = UI.CreateButton(f, L.CHAN_REFRESH, RIGHT_W, 24, function() Ch.RefreshAll() CL.RequestGuild() end) refresh:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", 0, 6) local right = UI.CreateScrollFrame(f) right:SetPoint("TOPRIGHT", f, "TOPRIGHT", 0, -54) right:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", 0, 36) right:SetWidth(RIGHT_W) local rrows = {} local function RightRow(i) local r = rrows[i] if not r then r = CreateFrame("Button", nil, right.child) r:SetHeight(22) r:SetPoint("TOPLEFT", right.child, "TOPLEFT", 0, -(i - 1) * 22) r:SetPoint("TOPRIGHT", right.child, "TOPRIGHT", 0, -(i - 1) * 22) r:RegisterForClicks("LeftButtonUp", "RightButtonUp") r.hl = r:CreateTexture(nil, "HIGHLIGHT") r.hl:SetAllPoints() r.hl:SetColorTexture(UI.Color("gold", 0.15)) r.icon = r:CreateTexture(nil, "ARTWORK") r.icon:SetSize(16, 16) r.icon:SetPoint("LEFT", r, "LEFT", 4, 0) r.text = UI.CreateLabel(r, "", { size = 12, justify = "LEFT" }) r.text:SetPoint("LEFT", r.icon, "RIGHT", 6, 0) r.text:SetPoint("RIGHT", r, "RIGHT", -4, 0) rrows[i] = r end return r end local function MembersOf(en) local out = {} if not en then return out end if en.kind == "channel" and en.e then local k = 1 while k <= table.getn(en.e.members) do out[table.getn(out) + 1] = { name = en.e.members[k] } k = k + 1 end elseif en.kind == "guild" then local k = 1 while k <= table.getn(CL.guild) do local g = CL.guild[k] out[table.getn(out) + 1] = { name = g.name, class = g.class, level = g.level } k = k + 1 end elseif en.kind == "group" then out = CL.ScanGroup() elseif en.kind == "whisper" then out[1] = { name = en.name } end return out end local function DrawRight() local en = selKey and EntryByKey(selKey) local items = {} if search ~= "" then local hits = Ch.Find(search, 300) 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 rhead:SetText(table.getn(items) == 0 and L.CHAN_NO_HITS or (Ch.moreFound and L.CHAN_MORE or "")) Ch.moreFound = nil else items = MembersOf(en) local title = (en and en.kind == "guild") and L.CHAT_ONLINE_HDR or L.CHAT_MEMBERS_HDR rhead:SetText(title .. " (" .. table.getn(items) .. ")") if en and en.kind == "group" and table.getn(items) <= 1 then rhead:SetText(L.CHAT_NOGROUP) end end local cnt = math.min(table.getn(items), 400) local i = 1 while i <= cnt do local it = items[i] local r = RightRow(i) local nm = it.name local cls, lv = it.class, it.level if not cls or not lv then local c2, l2 = CL.Info(nm) cls = cls or c2; lv = lv or l2 end SetClassIcon(r.icon, cls) local cr, cg, cb = CL.ClassColor(cls) local txt = Hex(cr, cg, cb) .. nm .. "|r" if lv then txt = txt .. " |cff9a978c" .. lv .. "|r" end if it.extra then txt = txt .. " |cff9a978c" .. it.extra .. "|r" end r.text:SetText(txt) r:SetScript("OnClick", function() ShowMenu(nm) end) r:Show() i = i + 1 end while rrows[i] do rrows[i]:Hide(); i = i + 1 end right:SetContentHeight(math.max(1, cnt * 22)) end edit:SetScript("OnTextChanged", function(self) search = self:GetText() or "" if search == "" then hint:Show() else hint:Hide() end right:ScrollToTop() DrawRight() end) ------------------------------------------------------------------ -- Zusammenspiel ------------------------------------------------------------------ Redraw = function() seen.cl, seen.ch = CL.version, Ch.version DrawLeft() CL.viewKey = selKey if selKey then CL.unread[selKey] = nil end DrawCenter() DrawRight() end selectKey = function(key) selKey = key stick = true CL.unread[key] = nil Redraw() end f.Refresh = function() CL.viewVisible = true if Ch.dirty or table.getn(Ch.list) == 0 then Ch.dirty = nil Ch.RefreshAll() else Ch.Rescan() end CL.RequestGuild() stick = true Redraw() end f:SetScript("OnHide", function() CL.viewVisible = false HideMenu() copy:Hide() end) local acc = 0 f:SetScript("OnUpdate", function(_, el) acc = acc + (el or arg1 or 0) if acc < 0.4 then return end acc = 0 if not f:IsShown() then return 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() end end) return f end UI:RegisterTab("channels", { label = function() return FW.L.TAB_CHANNELS end, order = 115, build = Build, onShow = function(f) f.Refresh() end, })