View Single Post
09-18-20, 08:03 PM   #1
siweia
A Flamescale Wyrmkin
 
siweia's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2011
Posts: 126
ScrollFrame seems to have a limit height in the patch 9.0.2.35938

Lua Code:
  1. local _, ns = ...
  2. local B, C, L, DB = unpack(ns)
  3. if not C.Infobar.Guild then return end
  4.  
  5. local module = B:GetModule("Infobar")
  6. local info = module:RegisterInfobar("Guild", C.Infobar.GuildPos)
  7.  
  8. local wipe, sort, format, select = table.wipe, table.sort, format, select
  9. local CLASS_ICON_TCOORDS, SELECTED_DOCK_FRAME = CLASS_ICON_TCOORDS, SELECTED_DOCK_FRAME
  10. local LEVEL_ABBR, CLASS_ABBR, NAME, ZONE, RANK, GUILDINFOTAB_APPLICANTS, REMOTE_CHAT = LEVEL_ABBR, CLASS_ABBR, NAME, ZONE, RANK, GUILDINFOTAB_APPLICANTS, REMOTE_CHAT
  11. local IsAltKeyDown, IsShiftKeyDown, C_Timer_After, GetTime, Ambiguate, MouseIsOver = IsAltKeyDown, IsShiftKeyDown, C_Timer.After, GetTime, Ambiguate, MouseIsOver
  12. local MailFrameTab_OnClick, MailFrame, SendMailNameEditBox = MailFrameTab_OnClick, MailFrame, SendMailNameEditBox
  13. local ChatEdit_ChooseBoxForSend, ChatEdit_ActivateChat, ChatFrame_OpenChat, ChatFrame_GetMobileEmbeddedTexture = ChatEdit_ChooseBoxForSend, ChatEdit_ActivateChat, ChatFrame_OpenChat, ChatFrame_GetMobileEmbeddedTexture
  14. local GetNumGuildMembers, GetGuildInfo, GetNumGuildApplicants, GetGuildRosterInfo, IsInGuild = GetNumGuildMembers, GetGuildInfo, GetNumGuildApplicants, GetGuildRosterInfo, IsInGuild
  15. local GetQuestDifficultyColor, GetRealZoneText, UnitInRaid, UnitInParty = GetQuestDifficultyColor, GetRealZoneText, UnitInRaid, UnitInParty
  16. local C_GuildInfo_GuildRoster = C_GuildInfo.GuildRoster
  17. local InviteToGroup = C_PartyInfo.InviteUnit
  18.  
  19. local r, g, b = DB.r, DB.g, DB.b
  20. local infoFrame, gName, gOnline, gApps, gRank, applyData, prevTime
  21.  
  22. local function scrollBarHook(self, delta)
  23.     local scrollBar = self.ScrollBar
  24.     scrollBar:SetValue(scrollBar:GetValue() - delta*50)
  25. end
  26.  
  27. function module:ReskinScrollBar()
  28.     local scrollBar = self.ScrollBar
  29.     B.HideObject(scrollBar.ScrollUpButton)
  30.     B.HideObject(scrollBar.ScrollDownButton)
  31.     scrollBar.ThumbTexture:SetColorTexture(.3, .3, .3)
  32.     scrollBar.ThumbTexture:SetSize(3, 10)
  33.     scrollBar.ThumbTexture:SetPoint("LEFT", -5, 0)
  34.     self:SetScript("OnMouseWheel", scrollBarHook)
  35. end
  36.  
  37. local function setupInfoFrame()
  38.     if infoFrame then infoFrame:Show() return end
  39.  
  40.     infoFrame = CreateFrame("Frame", "NDuiGuildInfobar", info)
  41.     infoFrame:SetSize(335, 495)
  42.     infoFrame:SetPoint("TOPLEFT", UIParent, 15, -30)
  43.     infoFrame:SetClampedToScreen(true)
  44.     infoFrame:SetFrameStrata("TOOLTIP")
  45.     local bg = B.SetBD(infoFrame)
  46.     bg:SetBackdropColor(0, 0, 0, .7)
  47.  
  48.     local function onUpdate(self, elapsed)
  49.         self.timer = (self.timer or 0) + elapsed
  50.         if self.timer > .1 then
  51.             if not infoFrame:IsMouseOver() then
  52.                 self:Hide()
  53.                 self:SetScript("OnUpdate", nil)
  54.             end
  55.  
  56.             self.timer = 0
  57.         end
  58.     end
  59.     infoFrame:SetScript("OnLeave", function(self)
  60.         self:SetScript("OnUpdate", onUpdate)
  61.     end)
  62.  
  63.     gName = B.CreateFS(infoFrame, 16, "Guild", true, "TOPLEFT", 15, -10)
  64.     gOnline = B.CreateFS(infoFrame, 13, "Online", false, "TOPLEFT", 15, -35)
  65.     gApps = B.CreateFS(infoFrame, 13, "Applications", false, "TOPRIGHT", -15, -35)
  66.     gRank = B.CreateFS(infoFrame, 13, "Rank", false, "TOPLEFT", 15, -51)
  67.  
  68.     local bu = {}
  69.     local width = {30, 35, 126, 126}
  70.     for i = 1, 4 do
  71.         bu[i] = CreateFrame("Button", nil, infoFrame)
  72.         bu[i]:SetSize(width[i], 22)
  73.         bu[i]:SetFrameLevel(infoFrame:GetFrameLevel() + 3)
  74.         if i == 1 then
  75.             bu[i]:SetPoint("TOPLEFT", 12, -75)
  76.         else
  77.             bu[i]:SetPoint("LEFT", bu[i-1], "RIGHT", -2, 0)
  78.         end
  79.         bu[i].HL = bu[i]:CreateTexture(nil, "HIGHLIGHT")
  80.         bu[i].HL:SetAllPoints(bu[i])
  81.         bu[i].HL:SetColorTexture(r, g, b, .2)
  82.     end
  83.     B.CreateFS(bu[1], 13, LEVEL_ABBR)
  84.     B.CreateFS(bu[2], 13, CLASS_ABBR)
  85.     B.CreateFS(bu[3], 13, NAME, false, "LEFT", 5, 0)
  86.     B.CreateFS(bu[4], 13, ZONE, false, "RIGHT", -5, 0)
  87.  
  88.     for i = 1, 4 do
  89.         bu[i]:SetScript("OnClick", function()
  90.             NDuiADB["GuildSortBy"] = i
  91.             NDuiADB["GuildSortOrder"] = not NDuiADB["GuildSortOrder"]
  92.             applyData()
  93.         end)
  94.     end
  95.  
  96.     B.CreateFS(infoFrame, 13, DB.LineString, false, "BOTTOMRIGHT", -12, 58)
  97.     local whspInfo = DB.InfoColor..DB.RightButton..L["Whisper"]
  98.     B.CreateFS(infoFrame, 13, whspInfo, false, "BOTTOMRIGHT", -15, 42)
  99.     local invtInfo = DB.InfoColor.."ALT +"..DB.LeftButton..L["Invite"]
  100.     B.CreateFS(infoFrame, 13, invtInfo, false, "BOTTOMRIGHT", -15, 26)
  101.     local copyInfo = DB.InfoColor.."SHIFT +"..DB.LeftButton..L["Copy Name"]
  102.     B.CreateFS(infoFrame, 13, copyInfo, false, "BOTTOMRIGHT", -15, 10)
  103.  
  104.     local scrollFrame = CreateFrame("ScrollFrame", nil, infoFrame, "UIPanelScrollFrameTemplate")
  105.     scrollFrame:SetSize(315, 320)
  106.     scrollFrame:SetPoint("TOPLEFT", 10, -100)
  107.     module.ReskinScrollBar(scrollFrame)
  108.  
  109.     local roster = CreateFrame("Frame", nil, scrollFrame)
  110.     roster:SetSize(315, 1)
  111.     scrollFrame:SetScrollChild(roster)
  112.     infoFrame.roster = roster
  113. end
  114.  
  115. local guildTable, frames, previous = {}, {}, 0
  116.  
  117. local function buttonOnClick(self, btn)
  118.     local name = guildTable[self.index][3]
  119.     if btn == "LeftButton" then
  120.         if IsAltKeyDown() then
  121.             InviteToGroup(name)
  122.         elseif IsShiftKeyDown() then
  123.             if MailFrame:IsShown() then
  124.                 MailFrameTab_OnClick(nil, 2)
  125.                 SendMailNameEditBox:SetText(name)
  126.                 SendMailNameEditBox:HighlightText()
  127.             else
  128.                 local editBox = ChatEdit_ChooseBoxForSend()
  129.                 local hasText = (editBox:GetText() ~= "")
  130.                 ChatEdit_ActivateChat(editBox)
  131.                 editBox:Insert(name)
  132.                 if not hasText then editBox:HighlightText() end
  133.             end
  134.         end
  135.     else
  136.         ChatFrame_OpenChat("/w "..name.." ", SELECTED_DOCK_FRAME)
  137.     end
  138. end
  139.  
  140. local function createRoster(parent, i)
  141.     local button = CreateFrame("Button", nil, parent)
  142.     button:SetSize(312, 20)
  143.     button.HL = button:CreateTexture(nil, "HIGHLIGHT")
  144.     button.HL:SetAllPoints()
  145.     button.HL:SetColorTexture(r, g, b, .2)
  146.     button.index = i
  147.  
  148.     button.level = B.CreateFS(button, 13, "Level", false)
  149.     button.level:SetPoint("TOP", button, "TOPLEFT", 16, -4)
  150.     button.class = button:CreateTexture(nil, "ARTWORK")
  151.     button.class:SetPoint("LEFT", 35, 0)
  152.     button.class:SetSize(16, 16)
  153.     button.class:SetTexture("Interface\\GLUES\\CHARACTERCREATE\\UI-CHARACTERCREATE-CLASSES")
  154.     button.name = B.CreateFS(button, 13, "Name", false, "LEFT", 65, 0)
  155.     button.name:SetPoint("RIGHT", button, "LEFT", 185, 0)
  156.     button.name:SetJustifyH("LEFT")
  157.     button.zone = B.CreateFS(button, 13, "Zone", false, "RIGHT", -2, 0)
  158.     button.zone:SetPoint("LEFT", button, "RIGHT", -120, 0)
  159.     button.zone:SetJustifyH("RIGHT")
  160.  
  161.     button:RegisterForClicks("AnyUp")
  162.     button:SetScript("OnClick", buttonOnClick)
  163.  
  164.     return button
  165. end
  166.  
  167. C_Timer_After(5, function()
  168.     if IsInGuild() then C_GuildInfo_GuildRoster() end
  169. end)
  170.  
  171. local function setPosition()
  172.     for i = 1, previous do
  173.         if i == 1 then
  174.             frames[i]:SetPoint("TOPLEFT")
  175.         else
  176.             frames[i]:SetPoint("TOP", frames[i-1], "BOTTOM")
  177.         end
  178.         frames[i]:Show()
  179.     end
  180. end
  181.  
  182. local function refreshData()
  183.     if not prevTime or (GetTime()-prevTime > 5) then
  184.         C_GuildInfo_GuildRoster()
  185.         prevTime = GetTime()
  186.     end
  187.  
  188.     wipe(guildTable)
  189.     local count = 0
  190.     local total, _, online = GetNumGuildMembers()
  191.     local guildName, guildRank = GetGuildInfo("player")
  192.  
  193.     gName:SetText("|cff0099ff<"..(guildName or "")..">")
  194.     gOnline:SetText(format(DB.InfoColor.."%s:".." %d/%d", GUILD_ONLINE_LABEL, online, total))
  195.     gApps:SetText(format(DB.InfoColor..GUILDINFOTAB_APPLICANTS, GetNumGuildApplicants()))
  196.     gRank:SetText(DB.InfoColor..RANK..": "..(guildRank or ""))
  197.  
  198.     for i = 1, total do
  199.         local name, _, _, level, _, zone, _, _, connected, status, class, _, _, mobile = GetGuildRosterInfo(i)
  200.         if connected or mobile then
  201.             if mobile and not connected then
  202.                 zone = REMOTE_CHAT
  203.                 if status == 1 then
  204.                     status = "|TInterface\\ChatFrame\\UI-ChatIcon-ArmoryChat-AwayMobile:14:14:0:0:16:16:0:16:0:16|t"
  205.                 elseif status == 2 then
  206.                     status = "|TInterface\\ChatFrame\\UI-ChatIcon-ArmoryChat-BusyMobile:14:14:0:0:16:16:0:16:0:16|t"
  207.                 else
  208.                     status = ChatFrame_GetMobileEmbeddedTexture(73/255, 177/255, 73/255)
  209.                 end
  210.             else
  211.                 if status == 1 then
  212.                     status = DB.AFKTex
  213.                 elseif status == 2 then
  214.                     status = DB.DNDTex
  215.                 else
  216.                     status = " "
  217.                 end
  218.             end
  219.             if not zone then zone = UNKNOWN end
  220.  
  221.             count = count + 1
  222.             guildTable[count] = {level, class, Ambiguate(name, "none"), zone, status}
  223.         end
  224.     end
  225.  
  226.     if count ~= previous then
  227.         if count > previous then
  228.             for i = previous+1, count do
  229.                 if not frames[i] then
  230.                     frames[i] = createRoster(infoFrame.roster, i)
  231.                 end
  232.             end
  233.         elseif count < previous then
  234.             for i = count+1, previous do
  235.                 frames[i]:Hide()
  236.             end
  237.         end
  238.         previous = count
  239.  
  240.         setPosition()
  241.     end
  242. end
  243.  
  244. local function sortGuild(a, b)
  245.     if a and b then
  246.         if NDuiADB["GuildSortOrder"] then
  247.             return a[NDuiADB["GuildSortBy"]] < b[NDuiADB["GuildSortBy"]]
  248.         else
  249.             return a[NDuiADB["GuildSortBy"]] > b[NDuiADB["GuildSortBy"]]
  250.         end
  251.     end
  252. end
  253.  
  254. function applyData()
  255.     sort(guildTable, sortGuild)
  256.  
  257.     for i = 1, previous do
  258.         local level, class, name, zone, status = unpack(guildTable[i])
  259.  
  260.         local levelcolor = B.HexRGB(GetQuestDifficultyColor(level))
  261.         frames[i].level:SetText(levelcolor..level)
  262.  
  263.         local tcoords = CLASS_ICON_TCOORDS[class]
  264.         frames[i].class:SetTexCoord(tcoords[1] + .022, tcoords[2] - .025, tcoords[3] + .022, tcoords[4] - .025)
  265.  
  266.         local namecolor = B.HexRGB(B.ClassColor(class))
  267.         frames[i].name:SetText(namecolor..name..status)
  268.  
  269.         local zonecolor = DB.GreyColor
  270.         if UnitInRaid(name) or UnitInParty(name) then
  271.             zonecolor = "|cff4c4cff"
  272.         elseif GetRealZoneText() == zone then
  273.             zonecolor = "|cff4cff4c"
  274.         end
  275.         frames[i].zone:SetText(zonecolor..zone)
  276.     end
  277. end
  278.  
  279. info.eventList = {
  280.     "PLAYER_ENTERING_WORLD",
  281.     "GUILD_ROSTER_UPDATE",
  282.     "PLAYER_GUILD_UPDATE",
  283. }
  284.  
  285. info.onEvent = function(self, event, ...)
  286.     if not IsInGuild() then
  287.         self.text:SetText(GUILD..": "..DB.MyColor..NONE)
  288.         return
  289.     end
  290.  
  291.     if event == "GUILD_ROSTER_UPDATE" then
  292.         local canRequestRosterUpdate = ...
  293.         if canRequestRosterUpdate then
  294.             C_GuildInfo_GuildRoster()
  295.         end
  296.     end
  297.  
  298.     local online = select(3, GetNumGuildMembers())
  299.     self.text:SetText(GUILD..": "..DB.MyColor..online)
  300.  
  301.     if infoFrame and infoFrame:IsShown() then
  302.         refreshData()
  303.         applyData()
  304.     end
  305. end
  306.  
  307. info.onEnter = function()
  308.     if not IsInGuild() then return end
  309.     if NDuiFriendsFrame and NDuiFriendsFrame:IsShown() then NDuiFriendsFrame:Hide() end
  310.     setupInfoFrame()
  311.     refreshData()
  312.     applyData()
  313. end
  314.  
  315. local function delayLeave()
  316.     if MouseIsOver(infoFrame) then return end
  317.     infoFrame:Hide()
  318. end
  319.  
  320. info.onLeave = function()
  321.     if not infoFrame then return end
  322.     C_Timer_After(.1, delayLeave)
  323. end
  324.  
  325. info.onMouseUp = function()
  326.     if InCombatLockdown() then UIErrorsFrame:AddMessage(DB.InfoColor..ERR_NOT_IN_COMBAT) return end
  327.  
  328.     if not IsInGuild() then return end
  329.     infoFrame:Hide()
  330.     if not GuildFrame then LoadAddOn("Blizzard_GuildUI") end
  331.     ToggleFrame(GuildFrame)
  332. end

You can also read from my Github.

Because blizzard prevent player from opening GuildFrame in combat, I use the code above to create a frame that display guild members with copy name and invite unit function, as a replacement of GameTooltip.

In the newest beta patch, once the online members go more than 97, the scrollframe becomes none scroll-able, no idea how to get a fix.

Last edited by siweia : 09-18-20 at 08:06 PM.
  Reply With Quote